Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Thread local propagation #125

wants to merge 368 commits into from

Update TaskWithThreadLocals to be its own class, without Task superclass (which no longer exists).

tarcieri and others added some commits
@tarcieri tarcieri Better delegation for Celluloid::PoolManager 461b4a9
@tarcieri tarcieri Combinatorial explosion of the matrix o_O 1abbbd7
@tarcieri tarcieri Huuuurk @ rbx d7d1c77
@slyphon slyphon Merge remote-tracking branch 'upstream/master' into clear_registry a8646d7
@slyphon slyphon actually assert the registry is empty 51b86c9
@tarcieri tarcieri Merge pull request #47 from motionbox/clear_registry
add a method to clear the registry (for use in tests)
@tarcieri tarcieri Synchronize ActorProxy#terminate with #join 499a2f6
@grantr grantr Add notifications for actors 82ce9fd
@grantr grantr test unsubscribe 1a1d6a3
@grantr grantr prune subscriptions from dead actors
Test fails; not sure how to kill a weakref.
@grantr grantr make fanout notifier an actor
Links to subscribers and prunes their subscriptions when they are
terminated. No need for a mutex or weakrefs.
@grantr grantr don't require a reason to prune 44eb77f
chatgris Added a failling test on Celluloid::Notification.
Signed-off-by: chatgris <>
chatgris Fix pattern on Celluloid::Notification.
Signed-off-by: chatgris <>
@tarcieri tarcieri Remove freenode token 3203e4c
@grantr grantr Merge pull request #1 from chatgris/notifications
Fix in pattern for Notifications
@halorgium halorgium Return the actor for Celluloid::SupervisionGroup::Member#start 16e3876
@halorgium halorgium Unify the Supervisor and SupervisionGroup classes
* Allow SupervisionGroup to be used without subclassing
* Separate the Registry from Actor
@tarcieri tarcieri Merge pull request #53 from halorgium/unify-supervisor-trees
Unify the Supervisor and SupervisionGroup classes
@grantr grantr test multiple subscriptions 5e48db6
@grantr grantr disambiguate local vs instance variables f13edd5
@KL-7 KL-7 Fix supervision groups link in the README. 5e4aedb
@tarcieri tarcieri Merge pull request #54 from KL-7/patch-1
Fix supervision groups link in the README.
@tarcieri tarcieri Merge pull request #52 from grantr/notifications
Notifications for actors
@tarcieri tarcieri Move example actor class into a separate file 9298dd7
@tarcieri tarcieri 'exclusive' class method
The 'exclusive' method can be used to mark certain instance methods as
always running exclusive. This has the side effect (which so happens to
be the main use case) of running code outside of a Ruby Fiber, allowing
that code to consumer more stack space than the 4kB stacks of YARV
fibers would otherwise allow.
@halorgium halorgium Do not require a caller for AsyncCall 0a6fb43
@halorgium halorgium Hide the task inside the Response object 317b8fc
@tarcieri tarcieri Merge pull request #56 from halorgium/fixes
Some simple refactor fixes
@halorgium halorgium Move guard-rspec out of CI gems 4175f4a
@tarcieri tarcieri Spec for thread count during pool execution 0e9718b
@tarcieri tarcieri Use the timers gem d2930e8
@tarcieri tarcieri Bump timers gem dependency a49a480
@tarcieri tarcieri Don't proxy the #class method
I've gone back and forth on this, and now I feel like proxying #class
and hiding the identity of the PoolManager is a bad idea. It's confusing
to those who don't realize that there's a PoolManager proxy between them
and the workers.
@tarcieri tarcieri Prevent SystemEvents from leaking out of #receive 8c8c682
@tarcieri tarcieri Update CHANGES cd340b1
@tarcieri tarcieri Bump timers dependency to 1.0.0.pre3 ed32c5e
@tarcieri tarcieri Bump timers dependency 0d9cc87
@tarcieri tarcieri Use Actor.all in pool spec 16440e7
@tarcieri tarcieri Use timers 1.0.0 41933c6
@tarcieri tarcieri Bump version to 0.11.1 4ff10f0
@tarcieri tarcieri Log the cause of aborted async calls
This was previously logging the AbortError, which doesn't give us useful
@tarcieri tarcieri SystemEvents are no longer exceptions
SystemEvents aren't necessarily errors or even exceptional, they're just
high priority messages. Once upon a time when they were used exclusively
for exit messages (caused by errors) it kind of made sense for them to
be exceptions, but they have grown in scope and usefulness and really
should just be objects.
@tarcieri tarcieri Eliminate Celluloid::Mailbox#system_event
Celluloid::Mailbox automatically detects system event messages and
treats them as being higher priority
@tarcieri tarcieri Visual cleanup e865dd2
@tarcieri tarcieri Link with SystemEvents
This introduces the LinkingRequest system event which improves system
robustness and allows linking requests to be handled seamlessly both in
exclusive mode and when using #receive

