Mark Chavez
eat. sleep. repeat. 👾 coding, ⌨️ keyboarding, 🚴🏼 cycling.
Thread-safe Ruby Code 02/15/2024

References:

đź’ˇ

Idiomatic Ruby code is most often thread-safe Ruby code.

Avoid mutating globals

Global objects are implicitly shared between all threads. Not thread-safe!

$counter = 0
puts "Hey threads, go ahead and increment me at will!"
✅ This is OK, because it doesn’t modify global state
class RainyCloudFactory
def self.generate
cloud = Cloud.new
cloud.rain!

cloud
end
end
❌ This is NOT OK, because it modifies global state, in this case, a class variable
class RainyCloudFactory
def self.generate
cloud = Cloud.new
@@clouds << cloud

cloud
end
end
What’s a thread-local?

A thread-local lets you define a variable that is global to the scope of the current thread. It’s a global variable that is locally scoped on a per-thread basis.

Example

# Instead of
$redis = Redis.new

# Use
Thread.current[:redis] = Redis.new

If your program is running N threads, it will open N connections to redis as well.

đź’ˇ

The same heuristic is applicable to a background job processor. Each job will be handled by a separate thread. A thread may process multiple jobs in its lifetime, but a job will only be processed by a single thread in its lifecycle.

Again, the path to thread safety is clear: create the necessary objects that you need in the body of the job, rather than sharing any global state.