![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /var/lib/gems/2.5.0/gems/em-synchrony-1.0.3/lib/em-synchrony/ |
Upload File : |
module EventMachine module Synchrony class ConnectionPool undef :send def initialize(opts, &block) @reserved = {} # map of in-progress connections @available = [] # pool of free connections @pending = [] # pending reservations (FIFO) opts[:size].times do @available.push(block.call) if block_given? end end # Choose first available connection and pass it to the supplied # block. This will block indefinitely until there is an available # connection to service the request. def execute(async) f = Fiber.current begin conn = acquire(f) yield conn ensure release(f) if not async end end private # Acquire a lock on a connection and assign it to executing fiber # - if connection is available, pass it back to the calling block # - if pool is full, yield the current fiber until connection is available def acquire(fiber) if conn = @available.pop @reserved[fiber.object_id] = conn conn else Fiber.yield @pending.push fiber acquire(fiber) end end # Release connection assigned to the supplied fiber and # resume any other pending connections (which will # immediately try to run acquire on the pool) def release(fiber) @available.push(@reserved.delete(fiber.object_id)) if pending = @pending.shift pending.resume end end # Allow the pool to behave as the underlying connection # # If the requesting method begins with "a" prefix, then # hijack the callbacks and errbacks to fire a connection # pool release whenever the request is complete. Otherwise # yield the connection within execute method and release # once it is complete (assumption: fiber will yield until # data is available, or request is complete) # def method_missing(method, *args, &blk) async = (method[0,1] == "a") execute(async) do |conn| df = conn.__send__(method, *args, &blk) if async fiber = Fiber.current df.callback { release(fiber) } df.errback { release(fiber) } end df end end end end end