#!/usr/bin/env ruby
# Taken from faraday internals
def middleware_mutex(&block)
<strong i="5">@middleware_mutex</strong> ||= begin
require 'monitor'
puts "I'm making a monitor!"
Monitor.new
end
puts @middleware_mutex.inspect
@middleware_mutex.synchronize(&block)
end
threads = 10.times.collect do
Thread.new do
middleware_mutex do
puts "I got the power!"
end
end
end
threads.each(&:join)
λ€μμ 2.6μ μΆλ ₯ μμ λλ€.
koyoko% rvm use 2.6
Using /home/samuel/.rvm/gems/ruby-2.6.3
^[[A% koyoko% ./middleware_mutex.rb
I'm making a monitor!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055fb2217ec60 @mon_mutex=#<Thread::Mutex:0x000055fb2217ec10>, @mon_mutex_owner_object_id=47268548572720, @mon_owner=nil, @mon_count=0>
I got the power!
koyoko% ./middleware_mutex.rb
I'm making a monitor!
I'm making a monitor!
#<Monitor:0x000055f197e82388 @mon_mutex=#<Thread::Mutex:0x000055f197e82338>, @mon_mutex_owner_object_id=47248062026180, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e81eb0 @mon_mutex=#<Thread::Mutex:0x000055f197e81e60>, @mon_mutex_owner_object_id=47248062025560, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e81b90 @mon_mutex=#<Thread::Mutex:0x000055f197e81b40>, @mon_mutex_owner_object_id=47248062025160, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e81938 @mon_mutex=#<Thread::Mutex:0x000055f197e818e8>, @mon_mutex_owner_object_id=47248062024860, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e816e0 @mon_mutex=#<Thread::Mutex:0x000055f197e81690>, @mon_mutex_owner_object_id=47248062024560, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x000055f197e827c0 @mon_mutex=#<Thread::Mutex:0x000055f197e82590>, @mon_mutex_owner_object_id=47248062026720, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e81438 @mon_mutex=#<Thread::Mutex:0x000055f197e813e8>, @mon_mutex_owner_object_id=47248062024220, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e811e0 @mon_mutex=#<Thread::Mutex:0x000055f197e81190>, @mon_mutex_owner_object_id=47248062023920, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e80f88 @mon_mutex=#<Thread::Mutex:0x000055f197e80f38>, @mon_mutex_owner_object_id=47248062023620, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!
#<Monitor:0x000055f197e80d30 @mon_mutex=#<Thread::Mutex:0x000055f197e80ce0>, @mon_mutex_owner_object_id=47248062023320, @mon_owner=nil, @mon_count=0>
I got the power!
λ€μμ jrubyμ μΆλ ₯ μμ λλ€.
koyoko% rvm use jruby
Using /home/samuel/.rvm/gems/jruby-9.2.6.0
koyoko% ./middleware_mutex.rb
I'm making a monitor!
I'm making a monitor!
I'm making a monitor!
#<Monitor:0x7ea668b0 @mon_mutex=#<Thread::Mutex:0x3027cbd3>, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!I'm making a monitor!#<Monitor:0x53ca91a5 @mon_mutex=#<Thread::Mutex:0x57f50f04>, @mon_owner=nil, @mon_count=0>I'm making a monitor!
#<Monitor:0x1b5e79ce @mon_mutex=#<Thread::Mutex:0x159994d5>, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x67589eb3 @mon_mutex=#<Thread::Mutex:0x63671680>, @mon_owner=nil, @mon_count=1>#<Monitor:0x1b5e79ce @mon_mutex=#<Thread::Mutex:0x159994d5>, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x67589eb3 @mon_mutex=#<Thread::Mutex:0x63671680>, @mon_owner=nil, @mon_count=0>
I got the power!
#<Monitor:0x49c2c95a @mon_mutex=#<Thread::Mutex:0xcc04e06>, @mon_owner=nil, @mon_count=0>
I got the power!
I'm making a monitor!#<Monitor:0x1b5e79ce @mon_mutex=#<Thread::Mutex:0x159994d5>, @mon_owner=nil, @mon_count=0>
#<Monitor:0x6fa38df1 @mon_mutex=#<Thread::Mutex:0x756e0d98>, @mon_owner=nil, @mon_count=0>
I got the power!
I got the power!
#<Monitor:0x4a9f0f52 @mon_mutex=#<Thread::Mutex:0x600dfde7>, @mon_owner=nil, @mon_count=0>
I got the power!
I got the power!
I got the power!
JRubyμμ μ΄κ²μ μ€ννλ©΄ <strong i="5">@middleware_mutex</strong> ||= begin
λ μμμ μ΄μ§ μκ³ λΈλ‘μ μ¬λ¬ λ² μ€ννκ² λ λΏλ§ μλλΌ @middleware_mutex
κ° μ€μ λ‘ μ¬λ¬ λͺ¨λν°μ μ¬λ¬ λ² μ€μ λ©λλ€. puts
κ° μ°¨λ¨/μ€λ λ 컨ν
μ€νΈ μ νμ λμ
ν μ μκΈ° λλ¬Έμ 2.6μμλ μ΄λ° μΌμ΄ λ°μν μ μμ΅λλ€.
_λΆμ κ°μ¬ν©λλ€!_
||=
κ° MRIμμλ λ¨μΌ ν λΉμ 보μ₯νμ§ μλλ€λ κ²μ λ§€μ° ν₯λ―Έλ‘μ΅λλ€.
@eregon λ€, μ λ λλμ΅λλ€. μ€μ λ‘ λ¬΄μ¨ μΌμ΄ μΌμ΄λκ³ μλμ§ λ³΄κΈ° μν΄ μ§μΉ¨μ λ²λ¦΄ μ μμ΅λκΉ?
@ioquatix
$ xsel -b | ruby --dump=insns
...
== disasm: #<ISeq:middleware_mutex@-:1 (1,0)-(9,3)> (catch: FALSE)
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: 0, kw: -1@-1, kwrest: -1])
[ 1] block@0<Block>
0000 putnil ( 2)[LiCa]
0001 defined instance-variable, :<strong i="7">@middleware_mutex</strong>, false
0005 branchunless 14
0007 getinstancevariable :<strong i="8">@middleware_mutex</strong>, <is:0>
0010 dup
0011 branchif 42
0013 pop
0014 putself ( 3)[Li]
0015 putstring "monitor"
0017 opt_send_without_block <callinfo!mid:require, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0020 pop
0021 putself ( 4)[Li]
0022 putstring "I'm making a monitor!"
0024 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0027 pop
0028 opt_getinlinecache 35, <is:1> ( 5)[Li]
0031 getconstant :Monitor
0033 opt_setinlinecache <is:1>
0035 opt_send_without_block <callinfo!mid:new, argc:0, ARGS_SIMPLE>, <callcache>
0038 dup ( 2)
0039 setinstancevariable :<strong i="9">@middleware_mutex</strong>, <is:0>
0042 pop
0043 putself ( 7)[Li]
0044 getinstancevariable :<strong i="10">@middleware_mutex</strong>, <is:0>
0047 opt_send_without_block <callinfo!mid:inspect, argc:0, ARGS_SIMPLE>, <callcache>
0050 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0053 pop
0054 getinstancevariable :<strong i="11">@middleware_mutex</strong>, <is:0> ( 8)[Li]
0057 getblockparamproxy block<strong i="12">@0</strong>, 0
0060 send <callinfo!mid:synchronize, argc:0, ARGS_BLOCKARG>, <callcache>, nil
0064 leave ( 9)[Re]
λ°λΌμ ||=
λ λ€μκ³Ό κ°μ΅λλ€.
if defined?(@middleware_mutex)
<strong i="17">@middleware_mutex</strong>
else
<strong i="18">@middleware_mutex</strong> = expression
end
MRIμμ μ¬μ μνμ§ μλλ‘ νλ €λ©΄ λ€μμ΄ νμν©λλ€.
if defined?(@middleware_mutex)
<strong i="22">@middleware_mutex</strong>
else
result = expression
# special bytecode to do `<strong i="23">@middleware_mutex</strong> = result unless defined?(@middleware_mutex)` atomically
end
λ¬Όλ‘ ν λΉνκΈ° μ μ μΆκ° νμΈμ νκΈ° λλ¬Έμ λΉμ©μ΄ λλλ€.
κ·Έλ¦¬κ³ λΈλ‘μ μ¬μ ν ββμ¬λ¬ λ² μ€νλμ΄ μλμΌλ‘ μμ νλ €κ³ νλ©΄ κ΅μ°© μνμ λμ μ€λ²ν€λκ° λ°μν μ μμΌλ―λ‘ ν΄λΉ λΆλΆμ μ¬μ©μ μ½λμ 맑기λ κ²μ΄ κ°μ₯ μ’μ΅λλ€.
μ€, λλ μ΄κ²μ΄ μ°λ¦¬κ° μλμΌλ‘ κ³ μΉ μ μλ κ²μ΄ μλλΌλ κ²μ μ μ μΌλ‘ λμν©λλ€. μ½λλ μ€λ λ μμ μ±μ POVμμ λμ°νκ² κΉ¨μ Έ μκ³ ||= μμκ° κ·Έκ²μ κ³ μΉ μ μμ΅λλ€.
μμ° @ioquatix λΆμμ κ°μ¬λ리며 μ΄ μ£Όμ μ λν κ·νμ μ λ¬Έ μ§μμ λ€μ ν λ² λͺ
ννκ² νμΈν μ μμ΅λλ€.
μ¦, λ΄κ° μλ ν JRuby λ° κΈ°ν λμ λ£¨λΉ κ΅¬νμ μ§μνκΈ° μν΄ νΉλ³ν λμ
λ κ½€ μ€λλ μ½λμ
λλ€.
μ€λλ μ°λ¦¬λ 곡μμ μΌλ‘ JRuby λ° κΈ°ν λΉ MRI 루λΉλ₯Ό λ μ΄μ μ§μνμ§ μμ΅λλ€. λλΆλΆ κ·Έλ κ² νλ λ° νμν μ§μμ΄ λΆμ‘±νλ€κ³ μκ°νκΈ° λλ¬Έμ λλ€. νμ§λ§ μ΅μν λμμ΄ λκΈ°λ₯Ό λ°λΌλ λ§μμμ κ·Έλλ‘ λμμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²μ μ λͺ¨λ₯΄κ² μ΅λλ€. κ·ν λλ @eregon μ΄ μ¬λ°λ₯Έ λ°©ν₯μ μλ €μ€ μ μλ€λ©΄ κΈ°κΊΌμ΄ μ§μμ μ»κ³ μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€. π€
μ΄κ²μ CRubyμ λ²κ·Έμ΄κΈ°λ ν©λλ€. PRμ μ μΆν μ μμ΅λλ€.
# 1074μμ νλμ μ루μ
μ μλνμ΅λλ€. MiddlewareRegistry
λͺ¨λμ ν΄λμ€λ‘ λ³ννλ κ²κ³Ό κ΄λ ¨λ λ λ€λ₯Έ μμ΄λμ΄κ° μμ΅λλ€. κ·Έλμ μ΄κ² λμ :
λ€μκ³Ό κ°μ μ μμ΅λλ€.
module Faraday
class Response
self.middleware_registry = MiddlewareRegistry.new(File.expand_path('response', __dir__),
raise_error: [:RaiseError, 'raise_error'],
logger: [:Logger, 'logger'],
)
μ΄κ²μ ν΄λμ€ μλͺ
μ£ΌκΈ° νν¬μ μμ‘΄νμ§ μμ΅λλ€. 루λΉκ° ν΄μλ λ MiddlewareRegistry
κ° μ¬κΈ°μμ μΈμ€ν΄μ€νλκ³ μμμ΄ λ§€μ° λΆλͺ
ν©λλ€.
class MiddlewareRegistry
def initialize
<strong i="14">@mutex</strong> = Monitor.new
end
end
κ°μ₯ μ μ©ν λκΈ
@ioquatix
λ°λΌμ
||=
λ λ€μκ³Ό κ°μ΅λλ€.MRIμμ μ¬μ μνμ§ μλλ‘ νλ €λ©΄ λ€μμ΄ νμν©λλ€.
λ¬Όλ‘ ν λΉνκΈ° μ μ μΆκ° νμΈμ νκΈ° λλ¬Έμ λΉμ©μ΄ λλλ€.
κ·Έλ¦¬κ³ λΈλ‘μ μ¬μ ν ββμ¬λ¬ λ² μ€νλμ΄ μλμΌλ‘ μμ νλ €κ³ νλ©΄ κ΅μ°© μνμ λμ μ€λ²ν€λκ° λ°μν μ μμΌλ―λ‘ ν΄λΉ λΆλΆμ μ¬μ©μ μ½λμ 맑기λ κ²μ΄ κ°μ₯ μ’μ΅λλ€.