espace / neverblock forked from oldmoe/neverblock
- Source
- Commits
- Network (6)
- Issues (2)
- Downloads (0)
- Wiki (1)
- Graphs
-
Branch:
master
neverblock / lib / never_block.rb
| 505d63e5 » | humanzz | 2008-08-17 | 1 | # Author:: Mohammad A. Ali (mailto:oldmoe@gmail.com) | |
| 2 | # Copyright:: Copyright (c) 2008 eSpace, Inc. | ||||
| 3 | # License:: Distributes under the same terms as Ruby | ||||
| 4 | |||||
| 8ea633a3 » | espace | 2008-08-13 | 5 | $:.unshift File.expand_path(File.dirname(__FILE__)) | |
| 6 | |||||
| 050ce0b5 » | oldmoe | 2008-10-28 | 7 | # Thanks to Aman Gupta for writing the Ruby 1.8 Fiber simulator | |
| c412799c » | humanzz | 2008-09-01 | 8 | unless defined? Fiber | |
| 9 | require 'thread' | ||||
| 10 | require 'singleton' | ||||
| 8c9b5f18 » | oldmoe | 2008-08-31 | 11 | class FiberError < StandardError; end | |
| 12 | class Fiber | ||||
| 13 | def initialize | ||||
| 14 | raise ArgumentError, 'new Fiber requires a block' unless block_given? | ||||
| 15 | |||||
| 16 | @yield = Queue.new | ||||
| 17 | @resume = Queue.new | ||||
| c412799c » | humanzz | 2008-09-01 | 18 | ||
| 8c9b5f18 » | oldmoe | 2008-08-31 | 19 | @thread = Thread.new{ @yield.push [ *yield(*@resume.pop) ] } | |
| 20 | @thread.abort_on_exception = true | ||||
| 21 | @thread[:fiber] = self | ||||
| 22 | end | ||||
| 23 | attr_reader :thread | ||||
| 24 | |||||
| 25 | def resume *args | ||||
| 26 | raise FiberError, 'dead fiber called' unless @thread.alive? | ||||
| 27 | @resume.push(args) | ||||
| 28 | result = @yield.pop | ||||
| 29 | result.size > 1 ? result : result.first | ||||
| 30 | end | ||||
| 31 | |||||
| 32 | def yield *args | ||||
| 33 | @yield.push(args) | ||||
| 34 | result = @resume.pop | ||||
| 35 | result.size > 1 ? result : result.first | ||||
| 36 | end | ||||
| 37 | |||||
| 38 | def self.yield *args | ||||
| 39 | raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber] | ||||
| 40 | fiber.yield(*args) | ||||
| 41 | end | ||||
| 42 | |||||
| 43 | def self.current | ||||
| 44 | Thread.current[:fiber] or raise FiberError, 'not inside a fiber' | ||||
| 45 | end | ||||
| 46 | |||||
| 47 | def inspect | ||||
| 48 | "#<#{self.class}:0x#{self.object_id.to_s(16)}>" | ||||
| 49 | end | ||||
| c412799c » | humanzz | 2008-09-01 | 50 | end | |
| 51 | |||||
| 52 | class RootFiber < Fiber | ||||
| 53 | include Singleton | ||||
| 54 | def initialize | ||||
| 55 | end | ||||
| 56 | |||||
| 57 | def resume *args | ||||
| 58 | raise FiberError, "can't resume root fiber" | ||||
| 59 | end | ||||
| 60 | |||||
| 61 | def yield *args | ||||
| 62 | raise FiberError, "can't yield from root fiber" | ||||
| 63 | end | ||||
| 64 | end | ||||
| 65 | |||||
| 66 | #attach the root fiber to the main thread | ||||
| 67 | Thread.main[:fiber] = RootFiber.instance | ||||
| 3890c345 » | oldmoe | 2008-09-02 | 68 | else | |
| 69 | require 'fiber' | ||||
| 8c9b5f18 » | oldmoe | 2008-08-31 | 70 | end | |
| 71 | |||||
| 8ea633a3 » | espace | 2008-08-13 | 72 | require 'never_block/extensions/fiber_extensions' | |
| 73 | require 'never_block/pool/fiber_pool' | ||||
| 74 | require 'never_block/pool/fibered_connection_pool' | ||||
| 75 | |||||
| 76 | module NeverBlock | ||||
| a413092f » | humanzz | 2008-10-23 | 77 | ||
| 78 | # Checks if we should be working in a non-blocking mode | ||||
| 79 | def self.neverblocking? | ||||
| 80 | Fiber.respond_to?(:current) && Fiber.current[:neverblock] | ||||
| 81 | end | ||||
| 82 | |||||
| 83 | def self.event_loop_available? | ||||
| 84 | defined?(EM) && EM.reactor_running? | ||||
| 85 | end | ||||
| 86 | |||||
| 87 | # The given block will run its queries either in blocking or non-blocking | ||||
| 88 | # mode based on the first parameter | ||||
| 0c8155ad » | humanzz | 2008-09-03 | 89 | def self.neverblock(nb = true, &block) | |
| 90 | status = Fiber.current[:neverblock] | ||||
| 91 | Fiber.current[:neverblock] = nb | ||||
| 92 | block.call | ||||
| 93 | Fiber.current[:neverblock] = status | ||||
| 94 | end | ||||
| bfbd3084 » | humanzz | 2008-10-27 | 95 | ||
| 96 | # Exception to be thrown for all neverblock internal errors | ||||
| 97 | class NBError < StandardError | ||||
| 98 | end | ||||
| 99 | |||||
| 8ea633a3 » | espace | 2008-08-13 | 100 | end | |
| 09c1320a » | modsaid | 2009-02-11 | 101 | puts "Using Neverblock" | |
| 8c9b5f18 » | oldmoe | 2008-08-31 | 102 | NB = NeverBlock | |