In addition, link/unlink now use exclusive mode, making them atomic and
transactional. This makes linking semantics easier to reason about.
@tarcieri tarcieri Unidirectional linking with #monitor and #unmonitor 3304605
@tarcieri tarcieri Handle system events properly when exclusive d606c4d
@tarcieri tarcieri Don't process system messages during linking
Processing system messages may kick off other events that can interfere
with the linking process. Instead, system messages are queued and
processed after linking operations are complete.
@tarcieri tarcieri Linking overhaul
This change moves much of the linking mechanics into Celluloid::Actor,
with the versions defined on instances of actors now calling these
versions. This makes linking available outside actor scope.

This was actually needed to correct a deadlock introduced by the
previous round of transactional/exclusive linking changes, as the
linking process was previously going through Actor.current (i.e. the
proxy object)

In addition, this fills out a missing #monitoring? API.
@tarcieri tarcieri Oops, leftover debugging stuffins e6ab522
@tarcieri tarcieri Delete ugly newline b22c788
@alh13 alh13 Provide the always_exclusive class method to classes that mixin
Celluloid. always_exclusive makes every method defined in the class
automatically be exclusive.

Test included.
@benlangfeld benlangfeld [BUGFIX] Dependencies' examples need the example actor class 1fb3a5c
@alh13 alh13 Per tarcieri, remove the always_exclusive method and instead trigger
that behavior by calling exclusive with no args.
@tarcieri tarcieri Merge pull request #59 from alh13/always_exclusive
Provide the always_exclusive class method to classes that mixin Celluloid
@tarcieri tarcieri Bump version to 0.12.0 50fd0c2
@tarcieri tarcieri Refactor always exclusive specs 0ccdc79
@tarcieri tarcieri Initial use_mailbox specs a8ad3f1
@tarcieri tarcieri Reduce sleep time for faster tests a8ecaeb
@tarcieri tarcieri Use timer quantum for the sleep time 775ae0e
@tarcieri tarcieri Subclasses should retain custom mailboxes b44ff91
@tarcieri tarcieri Factor join and kill into class methods of Actor f28f593
@tarcieri tarcieri Make ActorProxy a BasicObject 26300b5
@benlangfeld benlangfeld Changelog entry for #59 8d21eb3

This broke 9 examples...


WFM? Heh

Burgestrand and others added some commits
@Burgestrand Burgestrand Add missing parameter “include_private” to respond_to? for ActorProxy
Ruby’s own objects include this parameter [1], which when set to true also
takes into account private methods when looking up if the object responds
to the given method or not.

@tarcieri tarcieri Merge pull request #62 from Burgestrand/respond_to_include_private
Missing parameter “include_private” to respond_to? for ActorProxy

Hi tarcieri, thanks for writing celluloid. Would you mind giving some basic install instructions? I'm unable to get even the example basic_usage.rb to run, I'm wondering if there's any extra requirements.

% git clone              
Cloning into 'celluloid'...
% jruby -v
jruby 1.5.6
% cd celluloid/examples
% jruby basic_usage.rb 
/home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:74:in `shutdown': uninitialized constant #<Class:01x146b11e4>::Actor (NameError)
    from /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:73:in `shutdown'
    from /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:101

