Skip to content

Instantly share code, notes, and snippets.

@umegaya
Last active January 9, 2022 12:46
Show Gist options
  • Save umegaya/8131387 to your computer and use it in GitHub Desktop.
Save umegaya/8131387 to your computer and use it in GitHub Desktop.
about celluloid (ruby)
## celluloid?
- ruby library for concurrent programming
- https://github.com/celluloid/celluloid
## how it seems to be executed?
- include Celluloid module to your class
- instance of such a class is unit of concurrently executing.
- any method call through instance.async.method_call is queued as message and executed by
- fiber
- thread
later.
## how it works?
- inclusion of Celluloid module replaces original class's new method so when our class instantiated with ClassName.new, related Actor are setup. (more precisely, Actor (Call in latest version) wrapped an instance of our class created by allocate method)
- Cell.initialize
- Actor.initialize
- setup handle table (SystemEvent)
- setup handle table (Call, BlockCall, Response, BlockResponse)
- Actor.start (start to receive message from @mailbox)
- Actor set itself to current Threads local storage (TLS)
- Actor is like proxy of your instance and it schedules execution of your instances method.
- many ***proxy passes function name and args until final execution of our instance method.
- Celluloid::ClassMethods.async
- CellProxy.async
- AsyncProxy.method_missing (it pushes AsyncCall object to @mailbox, it is @mailbox in Actor instance
- MailBox.<< (it uses mutex)
- Actor.run
- MailBox.receive (it pops message/lock mutex)
- Actor.handle_message
- pattern matching in Handler.match
- Cell.invoke
- Cell.task
- Actor.task
- TaskFiber or TaskThread.new
- TaskFiber or TaskThread.resume
- message.dispatch (Call, BlockCall, AsyncCall) with Actor's @subject
- @subject.public_send(method, args, blocks)
- finally executed!!
## suspend/resume
- Receiver do it
- example : future
- Future.value
- Celluloid.receive
- Actor.receive
- Receivers.receive
- Task.suspend :receving => this causes susupend
-> when timeout > timer callback calls Receiver.resume > @task.resume
-> when some data received (@receivers.handle_message react incoming message (from Actor.handle_message)
(receiver receives block to check message is actually what it wants or not.)
- Celluloid.mailbox.receive
- ConditionVariable.wait
... wait until ...
- ConditionVariable.signal (in MailBox.<<)
## how Actor (and its @subject) walking through between threads.
- I think there is 1 actor for 1 object instance, but TLS has celluloid_actor. how it switches?
- for fiber, it never walking through fiber. 1 message execution bind to 1 fiber. (1 TaskFiber object)
- for thread, maybe same situation because both are almost same implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment