ruby - Understanding Celluloid Concurrency -
following celluloid codes.
client1.rb
1 of 2 clients. (i named client 1)client2.rb
2nd of 2 clients. (named client 2 )
note:
the difference between above 2 clients text passed server. i.e ('client-1'
, 'client-2'
respectively)
on testing 2 clients (by running them side side) against following 2 servers (one @ time). found strange results.
server1.rb
(a basic example taken readme.md of celluloid-zmq)using example server 2 above clients resulted in parallel executions of tasks.
output
ruby server1.rb received @ 04:59:39 pm , message client-1 going sleep received @ 04:59:52 pm , message client-2
note:
the client2.rb message processed when client1.rb request on sleep.(mark of parallelism)
-
using example server 2 above clients did not resulted in parallel executions of tasks.
output
ruby server2.rb received @ 04:55:52 pm , message client-1 going sleep received @ 04:56:52 pm , message client-2
note:
the client-2 ask wait 60 seconds since client-1 sleeping(60 seconds sleep)
i ran above test multiple times resulted in same behaviour.
can explain me results of above tests that.
question: why celluloid made wait 60 seconds before can process other request i.e noticed in server2.rb case.?
ruby version
ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
using gists, verified issue can reproduced in mri 2.2.1
jruby 1.7.21
, rubinius 2.5.8
... difference between server1.rb
, server2.rb
use of displaymessage
, message
class method in latter.
use of sleep
in displaymessage
out of celluloid
scope.
when sleep
used in server1.rb
using celluloid.sleep
in actuality, when used in server2.rb
using kernel.sleep
... locks mailbox server
until 60 seconds have passed. prevents future method calls on actor processed until mailbox processing messages ( method calls on actor ) again.
there 3 ways resolve this:
use
defer {}
orfuture {}
block.explicitly invoke
celluloid.sleep
rathersleep
( if not explicitly invokedcelluloid.sleep
, usingsleep
end callingkernel.sleep
sincedisplaymessage
notinclude celluloid
server
)bring contents of
displaymessage.message
handle_message
inserver1.rb
; or @ leastserver
, incelluloid
scope, , use correctsleep
.
the defer {}
approach:
def handle_message(message) defer { displaymessage.message(message) } end
the celluloid.sleep
approach:
class displaymessage def self.message(message) #de ... celluloid.sleep 60 end end
not scope issue; it's asynchrony.
to reiterate, deeper issue not scope of sleep
... that's why defer
, future
best recommendation. post here came out in comments:
using defer
or future
pushes task cause actor become tied thread. if use future
, can return value once task done, if use defer
can fire & forget.
but better yet, create actor tasks tend tied up, , pool other actor... if defer
or future
don't work you.
i'd more happy answer follow-up questions brought question; have active mailing list, , irc channel. generous bounties commendable, plenty of purely you.
Comments
Post a Comment