@soniah I'm able to reproduce this and it seems like it might be a JRuby bug of some sort. I don't get the same behavior on 1.9.3. It also works for me on both if you run the script from the toplevel directory, e.g:

% cd celluloid
% jruby examples/basic_usage.rb

@tarcieri I tried installing the Sun jvm, running with different jruby's, I still get a variety of errors. I was hoping to avoid the Ruby GIL problems, I guess I should try Rubinius?

I'm surprised you got it working using JRuby, maybe something is wrong with my environment...?

% java -version
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

% jruby -v
jruby 1.5.6

% jruby --1.9 examples/basic_usage.rb                    
/home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:74:in `shutdown': uninitialized constant #<Class:01x304cf82d>::Actor (NameError)
    from /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:73:in `shutdown'
    from /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:101

% ~/jruby- --1.9 examples/basic_usage.rb
LoadError: no such file to load -- timers
  require at org/jruby/
  require at /home/d674395/jruby-
   (root) at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid/receivers.rb:2
  require at org/jruby/
  require at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid/receivers.rb:36
   (root) at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:387
  require at org/jruby/
  require at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:36
   (root) at examples/basic_usage.rb:4
NameError: uninitialized constant #<Class:0x366a782d>::Actor
  const_missing at org/jruby/
       shutdown at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:74
        timeout at org/jruby/ext/
       shutdown at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:73
      Celluloid at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:101

% ~/jruby-1.7.0.preview1/bin/jruby --1.9 examples/basic_usage.rb 
LoadError: no such file to load -- timers
  require at org/jruby/
  require at /home/d674395/jruby-1.7.0.preview1/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid/receivers.rb:2
  require at org/jruby/
   (root) at /home/d674395/jruby-1.7.0.preview1/lib/ruby/shared/rubygems/custom_require.rb:1
  require at /home/d674395/jruby-1.7.0.preview1/lib/ruby/shared/rubygems/custom_require.rb:36
  require at org/jruby/
   (root) at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:387
   (root) at examples/basic_usage.rb:4
NameError: uninitialized constant #<Class:0x67e9bf91>::Actor
  const_missing at org/jruby/
       shutdown at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:74
        timeout at org/jruby/ext/timeout/
       shutdown at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:73
      Celluloid at /home/d674395/poller.ruby/pkg/celluloid.git/lib/celluloid.rb:101

@soniah you most likely need to run "bundle" first. That said celluloid is probably best used as a Ruby gem and not by directly cloning the source repository

tarcieri and others added some commits
@tarcieri tarcieri Configurable Celluloid::Task types
Allow users to specify alternative task types, e.g.

    class MyActor
      include Celluloid
      task_class MyTaskType

