Sha256: bd64460a57378cdf7cc8e54cf013ec41084d399f242166c8e4bfbf52990b7381
Contents?: true
Size: 1.73 KB
Versions: 1
Compression:
Stored size: 1.73 KB
Contents
# managing connection across forks and threads is tricky. most libraries use # and icky idiom that requires each and every client to configure it's own # forking logic, something like # # MyLameLib.after_for do # # close handles you should close # end # # many libs also do not provide you with per-thread connection, making MT a # manual process. # # a teeny bit of code can solve both. the concept is simple: # # maintain a table of connections scoped by process id and thread id. any # miss will trigger auto-scrubbing the table, but only connections from # another process (we've been forked) will be closed. this gives # # * per thread connections # # * per process connections # # * auto-matic cleanup after a fork # module ForkHandle def version '0.0.1' end @handles = Hash.new @pid = Process.pid @tid = Thread.current.object_id attr_accessor :handles attr_accessor :pid attr_accessor :tid class Key def for(*args) case when args.size == 1 && args.first.is_a?(Key) args.first else new(*args) end end def initialize(pid, tid, key) @pid = pid @tid = tid @key = key end end def key_for(key) Key.for(@pid, @tid, key) end def get(key, &block) @handles.fetch(key_for(key)) do clear! block.call end end alias_method :fetch, :get def set(key, value) @handles[key_for(key)] = value end def clear! each do |key, val| next if key.pid == pid begin val.close rescue nil end end end extend(ForkHandle) end Forkhandle = ForkHandle __END__ ForkHandle.get(:default){ build_default_connection } ForkHandle.set(:default, build_default_connection)
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
forkhandle-0.0.1 | lib/forkhandle.rb |