celluloid/celluloid — pull request #224 by tarcieri (2013-04-20 19:27:02+00:00)
Title: Actor-local Celluloid::Thread#[] support

An initial spike of redirecting the methods that ordinarily deal with
Ruby thread (or, in fact, fiber) locals to a set of locals on the
Celluloid::Actor object for the current thread/fiber.

A bit of history: there existed a bunch of Ruby code which abused
Thread.current[...] as a means of achieving dynamic scope. This code
became broken when Fibers were introduced. However, rather than adding
Fiber#[] and having people who want to have pseudo-dynamic scope use
Fiber.current[...] instead of Thread.current[...], the decision was made
to make Thread.current[...] Fiber local, and for it we all suffer.

This breaks a litany of gems that use thread locals actually expecting
them to be thread local (instead of fiber local), most notably
ActiveRecord, but including any gem that tries to store a connection to
a service in a thread local.

This commit is an initial attempt to generally fix this problem
throughout Celluloid, and it's accomplished without using any core
extensions, but instead overriding the thread local behavior inside of
Celluloid::Thread (itself a subclass of Thread).

All methods for accessing thread locals are treated as "actor locals"
instead with this change, thunking to a hash stored in the
Celluloid::Actor object for the current actor.

This implementation is a bit of a hack because Celluloid has its own set
of "special" thread locals it needs to operate. It's hoped that this
commit can also provide a new set of APIs (e.g. Thread.current.actor)
which can be used to replace Celluloid's own internal usage of thread
locals, and thus help clean up Celluloid's internals at the same time.