This change also renames Celluloid::Task to Celluloid::TaskFiber in
anticipation of the addition of more task types.
@tarcieri tarcieri Fix redefined constant warnings in specs c352388
@tarcieri tarcieri Not sure why this was disabled on rbx 03abb26
@tarcieri tarcieri Raise DeadActorError if notifier isn't running 1488ec7
@tarcieri tarcieri Add some debug logging for Travis 2c35648
@tarcieri tarcieri Fix some potential culprits for the failing specs
It looks like someone decided to lazy-initialize the registry which is
not thread safe and rather silly. It also seems the clear_registry tests
are blowing away actors that other specs may need to run.
@tarcieri tarcieri More debug logging for Travis :(
I can't for the life of me reproduce these test failures locally
@tarcieri tarcieri Revert "More debug logging for Travis :("
This reverts commit 88b88ee.

WTF, now everything is magically working? o_O
@tarcieri tarcieri Fix operation in exclusive :all mode ce05b79
@tarcieri tarcieri Changes d272a48
@tarcieri tarcieri All Celluloid methods are available through the singleton
There were previously several methods that were inaccessible because
they were only available in the Celluloid module and couldn't be called
on the singleton.

This change makes all of these methods available through the singleton
to any code that needs to do actor-like things but doesn't include
Celluloid itself
@tarcieri tarcieri Put TIMER_QUANTUM into the shared specs fdb2b24
@tarcieri tarcieri Rename events.rb to system_events.rb 2eb1699
@tarcieri tarcieri Log tests to log/test.log d784dd2
@tarcieri tarcieri Fix reference to legacy name 6eecbd8
@tarcieri tarcieri Remove legacy Celluloid::Group constant 4f90a3b
@tyabe tyabe Add CPU pattern of Windows to CPU counter b6fd449
@tarcieri tarcieri Merge pull request #66 from tyabe/add_cpu_pattern
Add CPU pattern of  Windows to CPU counter
@JustinLove JustinLove use map for terminators - each returns the original array 5e993e4
@JustinLove JustinLove BasicObject doesn't even have raise 3a604dd
@JustinLove JustinLove backfill raise test 762c565
@tarcieri tarcieri Merge pull request #67 from JustinLove/raise
raise isn't available in BasicObject
@tarcieri tarcieri Merge pull request #68 from JustinLove/map
use map for terminators - each returns the original array
@JustinLove JustinLove fix undefined method value for nil error on jruby and rbx bf11117
@tarcieri tarcieri Merge pull request #69 from JustinLove/nilvalue
fix undefined method value for nil error on jruby and rbx
@tarcieri tarcieri Impose 5 second timeout on linking 7a96e48
@tarcieri tarcieri Proper finalizer for Celluloid::PoolManager
This finalizer gracefully requests all threads in the pool to terminate
@tarcieri tarcieri Remove #join and #kill from the actor proxy a000e8e
@tarcieri tarcieri Fix terminate/kill specs 6281012
@tarcieri tarcieri Initial task specs f1c5b0a
@tarcieri tarcieri Marginally improved task specs f51aa7f
tarcieri and others added some commits
@tarcieri tarcieri Use the Celluloid::TIMER_QUANTUM constant everywhere cf7f988
@tarcieri tarcieri Celluloid::Actor#timeout -> #timeout_interval b3aa723
@tarcieri tarcieri Bump version in CHANGES to 0.12.0 cc6738c
@tarcieri tarcieri Bump version of HEAD to 0.12.1 ff996f4
@tarcieri tarcieri Remove Celluloid#alive?
All #alive? checks should be performed through the proxy. The only way
this method could ever get called is within an actor itself, which by
definition must be alive to be running code. Therefore it makes no sense
to have this method at all.
@tarcieri tarcieri String inspect warnings for bare Celluloid objects 3af0db8
@tarcieri tarcieri Make 'bare object' the canonical name for naked Celluloid objects 21a4f0e
@tarcieri tarcieri Update basic usage to use new async syntax 631d359
@tarcieri tarcieri Update async syntax in cigarette smokers example c9b39b2
@tarcieri tarcieri Update future syntax in example 71c504b
@tarcieri tarcieri Update future syntax in pool example 74c1d56
@tarcieri tarcieri Update async syntax in ring example 79ef141
@grantr grantr add RingBuffer for storing log messages
First step to foolscap-style logging!
@grantr grantr add RingBuffer#flush
Currently flush locks the buffer during the entire loop instead of
once for each element. This may cause pauses when appending but keeps
the buffer from wrapping around during the flush.
@grantr grantr add IncidentLogger and supporting classes
For now IncidentLogger is single progname only. This will probably
@benlangfeld benlangfeld Undo BasicObject based ActorProxy change
* BasicObject breaks all sorts of things
@grantr grantr allow multiple prognames per logger
This allows an incident to include logs from mulitple facilities. It is
also closer to the ruby Logger api.
@grantr grantr publish to a progname topic
In case anyone wants to filter incidents by progname.
@grantr grantr use a Logger to write incident events
Includes a custom formatter that uses the event time instead of the time
given by Logger, which is likely to be inaccurate as most events
actually happened in the past.

The actual format of the log output is the same as the default.
@grantr grantr Event#time instead of #timestamp 5c25f1e
@grantr grantr pass args into wrapped Logger instance 5018d99
@grantr grantr use IncidentLogger as Celluloid.logger
IncidentLogger needs to be started after the fanout actor.

IncidentLogger should also be one of the last actors to shut down,
otherwise shutdown messages are lost.
@benlangfeld benlangfeld [BUGFIX] Make pool size accessible 1efd8d5
@tarcieri tarcieri Merge pull request #90 from benlangfeld/master
Remove BasicObject from ActorProxy inheritance tree
@tarcieri tarcieri Disable rbx on travis due to fiber-related crash 3b370ec
@tarcieri tarcieri Notes on reverting BasicObject proxies e84b527
@tarcieri tarcieri Changes 43589b3
@tarcieri tarcieri Notes on removing Celluloid#alive? 4b764b4
@grantr grantr rename Event to LogEvent
Event is too vague. This class is really only for log messages.
@grantr grantr missed a rename 6c9d0fa
@grantr grantr if logger doesn't respond to alive?, don't send it 1563a13
@grantr grantr make IncidentLogger a plain old ruby object
This may be reverted eventually, but as I'm trying to fix test failures,
it seems that having the logger itself be managed by the system it's
trying to log is going to cause trouble.

The only change to IncidentLogger itself is the addition of a mutex
around the ring buffers. The only functionality removed is the ability
to log messages asynchronously, but there probably isn't much need for

IncidentReporter is still an actor, as it needs to subscribe to
notifications and only actors can do that.
@grantr grantr allow triggering_event to be nil 6b3fc7b
@grantr grantr return a new incident when merging 4d1ff84
@grantr grantr merge more than two incidents together c544ed3
@grantr grantr add triggering event time to incident header e52dcf1
@grantr grantr add a fallback logger
Debugging the IncidentLogger is challenging without one. Not sure if it
will stick around though.
@grantr grantr add newlines to incident reports 6deb1e9
@grantr grantr don't replace the celluloid logger in specs
This is likely temporary, but it is useful for debugging the incident

FYI, you can keep building against rbx without "failing" the build with this:

    - rvm: rbx-19mode


@jmazzi thanks! I was trying to find that at one point

@tarcieri not a problem, just noticed it going through the changelog :)

