GitXplorerGitXplorer
M

threadlocal

public
5 stars
0 forks
1 issues

Commits

List of commits on branch master.
Unverified
74eecc6464ff472739cf530215bb1bc609e50886

Add tests for ThreadLocalDelegator.

MMSch committed 11 years ago
Unverified
bf31a9de7e6e25b58586b7d3c0478610d07557a5

Run tests via Rake

MMSch committed 11 years ago
Unverified
95c1a0dacf07e168e887d2cf4df666eb799f4aaa

Cleaner code

MMSch committed 11 years ago
Unverified
bed16822ec243eaa4bf186815a005c632923b82f

fix

MMSch committed 11 years ago
Unverified
9fab4ae6fd99585976975c8b376e929cba0edb5c

Get rid of VERSION constant

MMSch committed 11 years ago
Unverified
8b97a1d91e70b8cfcde7dd059f677eaa90ab4f31

Use object_id instead of counting ourself

MMSch committed 11 years ago

README

The README file for this repository.

threadlocal

Build Status

Ruby's thread local variables are badly designed compared to other languages, even Java or Python.

This gem fixes that.

Why?

In Ruby there's a global namespace of thread local names that are accessed like that:

Thread.current.thread_variable_get(:some_global_name)

This has two implications:

  1. If e.g. Rails uses the :time_zone thread variable you can't. Obviously.
  2. If an object uses a thread variable it has to make sure it cleans up after itself when it gets garbage collected.

In Java or Python instead of a global namespace where you assign keys to values you just create a new instance of a ThreadLocal (or threading.local) object, like this:

class MyThingy
  def initialize
    @some_setting = ThreadLocal.new(false)
  end

  def do_something
    if @some_setting.get == true
      # Do something only if it's enabled
    end
  end

  def enable_setting
    @some_setting.set(true)
  end
end

a = MyThingy.new
b = MyThingy.new

a and b have different ivars which means their thread-local setting will never clash. And when one of them gets garbage collected the thread local variable is cleaned up across all threads (not that important for a boolean but really important in the general case.) Success!

Obviously this works just as well

class MyThingy
  @settings = ThreadLocal.new({})

  def self.settings
    @settings.get
  end
end

MyThingy.settings[:whatever] # this is per thread now

The threadlocal gem works and is tested on Ruby 2.0 and 2.1, JRuby can use Java's built-in ThreadLocal (making this transparent is on the roadmap.)

ThreadLocalDelegator

There's also ThreadLocalDelegator which is mostly useful when supplied with a default value / default proc.

class MyThingy
  @settings = ThreadLocalDelegator.new({}) # will do {}.dup for every new thread since that's the default value

  def self.enable_something
    @settings[:something] = true
  end
end

Acknowledgements

Thanks to