0
As you could see from the screenshot below, you will always see POST after 302 response in IE developer tools.
If you see details for these request, you will see both POST and GET requests. How could it be?
While, if you use other network monitor tools to monitor the network, you will see only GET request.
It will bring developers into wrong directions as they would think it's the HTTP method error. For example: https://stackoverflow.com/questions/28513449/ie-ignores-303-redirect-in-post-redirect-get-scenario
And I would share another IE bug. If there is underscore in your domain, no cookies will be set.
See https://blogs.msdn.microsoft.com/ieinternals/2009/08/20/internet-explorer-cookie-internals-faq/
Posted on
Friday, November 09, 2018
by
醉·醉·鱼
and labeled under
IE
You may expect IE will redirect 302 for POST to a GET request. The truth is IE does it. However, the default developer tools sucks.As you could see from the screenshot below, you will always see POST after 302 response in IE developer tools.
If you see details for these request, you will see both POST and GET requests. How could it be?
While, if you use other network monitor tools to monitor the network, you will see only GET request.
It will bring developers into wrong directions as they would think it's the HTTP method error. For example: https://stackoverflow.com/questions/28513449/ie-ignores-303-redirect-in-post-redirect-get-scenario
And I would share another IE bug. If there is underscore in your domain, no cookies will be set.
See https://blogs.msdn.microsoft.com/ieinternals/2009/08/20/internet-explorer-cookie-internals-faq/
0
在这篇文章里面已经介绍了一种方法 http://tech.tulentsev.com/2012/02/ruby-how-to-override-class-method-with-a-module/,但我还可以分享另外的方法。
能够直接用prepend么?不行。你可以试试下面的例子。虽然说,被prepend的module会放到class的继承链的下方,但实际上,类方法却不受影响。
Posted on
Tuesday, September 04, 2018
by
醉·醉·鱼
and labeled under
ruby
You have a class with a class method. Write a module that, when included, will override that class method.
在这篇文章里面已经介绍了一种方法 http://tech.tulentsev.com/2012/02/ruby-how-to-override-class-method-with-a-module/,但我还可以分享另外的方法。
方法一:用instance_eval。原文中的方法。
方法二:用 class << base ; end
方法三:用prepend。如果你知道extend实际上就是class << base; include ClassMethods end的话,你就很好理解为啥prepend在这里可以起作用了。前两者都是直接修改类方法,而这直接通过修改继承链的方法去覆盖类方法。
module BooModule
def self.included base
base.instance_eval do
def bar
puts "module"
end
end
end
end
class KlassC
def self.bar
puts 'class'
end
end
KlassC.send(:include, BooModule)
KlassC.bar #=> module
p KlassC.ancestors
方法二:用 class << base ; end
module TooModule
def self.included base
class << base
def bar
puts "module"
end
end
end
end
class KlassD
def self.bar
puts 'class'
end
end
KlassD.send(:include, TooModule)
KlassD.bar #=> module
p KlassD.ancestors
方法三:用prepend。如果你知道extend实际上就是class << base; include ClassMethods end的话,你就很好理解为啥prepend在这里可以起作用了。前两者都是直接修改类方法,而这直接通过修改继承链的方法去覆盖类方法。
module GooModule
def self.included base
class << base
prepend ClassMethods
end
end
module ClassMethods
def bar
puts "module"
end
end
end
class KlassE
def self.bar
puts 'class'
end
end
KlassE.send(:include, GooModule)
KlassE.bar #=> module
p KlassE.ancestors
能够直接用prepend么?不行。你可以试试下面的例子。虽然说,被prepend的module会放到class的继承链的下方,但实际上,类方法却不受影响。
module FooModule
def self.included base
base.extend ClassMethods
end
def self.prepended base
base.extend ClassMethods
end
module ClassMethods
def bar
puts "module"
end
end
end
class KlassA
include FooModule
def self.bar
puts 'class'
end
end
KlassA.bar #=> class
p KlassA.ancestors
class KlassB
prepend FooModule
def self.bar
puts 'class'
end
end
KlassB.bar #=> class
p KlassB.ancestors
0
https://github.com/seattlerb/minitest/blob/master/lib/minitest.rb#L617
将上述代码替换成下面代码,就可以看到某个test用掉多少时间。
输出
Posted on
Tuesday, September 04, 2018
by
醉·醉·鱼
and labeled under
ruby
最新的5.11.3 minitest不知道为什么,在verbose模式下,把对应的测试 用例的名字给抹掉了。这样的话,导致分析测试用例performance的时候,非常得不友好。https://github.com/seattlerb/minitest/blob/master/lib/minitest.rb#L617
def record result # :nodoc:
io.print "%.2f s = " % [result.time] if options[:verbose]
io.print result.result_code
io.puts if options[:verbose]
end
end
将上述代码替换成下面代码,就可以看到某个test用掉多少时间。
def record result # :nodoc:
io.print "%s#%s = %.2f s = " % [result.klass, result.name, result.time] if options[:verbose]
io.print result.result_code
io.puts if options[:verbose]
end
输出
Run options: -n test_viewing_transaction --verbose --seed 39465
# Running:
TransactionsControllerTest#test_viewing_transaction = 6.13 s = .
Finished in 7.851562s, 0.1274 runs/s, 0.1274 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
0
罗列所有container的IP地址
单独monitor某个contrainer的logs
Posted on
Thursday, August 30, 2018
by
醉·醉·鱼
and labeled under
docker
罗列所有container的IP地址
docker ps -q | xargs -n 1 docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} {{ .Name }}'
单独monitor某个contrainer的logs
docker ps -a | grep payments | sed 's/ .*//' | xargs docker logs -f
0
DatabaseCleaner上面的example过时了。按照示例去做的话,会报错 unknown method 'before'。在github上找到了答案,还是比较简单的。
配置完成以后,就可以在MYSQL去monitor query,看具体是如何操作数据库的。
观察log
最后,重置改动。
class ActiveSupport::TestCase
include FactoryGirl::Syntax::Methods
ActiveRecord::Migration.check_pending!
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.logger = Rails.logger
setup { DatabaseCleaner.start }
teardown { DatabaseCleaner.clean }
end
配置完成以后,就可以在MYSQL去monitor query,看具体是如何操作数据库的。
mysql> SHOW VARIABLES LIKE "general_log%";
+------------------+----------------------------+
| Variable_name | Value |
+------------------+----------------------------+
| general_log | OFF |
| general_log_file | /var/run/mysqld/mysqld.log |
+------------------+----------------------------+
mysql> SET GLOBAL general_log = 'ON';
观察log
tail -f -n300 /var/run/mysqld/mysqld.log
最后,重置改动。
mysql> SET GLOBAL general_log = 'OFF';
- https://stackoverflow.com/questions/568564/how-can-i-view-live-mysql-queries
- https://github.com/metaskills/minitest-spec-rails/issues/44#issuecomment-244155657
0
在RR级别下,除了常规的RECORD LOCK,还有一个GAP LOCK。即两条记录之前的间隙。这样的话,就不会允许在范围内插入数据了。http://blog.csdn.net/wanghai__/article/details/7067118 这里有个很好的例子去模拟死锁。
至于分析锁,首先执行
然后,再执行
-- session 1
mysql> start transaction;
mysql> delete from game_summaries where game_id = 2;
-- session 2
mysql> start transaction;
mysql> delete from game_summaries where game_id = 3;
-- session 1
mysql> insert into game_summaries(game_id, score) values (2, 0);
-- waiting
-- session 2
mysql> insert into game_summaries(game_id, score) values(3, 0);
-- deadlock occurs
Deadlock info
然后就按照下面两篇文章去分析锁就行了。
Posted on
Monday, January 22, 2018
by
醉·醉·鱼
and labeled under
Mysql
之前分析过SQL SERVER的死锁,但基本都是基于READ COMMITTED下的死锁。玩得高级点的,就是key lookup lock。最近不幸玩了MySQL,拿原来的理解去尝试分析,结果不对,然后才发现,MySQL的默认隔离级别是REPEATABLE READ。呵呵~在RR级别下,除了常规的RECORD LOCK,还有一个GAP LOCK。即两条记录之前的间隙。这样的话,就不会允许在范围内插入数据了。http://blog.csdn.net/wanghai__/article/details/7067118 这里有个很好的例子去模拟死锁。
至于分析锁,首先执行
set global innodb_status_output_locks=on;
然后,再执行
SHOW ENGINE INNODB STATUS \G
就可以拿到所有session的锁了。-- session 1
mysql> start transaction;
mysql> delete from game_summaries where game_id = 2;
-- session 2
mysql> start transaction;
mysql> delete from game_summaries where game_id = 3;
-- session 1
mysql> insert into game_summaries(game_id, score) values (2, 0);
-- waiting
-- session 2
mysql> insert into game_summaries(game_id, score) values(3, 0);
-- deadlock occurs
Deadlock info
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-02-11 02:19:51 0x7ff5b7b83700
*** (1) TRANSACTION:
TRANSACTION 365986, ACTIVE 59 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 16, OS thread handle 140693325752064, query id 1184 172.18.0.1 root update
insert into game_summaries(game_id, score) values (2, 0)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3445 page no 4 n bits 72 index index_game_summaries_on_game_id of table `TEST`.`game_summaries` trx id 365986 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc ;;
1: len 4; hex 80000002; asc ;;
*** (2) TRANSACTION:
TRANSACTION 365987, ACTIVE 45 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 17, OS thread handle 140693326018304, query id 1186 172.18.0.1 root update
insert into game_summaries(game_id, score) values(3, 0)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 3445 page no 4 n bits 72 index index_game_summaries_on_game_id of table `TEST`.`game_summaries` trx id 365987 lock_mode X locks gap before rec
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc ;;
1: len 4; hex 80000002; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3445 page no 4 n bits 72 index index_game_summaries_on_game_id of table `TEST`.`game_summaries` trx id 365987 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000009; asc ;;
1: len 4; hex 80000002; asc ;;
*** WE ROLL BACK TRANSACTION (2)
然后就按照下面两篇文章去分析锁就行了。
- http://keithlan.github.io/2017/06/21/innodb_locks_algorithms/
- http://keithlan.github.io/2017/06/05/innodb_locks_1/
如果你有SQL SERVER的背景知识,简单来说,就是基本的record lock(以及相关的index),加上gap lock。一旦有gap lock,这个范围内是不允许插入数据的。这就增加了死锁发生的几率。这种情况更多是发生在DELETE & INSERT 组合情况下。
在上面的例子里面,两个delete statement所加的gap lock是不会相互冲突的。但是会阻止后续的插入。