tarcieri and others added some commits
@tarcieri tarcieri Allow failures on rbx and jruby-head f8ec2ee
@tarcieri tarcieri Raise NotTaskError if task-related things are requested outside a task b742ae2
@tarcieri tarcieri More idiomatic bf5ce9b
@tarcieri tarcieri Use exclusive mode by default unless within a task 6328c9f
@jrochkind jrochkind workaround MRI bug in preserving exit status in at_exit bb9364b
@grantr grantr report incidents to a logfile in tests
Also terminate the default reporter to silence messages to stderr.
@grantr grantr add silence/unsilence to IncidentReporter
Instead of terminating the actor to silence it, just add a silence
@tarcieri tarcieri Initial thread dump spike 7dba40a
@tarcieri tarcieri Merge pull request #93 from jrochkind/workaround_mri_at_exit_bug
workaround MRI bug in preserving exit status in at_exit
@tarcieri tarcieri Improved stack dumper 5fc84e0
@tarcieri tarcieri Revert "Use exclusive mode by default unless within a task"
This change is causing sporadic hangs and seems to be setting @exclusive
inappropriately. It needs to be investigated further.

This reverts commit 6328c9f.
@tarcieri tarcieri Set the proper task type 28a5f4d
@tarcieri tarcieri Changes! 04a2286
@grantr grantr publish incidents with async call
Avoids the issues with making synchronous calls within actor internals.
@grantr grantr no need to include Celluloid::Notifications c8a2187
@grantr grantr publish to the correct incident topic
Allows reporters to choose which prognames to subscribe to.
@tarcieri tarcieri Merge pull request #92 from grantr/logging
Foolscap-style incident logger
@jmoses jmoses Count cores properly in AWS/Ubuntu
Since the /proc/cpuinfo file format has no standard, and ubuntu (or the version we use)
says 'processor' not 'core id'.
@tarcieri tarcieri Merge pull request #98 from jmoses/master
Make CPU counter try a little harder for linux OS
@jc00ke jc00ke Use Facter for CPU count
References #98
Joey Butler Add test around FSM#transition 6ca69e6
Joey Butler Encapsulate the idea of "transitioning with callbacks" into a method 4af0890
Joey Butler Extra method refactoring 0f17368
Joey Butler Improve test coverage for FSM#transition 4cac889
Joey Butler Extract out FSM state methods 397cdaa
Joey Butler The final extract method refactoring that tames the beast formerly known
as FSM#transition
@tarcieri tarcieri Merge pull request #99 from JoeyButler/refactor_fsm_transition
Refactor FSM#transition
@tarcieri tarcieri Better logic for suspending via tasks
There seems to be a deeper bug here with Celluloid.exclusive? not
returning the correct value. I will continue to investigate.

This logic is clearer and also fixes #91
@tarcieri tarcieri Ensure exclusive mode remains on in nested blocks 38ab7ad
@tarcieri tarcieri Better logic for sleeping via a task 00cfb17
@tarcieri tarcieri Bump version to 0.12.1.pre2 92f3563
@tarcieri tarcieri Bump to 0.12.1 (with CHANGES) 17b4079
@tarcieri tarcieri Disable the IncidentReporter by default
The IncidentReporter is untested and probably not ready for primetime
yet. This change disables it by default and uses similar logging to
0.12.0, which is a stdlib Logger which logs to STDERR.
@tarcieri tarcieri Bump version to 0.12.2 c63e71e
@tarcieri tarcieri Make the exit handler an inheritable property 04fd97d
@tarcieri tarcieri Remove rbx and jruby from allowed failures 6c1772f
@benlangfeld benlangfeld Focus-fail f135337
@tarcieri tarcieri Merge pull request #108 from celluloid/feature/broken_exclusive
Single-method exclusive mode broken
@benlangfeld benlangfeld [BUGFIX] Ensure exclusive mode works correctly for per-method case 96b7f8b
@tarcieri tarcieri Bump version to 0.12.3 636139e
@tarcieri tarcieri Log test output to a logfile 69922df
@schmurfy schmurfy added proxy_class to switch actor proxy class 702dd56
@tarcieri tarcieri Merge pull request #103 from schmurfy/use_proxy
added use_proxy to switch actor proxy class
@schmurfy schmurfy added rb-fsevent gem for guard on Mac OS X b61cb78
@schmurfy schmurfy added method name on call errors 76313fb
@halorgium halorgium Merge pull request #111 from schmurfy/guard_mac
added rb-fsevent gem for guard on Mac OS X
@tarcieri tarcieri Emphasize the docs 1201e86
@tarcieri tarcieri Update Sidekiq URL 03f476e
@tarcieri tarcieri Trololol 'async' programming 41783f1
@tarcieri tarcieri Fix exclusive mode
Celluloid 0.12.1 and subsequent releases completely broke exclusive
mode. This corrects the problem and adds additional tests to ensure it
won't regress in the future.

The code makes so much sense to me now after this change. :+1:

tarcieri and others added some commits
@tarcieri tarcieri Merge pull request #110 from schmurfy/improved_call_error
added method name on call errors
@tarcieri tarcieri Use debug loglevel for termination messages 04f2820
@tarcieri tarcieri Improved debugging for fiber-related errors
Attempt to improve the fiber debugging situation by providing more
context for fiber-related errors from the original exception messages
and also provide a link to the Celluloid wiki with debugging
@tarcieri tarcieri API documentation f07e038
RageLtMan fix TaskWithThreadLocals, remove Task superclass ec83a2a

I think if I loop back on this I'll do a rewrite of the existing code...

@tarcieri tarcieri closed this


travis was b0rking if i recall.


Works fine for all of my projects which use guard. I'm gonna try out the simpler method with celluloid-io and then perhaps revert this.


Should this be #map rather than #each?



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.