celluloid 0.13.0.pre → 0.13.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +16 -15
- data/lib/celluloid.rb +34 -9
- data/lib/celluloid/actor.rb +21 -23
- data/lib/celluloid/autostart.rb +16 -0
- data/lib/celluloid/calls.rb +21 -18
- data/lib/celluloid/condition.rb +9 -3
- data/lib/celluloid/cpu_counter.rb +7 -1
- data/lib/celluloid/future.rb +1 -1
- data/lib/celluloid/logger.rb +5 -1
- data/lib/celluloid/pool_manager.rb +1 -1
- data/lib/celluloid/stack_dump.rb +19 -11
- data/lib/celluloid/supervision_group.rb +1 -1
- data/lib/celluloid/tasks.rb +28 -0
- data/lib/celluloid/tasks/task_thread.rb +8 -2
- data/lib/celluloid/version.rb +1 -1
- data/spec/support/actor_examples.rb +18 -1
- data/spec/support/example_actor_class.rb +4 -0
- data/spec/support/task_examples.rb +9 -0
- metadata +3 -3
- data/lib/celluloid/boot.rb +0 -23
    
        data/README.md
    CHANGED
    
    | @@ -1,8 +1,10 @@ | |
| 1 1 | 
             
            
         | 
| 2 2 | 
             
            =========
         | 
| 3 | 
            +
            [](http://rubygems.org/gems/celluloid)
         | 
| 3 4 | 
             
            [](http://travis-ci.org/celluloid/celluloid)
         | 
| 4 5 | 
             
            [](https://gemnasium.com/celluloid/celluloid)
         | 
| 5 6 | 
             
            [](https://codeclimate.com/github/celluloid/celluloid)
         | 
| 7 | 
            +
            [](https://coveralls.io/r/celluloid/celluloid)
         | 
| 6 8 |  | 
| 7 9 | 
             
            > "I thought of objects being like biological cells and/or individual
         | 
| 8 10 | 
             
            > computers on a network, only able to communicate with messages"
         | 
| @@ -71,6 +73,10 @@ library. | |
| 71 73 | 
             
            Like Celluloid? [Join the Google Group](http://groups.google.com/group/celluloid-ruby)
         | 
| 72 74 | 
             
            or visit us on IRC at #celluloid on freenode
         | 
| 73 75 |  | 
| 76 | 
            +
            ### Is it any good?
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            [Yes](http://news.ycombinator.com/item?id=3067434)
         | 
| 79 | 
            +
             | 
| 74 80 | 
             
            ### Is It "Production Ready™"?
         | 
| 75 81 |  | 
| 76 82 | 
             
            Yes, many users are now running Celluloid in production by using
         | 
| @@ -104,25 +110,20 @@ Or install it yourself as: | |
| 104 110 |  | 
| 105 111 | 
             
                $ gem install celluloid
         | 
| 106 112 |  | 
| 107 | 
            -
            Inside of your Ruby program  | 
| 108 | 
            -
             | 
| 109 | 
            -
                require 'celluloid'
         | 
| 113 | 
            +
            Inside of your Ruby program, require Celluloid with:
         | 
| 110 114 |  | 
| 111 | 
            -
             | 
| 115 | 
            +
                require 'celluloid/autostart'
         | 
| 112 116 |  | 
| 113 117 | 
             
            Supported Platforms
         | 
| 114 118 | 
             
            -------------------
         | 
| 115 119 |  | 
| 116 | 
            -
            Celluloid works on Ruby 1.9.3, JRuby 1.6 | 
| 117 | 
            -
            are the preferred platforms as they support true thread-level parallelism when
         | 
| 118 | 
            -
            executing Ruby code, whereas MRI/YARV is constrained by a global interpreter
         | 
| 119 | 
            -
            lock (GIL) and can only execute one thread at a time.
         | 
| 120 | 
            +
            Celluloid works on Ruby 1.9.3, 2.0.0, JRuby 1.6+, and Rubinius 2.0.
         | 
| 120 121 |  | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 122 | 
            +
            JRuby or Rubinius are the preferred platforms as they support true thread-level
         | 
| 123 | 
            +
            parallelism when executing Ruby code, whereas MRI/YARV is constrained by a global
         | 
| 124 | 
            +
            interpreter lock (GIL) and can only execute one thread at a time.
         | 
| 123 125 |  | 
| 124 | 
            -
             | 
| 125 | 
            -
            * rbx: -X19 command line option
         | 
| 126 | 
            +
            Celluloid requires Ruby 1.9 mode on all interpreters.
         | 
| 126 127 |  | 
| 127 128 | 
             
            Additional Reading
         | 
| 128 129 | 
             
            ------------------
         | 
| @@ -134,9 +135,9 @@ Contributing to Celluloid | |
| 134 135 | 
             
            -------------------------
         | 
| 135 136 |  | 
| 136 137 | 
             
            * Fork this repository on github
         | 
| 137 | 
            -
            * Make your changes and send  | 
| 138 | 
            -
            * If  | 
| 139 | 
            -
            * If  | 
| 138 | 
            +
            * Make your changes and send us a pull request
         | 
| 139 | 
            +
            * If we like them we'll merge them
         | 
| 140 | 
            +
            * If we've accepted a patch, feel free to ask for commit access
         | 
| 140 141 |  | 
| 141 142 | 
             
            License
         | 
| 142 143 | 
             
            -------
         | 
    
        data/lib/celluloid.rb
    CHANGED
    
    | @@ -6,16 +6,14 @@ require 'set' | |
| 6 6 | 
             
            module Celluloid
         | 
| 7 7 | 
             
              extend self # expose all instance methods as singleton methods
         | 
| 8 8 |  | 
| 9 | 
            -
              # How long actors have to terminate
         | 
| 10 | 
            -
              SHUTDOWN_TIMEOUT = 10
         | 
| 11 | 
            -
             | 
| 12 9 | 
             
              # Warning message added to Celluloid objects accessed outside their actors
         | 
| 13 10 | 
             
              BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT "
         | 
| 14 11 |  | 
| 15 12 | 
             
              class << self
         | 
| 16 | 
            -
                attr_accessor :internal_pool | 
| 17 | 
            -
                attr_accessor :logger | 
| 18 | 
            -
                attr_accessor :task_class | 
| 13 | 
            +
                attr_accessor :internal_pool    # Internal thread pool
         | 
| 14 | 
            +
                attr_accessor :logger           # Thread-safe logger class
         | 
| 15 | 
            +
                attr_accessor :task_class       # Default task type to use
         | 
| 16 | 
            +
                attr_accessor :shutdown_timeout # How long actors have to terminate
         | 
| 19 17 |  | 
| 20 18 | 
             
                def included(klass)
         | 
| 21 19 | 
             
                  klass.send :extend,  ClassMethods
         | 
| @@ -50,9 +48,26 @@ module Celluloid | |
| 50 48 | 
             
                  Logger.exception_handler(&block)
         | 
| 51 49 | 
             
                end
         | 
| 52 50 |  | 
| 51 | 
            +
                def suspend(status, waiter)
         | 
| 52 | 
            +
                  task = Thread.current[:celluloid_task]
         | 
| 53 | 
            +
                  if task && !Celluloid.exclusive?
         | 
| 54 | 
            +
                    waiter.before_suspend(task) if waiter.respond_to?(:before_suspend)
         | 
| 55 | 
            +
                    Task.suspend(status)
         | 
| 56 | 
            +
                  else
         | 
| 57 | 
            +
                    waiter.wait
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                # Launch default services
         | 
| 62 | 
            +
                # FIXME: We should set up the supervision hierarchy here
         | 
| 63 | 
            +
                def boot
         | 
| 64 | 
            +
                  Celluloid::Notifications::Fanout.supervise_as :notifications_fanout
         | 
| 65 | 
            +
                  Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 53 68 | 
             
                # Shut down all running actors
         | 
| 54 69 | 
             
                def shutdown
         | 
| 55 | 
            -
                  Timeout.timeout( | 
| 70 | 
            +
                  Timeout.timeout(shutdown_timeout) do
         | 
| 56 71 | 
             
                    actors = Actor.all
         | 
| 57 72 | 
             
                    Logger.debug "Terminating #{actors.size} actors..." if actors.size > 0
         | 
| 58 73 |  | 
| @@ -77,7 +92,7 @@ module Celluloid | |
| 77 92 | 
             
                    Logger.debug "Shutdown completed cleanly"
         | 
| 78 93 | 
             
                  end
         | 
| 79 94 | 
             
                rescue Timeout::Error => ex
         | 
| 80 | 
            -
                  Logger.error("Couldn't cleanly terminate all actors in #{ | 
| 95 | 
            +
                  Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!")
         | 
| 81 96 | 
             
                end
         | 
| 82 97 | 
             
              end
         | 
| 83 98 |  | 
| @@ -204,6 +219,12 @@ module Celluloid | |
| 204 219 | 
             
                  end
         | 
| 205 220 | 
             
                end
         | 
| 206 221 |  | 
| 222 | 
            +
                # Mark methods as running blocks on the receiver
         | 
| 223 | 
            +
                def execute_block_on_receiver(*methods)
         | 
| 224 | 
            +
                  # A noop method in preparation
         | 
| 225 | 
            +
                  # See https://github.com/celluloid/celluloid/pull/55
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 207 228 | 
             
                # Configuration options for Actor#new
         | 
| 208 229 | 
             
                def actor_options
         | 
| 209 230 | 
             
                  {
         | 
| @@ -457,4 +478,8 @@ require 'celluloid/notifications' | |
| 457 478 | 
             
            require 'celluloid/logging'
         | 
| 458 479 |  | 
| 459 480 | 
             
            require 'celluloid/legacy' unless defined?(CELLULOID_FUTURE)
         | 
| 460 | 
            -
             | 
| 481 | 
            +
             | 
| 482 | 
            +
            # Configure default systemwide settings
         | 
| 483 | 
            +
            Celluloid.task_class = Celluloid::TaskFiber
         | 
| 484 | 
            +
            Celluloid.logger     = Logger.new(STDERR)
         | 
| 485 | 
            +
            Celluloid.shutdown_timeout = 10
         | 
    
        data/lib/celluloid/actor.rb
    CHANGED
    
    | @@ -66,19 +66,7 @@ module Celluloid | |
| 66 66 | 
             
                      raise DeadActorError, "attempted to call a dead actor"
         | 
| 67 67 | 
             
                    end
         | 
| 68 68 |  | 
| 69 | 
            -
                     | 
| 70 | 
            -
                      Task.suspend(:callwait).value
         | 
| 71 | 
            -
                    else
         | 
| 72 | 
            -
                      response = loop do
         | 
| 73 | 
            -
                        message = Thread.mailbox.receive do |msg|
         | 
| 74 | 
            -
                          msg.respond_to?(:call) and msg.call == call
         | 
| 75 | 
            -
                        end
         | 
| 76 | 
            -
                        break message unless message.is_a?(SystemEvent)
         | 
| 77 | 
            -
                        Thread.current[:celluloid_actor].handle_system_event(message)
         | 
| 78 | 
            -
                      end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                      response.value
         | 
| 81 | 
            -
                    end
         | 
| 69 | 
            +
                    Celluloid.suspend(:callwait, call).value
         | 
| 82 70 | 
             
                  end
         | 
| 83 71 |  | 
| 84 72 | 
             
                  # Invoke a method asynchronously on an actor via its mailbox
         | 
| @@ -168,7 +156,7 @@ module Celluloid | |
| 168 156 | 
             
                  @exclusives   = options[:exclusive_methods]
         | 
| 169 157 | 
             
                  @task_class   = options[:task_class] || Celluloid.task_class
         | 
| 170 158 |  | 
| 171 | 
            -
                  @tasks     =  | 
| 159 | 
            +
                  @tasks     = TaskSet.new
         | 
| 172 160 | 
             
                  @links     = Links.new
         | 
| 173 161 | 
             
                  @signals   = Signals.new
         | 
| 174 162 | 
             
                  @receivers = Receivers.new
         | 
| @@ -308,15 +296,25 @@ module Celluloid | |
| 308 296 | 
             
                  @timers.every(interval) { task(:timer, &block) }
         | 
| 309 297 | 
             
                end
         | 
| 310 298 |  | 
| 299 | 
            +
                class Sleeper
         | 
| 300 | 
            +
                  def initialize(timers, interval)
         | 
| 301 | 
            +
                    @timers = timers
         | 
| 302 | 
            +
                    @interval = interval
         | 
| 303 | 
            +
                  end
         | 
| 304 | 
            +
             | 
| 305 | 
            +
                  def before_suspend(task)
         | 
| 306 | 
            +
                    @timers.after(@interval) { task.resume }
         | 
| 307 | 
            +
                  end
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                  def wait
         | 
| 310 | 
            +
                    Kernel.sleep(@interval)
         | 
| 311 | 
            +
                  end
         | 
| 312 | 
            +
                end
         | 
| 313 | 
            +
             | 
| 311 314 | 
             
                # Sleep for the given amount of time
         | 
| 312 315 | 
             
                def sleep(interval)
         | 
| 313 | 
            -
                   | 
| 314 | 
            -
                   | 
| 315 | 
            -
                    @timers.after(interval) { task.resume }
         | 
| 316 | 
            -
                    Task.suspend :sleeping
         | 
| 317 | 
            -
                  else
         | 
| 318 | 
            -
                    Kernel.sleep(interval)
         | 
| 319 | 
            -
                  end
         | 
| 316 | 
            +
                  sleeper = Sleeper.new(@timers, interval)
         | 
| 317 | 
            +
                  Celluloid.suspend(:sleeping, sleeper)
         | 
| 320 318 | 
             
                end
         | 
| 321 319 |  | 
| 322 320 | 
             
                # Handle standard low-priority messages
         | 
| @@ -390,7 +388,7 @@ module Celluloid | |
| 390 388 | 
             
                  end
         | 
| 391 389 |  | 
| 392 390 | 
             
                  finalizer = @subject.class.finalizer
         | 
| 393 | 
            -
                  if finalizer && @subject.respond_to?(finalizer)
         | 
| 391 | 
            +
                  if finalizer && @subject.respond_to?(finalizer, true)
         | 
| 394 392 | 
             
                    task(:finalizer, :finalize) { @subject.__send__(finalizer) }
         | 
| 395 393 | 
             
                  end
         | 
| 396 394 | 
             
                rescue => ex
         | 
| @@ -415,7 +413,7 @@ module Celluloid | |
| 415 413 |  | 
| 416 414 | 
             
                # Run a method inside a task unless it's exclusive
         | 
| 417 415 | 
             
                def task(task_type, method_name = nil, &block)
         | 
| 418 | 
            -
                  if @exclusives && (@exclusives == :all || @exclusives.include?(method_name.to_sym))
         | 
| 416 | 
            +
                  if @exclusives && (@exclusives == :all || (method_name && @exclusives.include?(method_name.to_sym)))
         | 
| 419 417 | 
             
                    exclusive { block.call }
         | 
| 420 418 | 
             
                  else
         | 
| 421 419 | 
             
                    @task_class.new(task_type, &block).resume
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'celluloid'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Celluloid.boot
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # Terminate all actors at exit
         | 
| 6 | 
            +
            at_exit do
         | 
| 7 | 
            +
              if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION >= "1.9"
         | 
| 8 | 
            +
                # workaround for MRI bug losing exit status in at_exit block
         | 
| 9 | 
            +
                # http://bugs.ruby-lang.org/issues/5218
         | 
| 10 | 
            +
                exit_status = $!.status if $!.is_a?(SystemExit)
         | 
| 11 | 
            +
                Celluloid.shutdown
         | 
| 12 | 
            +
                exit exit_status if exit_status
         | 
| 13 | 
            +
              else
         | 
| 14 | 
            +
                Celluloid.shutdown
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
    
        data/lib/celluloid/calls.rb
    CHANGED
    
    | @@ -11,34 +11,37 @@ module Celluloid | |
| 11 11 | 
             
                  obj.public_send(@method, *@arguments, &@block)
         | 
| 12 12 | 
             
                rescue NoMethodError => ex
         | 
| 13 13 | 
             
                  # Abort if the caller made a mistake
         | 
| 14 | 
            -
                   | 
| 14 | 
            +
                  raise AbortError.new(ex) unless obj.respond_to? @method
         | 
| 15 15 |  | 
| 16 16 | 
             
                  # Otherwise something blew up. Crash this actor
         | 
| 17 17 | 
             
                  raise
         | 
| 18 18 | 
             
                rescue ArgumentError => ex
         | 
| 19 19 | 
             
                  # Abort if the caller made a mistake
         | 
| 20 | 
            -
                   | 
| 21 | 
            -
             | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
              private
         | 
| 20 | 
            +
                  begin
         | 
| 21 | 
            +
                    arity = obj.method(@method).arity
         | 
| 22 | 
            +
                  rescue NameError
         | 
| 23 | 
            +
                    # In theory this shouldn't happen, but just in case
         | 
| 24 | 
            +
                    raise AbortError.new(ex)
         | 
| 25 | 
            +
                  end
         | 
| 27 26 |  | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                   | 
| 31 | 
            -
                     | 
| 32 | 
            -
                     | 
| 27 | 
            +
                  if arity >= 0
         | 
| 28 | 
            +
                    raise AbortError.new(ex) if @arguments.size != arity
         | 
| 29 | 
            +
                  elsif arity < -1
         | 
| 30 | 
            +
                    mandatory_args = -arity - 1
         | 
| 31 | 
            +
                    raise AbortError.new(ex) if arguments.size < mandatory_args
         | 
| 33 32 | 
             
                  end
         | 
| 34 33 |  | 
| 35 | 
            -
                   | 
| 34 | 
            +
                  # Otherwise something blew up. Crash this actor
         | 
| 35 | 
            +
                  raise
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            -
                 | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 38 | 
            +
                def wait
         | 
| 39 | 
            +
                  loop do
         | 
| 40 | 
            +
                    message = Thread.mailbox.receive do |msg|
         | 
| 41 | 
            +
                      msg.respond_to?(:call) and msg.call == self
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    break message unless message.is_a?(SystemEvent)
         | 
| 44 | 
            +
                    Thread.current[:celluloid_actor].handle_system_event(message)
         | 
| 42 45 | 
             
                  end
         | 
| 43 46 | 
             
                end
         | 
| 44 47 | 
             
              end
         | 
    
        data/lib/celluloid/condition.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ module Celluloid | |
| 7 7 |  | 
| 8 8 | 
             
                def initialize
         | 
| 9 9 | 
             
                  @mutex = Mutex.new
         | 
| 10 | 
            -
                  @owner =  | 
| 10 | 
            +
                  @owner = Thread.current[:celluloid_actor]
         | 
| 11 11 | 
             
                  @tasks = []
         | 
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| @@ -16,7 +16,9 @@ module Celluloid | |
| 16 16 | 
             
                  raise ConditionError, "cannot wait for signals while exclusive" if Celluloid.exclusive?
         | 
| 17 17 |  | 
| 18 18 | 
             
                  @mutex.synchronize do
         | 
| 19 | 
            -
                     | 
| 19 | 
            +
                    actor = Thread.current[:celluloid_actor]
         | 
| 20 | 
            +
                    raise ConditionError, "can't wait for conditions outside actors" unless actor
         | 
| 21 | 
            +
                    raise ConditionError, "can't wait unless owner" unless actor == @owner
         | 
| 20 22 | 
             
                    @tasks << Task.current
         | 
| 21 23 | 
             
                  end
         | 
| 22 24 |  | 
| @@ -27,7 +29,9 @@ module Celluloid | |
| 27 29 |  | 
| 28 30 | 
             
                # Send a signal to the first task waiting on this condition
         | 
| 29 31 | 
             
                def signal(value = nil)
         | 
| 30 | 
            -
             | 
| 32 | 
            +
                  @mutex.synchronize do
         | 
| 33 | 
            +
                    raise ConditionError, "no owner for this condition" unless @owner
         | 
| 34 | 
            +
             | 
| 31 35 | 
             
                    if task = @tasks.shift
         | 
| 32 36 | 
             
                      @owner.mailbox << SignalConditionRequest.new(task, value)
         | 
| 33 37 | 
             
                    else
         | 
| @@ -39,6 +43,8 @@ module Celluloid | |
| 39 43 | 
             
                # Broadcast a value to all waiting tasks
         | 
| 40 44 | 
             
                def broadcast(value = nil)
         | 
| 41 45 | 
             
                  @mutex.synchronize do
         | 
| 46 | 
            +
                    raise ConditionError, "no owner for this condition" unless @owner
         | 
| 47 | 
            +
             | 
| 42 48 | 
             
                    @tasks.each { |task| @owner.mailbox << SignalConditionRequest.new(task, value) }
         | 
| 43 49 | 
             
                    @tasks.clear
         | 
| 44 50 | 
             
                  end
         | 
| @@ -6,7 +6,11 @@ module Celluloid | |
| 6 6 | 
             
                when 'darwin'
         | 
| 7 7 | 
             
                  @cores = Integer(`sysctl hw.ncpu`[/\d+/])
         | 
| 8 8 | 
             
                when 'linux'
         | 
| 9 | 
            -
                  @cores = File. | 
| 9 | 
            +
                  @cores = if File.exists?("/sys/devices/system/cpu/present")
         | 
| 10 | 
            +
                    File.read("/sys/devices/system/cpu/present").split('-').last.to_i+1
         | 
| 11 | 
            +
                  else
         | 
| 12 | 
            +
                    Dir["/sys/devices/system/cpu/cpu*"].select { |n| n=~/cpu\d+/ }.count
         | 
| 13 | 
            +
                  end
         | 
| 10 14 | 
             
                when 'mingw', 'mswin'
         | 
| 11 15 | 
             
                  @cores = Integer(`SET NUMBER_OF_PROCESSORS`[/\d+/])
         | 
| 12 16 | 
             
                else
         | 
| @@ -16,3 +20,5 @@ module Celluloid | |
| 16 20 | 
             
                def self.cores; @cores; end
         | 
| 17 21 | 
             
              end
         | 
| 18 22 | 
             
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
    
        data/lib/celluloid/future.rb
    CHANGED
    
    
    
        data/lib/celluloid/logger.rb
    CHANGED
    
    | @@ -53,7 +53,11 @@ module Celluloid | |
| 53 53 | 
             
                # Format an exception message
         | 
| 54 54 | 
             
                def format_exception(exception)
         | 
| 55 55 | 
             
                  str = "#{exception.class}: #{exception.to_s}\n\t"
         | 
| 56 | 
            -
                   | 
| 56 | 
            +
                  if exception.backtrace
         | 
| 57 | 
            +
                    str << exception.backtrace.join("\n\t")
         | 
| 58 | 
            +
                  else
         | 
| 59 | 
            +
                    str << "EMPTY BACKTRACE\n\t"
         | 
| 60 | 
            +
                  end
         | 
| 57 61 | 
             
                end
         | 
| 58 62 | 
             
              end
         | 
| 59 63 | 
             
            end
         | 
    
        data/lib/celluloid/stack_dump.rb
    CHANGED
    
    | @@ -55,32 +55,40 @@ module Celluloid | |
| 55 55 |  | 
| 56 56 | 
             
                def dump(output = STDERR)
         | 
| 57 57 | 
             
                  @actors.each do |actor|
         | 
| 58 | 
            -
                     | 
| 59 | 
            -
                     | 
| 60 | 
            -
                     | 
| 58 | 
            +
                    string = ""
         | 
| 59 | 
            +
                    string << "Celluloid::Actor 0x#{actor.subject_id.to_s(16)}: #{actor.subject_class}"
         | 
| 60 | 
            +
                    string << " [#{actor.name}]" if actor.name
         | 
| 61 | 
            +
                    string << "\n"
         | 
| 61 62 |  | 
| 62 63 | 
             
                    if actor.status == :idle
         | 
| 63 | 
            -
                       | 
| 64 | 
            +
                      string << "State: Idle (waiting for messages)\n"
         | 
| 64 65 | 
             
                    else
         | 
| 65 | 
            -
                       | 
| 66 | 
            -
                       | 
| 66 | 
            +
                      string << "State: Running (executing tasks)\n"
         | 
| 67 | 
            +
                      string << "Tasks:\n"
         | 
| 67 68 |  | 
| 68 69 | 
             
                      actor.tasks.each_with_index do |task, i|
         | 
| 69 | 
            -
                         | 
| 70 | 
            +
                        string << "  #{i+1}) #{task.task_class}: #{task.status}\n"
         | 
| 70 71 | 
             
                      end
         | 
| 71 72 | 
             
                    end
         | 
| 72 73 |  | 
| 73 | 
            -
                    display_backtrace actor.backtrace,  | 
| 74 | 
            +
                    display_backtrace actor.backtrace, string
         | 
| 75 | 
            +
                    output.print string
         | 
| 74 76 | 
             
                  end
         | 
| 75 77 |  | 
| 76 78 | 
             
                  @threads.each do |thread|
         | 
| 77 | 
            -
                     | 
| 78 | 
            -
                     | 
| 79 | 
            +
                    string = ""
         | 
| 80 | 
            +
                    string << "Thread 0x#{thread.thread_id.to_s(16)}:\n"
         | 
| 81 | 
            +
                    display_backtrace thread.backtrace, string
         | 
| 82 | 
            +
                    output.print string
         | 
| 79 83 | 
             
                  end
         | 
| 80 84 | 
             
                end
         | 
| 81 85 |  | 
| 82 86 | 
             
                def display_backtrace(backtrace, output)
         | 
| 83 | 
            -
                   | 
| 87 | 
            +
                  if backtrace
         | 
| 88 | 
            +
                    output << "\t" << backtrace.join("\n\t") << "\n\n"
         | 
| 89 | 
            +
                  else
         | 
| 90 | 
            +
                    output << "EMPTY BACKTRACE\n\n"
         | 
| 91 | 
            +
                  end
         | 
| 84 92 | 
             
                end
         | 
| 85 93 | 
             
              end
         | 
| 86 94 | 
             
            end
         | 
    
        data/lib/celluloid/tasks.rb
    CHANGED
    
    | @@ -25,6 +25,34 @@ module Celluloid | |
| 25 25 | 
             
                  @status = :new
         | 
| 26 26 | 
             
                end
         | 
| 27 27 | 
             
              end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
              class TaskSet
         | 
| 30 | 
            +
                include Enumerable
         | 
| 31 | 
            +
              
         | 
| 32 | 
            +
                def initialize
         | 
| 33 | 
            +
                  @tasks = Set.new
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
                def <<(task)
         | 
| 37 | 
            +
                  @tasks += [task]
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              
         | 
| 40 | 
            +
                def delete(task)
         | 
| 41 | 
            +
                  @tasks -= [task]
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              
         | 
| 44 | 
            +
                def each(&blk)
         | 
| 45 | 
            +
                  @tasks.each &blk
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              
         | 
| 48 | 
            +
                def first
         | 
| 49 | 
            +
                  @tasks.first
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def empty?
         | 
| 53 | 
            +
                  @tasks.empty?
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 28 56 | 
             
            end
         | 
| 29 57 |  | 
| 30 58 | 
             
            require 'celluloid/tasks/task_fiber'
         | 
| @@ -8,6 +8,7 @@ module Celluloid | |
| 8 8 | 
             
                  super
         | 
| 9 9 |  | 
| 10 10 | 
             
                  @resume_queue = Queue.new
         | 
| 11 | 
            +
                  @exception_queue = Queue.new
         | 
| 11 12 | 
             
                  @yield_mutex  = Mutex.new
         | 
| 12 13 | 
             
                  @yield_cond   = ConditionVariable.new
         | 
| 13 14 |  | 
| @@ -19,8 +20,8 @@ module Celluloid | |
| 19 20 |  | 
| 20 21 | 
             
                  @thread = Celluloid.internal_pool.get do
         | 
| 21 22 | 
             
                    begin
         | 
| 22 | 
            -
                      ex = @resume_queue.pop | 
| 23 | 
            -
                      raise ex if ex
         | 
| 23 | 
            +
                      ex = @resume_queue.pop
         | 
| 24 | 
            +
                      raise ex if ex.is_a?(Task::TerminatedError)
         | 
| 24 25 |  | 
| 25 26 | 
             
                      @status = :running
         | 
| 26 27 | 
             
                      Thread.current[:celluloid_actor]    = actor
         | 
| @@ -32,6 +33,8 @@ module Celluloid | |
| 32 33 | 
             
                      yield
         | 
| 33 34 | 
             
                    rescue Task::TerminatedError
         | 
| 34 35 | 
             
                      # Task was explicitly terminated
         | 
| 36 | 
            +
                    rescue Exception => ex
         | 
| 37 | 
            +
                      @exception_queue << ex
         | 
| 35 38 | 
             
                    ensure
         | 
| 36 39 | 
             
                      @status = :dead
         | 
| 37 40 | 
             
                      actor.tasks.delete self
         | 
| @@ -59,6 +62,9 @@ module Celluloid | |
| 59 62 | 
             
                  @yield_mutex.synchronize do
         | 
| 60 63 | 
             
                    @resume_queue.push(value)
         | 
| 61 64 | 
             
                    @yield_cond.wait(@yield_mutex)
         | 
| 65 | 
            +
                    while @exception_queue.size > 0
         | 
| 66 | 
            +
                      raise @exception_queue.pop
         | 
| 67 | 
            +
                    end
         | 
| 62 68 | 
             
                  end
         | 
| 63 69 |  | 
| 64 70 | 
             
                  nil
         | 
    
        data/lib/celluloid/version.rb
    CHANGED
    
    
| @@ -130,6 +130,7 @@ shared_context "a Celluloid Actor" do |included_module| | |
| 130 130 | 
             
                actor.run do
         | 
| 131 131 | 
             
                  Celluloid.actor?
         | 
| 132 132 | 
             
                end.should be_true
         | 
| 133 | 
            +
                actor.should be_actor
         | 
| 133 134 | 
             
              end
         | 
| 134 135 |  | 
| 135 136 | 
             
              it "inspects properly" do
         | 
| @@ -253,7 +254,7 @@ shared_context "a Celluloid Actor" do |included_module| | |
| 253 254 | 
             
                    actor.crash_with_abort_raw 10
         | 
| 254 255 | 
             
                  end.to raise_exception(TypeError, "Exception object/String expected, but Fixnum received")
         | 
| 255 256 |  | 
| 256 | 
            -
                   | 
| 257 | 
            +
                  Celluloid::Actor.join(actor)
         | 
| 257 258 | 
             
                  actor.should_not be_alive
         | 
| 258 259 | 
             
                end
         | 
| 259 260 | 
             
              end
         | 
| @@ -690,6 +691,22 @@ shared_context "a Celluloid Actor" do |included_module| | |
| 690 691 | 
             
                  sleep(interval + Celluloid::TIMER_QUANTUM) # wonky! #/
         | 
| 691 692 | 
             
                  actor.should_not be_fired
         | 
| 692 693 | 
             
                end
         | 
| 694 | 
            +
             | 
| 695 | 
            +
                it "allows delays from outside the actor" do
         | 
| 696 | 
            +
                  actor = @klass.new
         | 
| 697 | 
            +
             | 
| 698 | 
            +
                  interval = Celluloid::TIMER_QUANTUM * 10
         | 
| 699 | 
            +
                  started_at = Time.now
         | 
| 700 | 
            +
                  fired = false
         | 
| 701 | 
            +
             | 
| 702 | 
            +
                  timer = actor.after(interval) do
         | 
| 703 | 
            +
                    fired = true
         | 
| 704 | 
            +
                  end
         | 
| 705 | 
            +
                  fired.should be_false
         | 
| 706 | 
            +
             | 
| 707 | 
            +
                  sleep(interval + Celluloid::TIMER_QUANTUM) # wonky! #/
         | 
| 708 | 
            +
                  fired.should be_true
         | 
| 709 | 
            +
                end
         | 
| 693 710 | 
             
              end
         | 
| 694 711 |  | 
| 695 712 | 
             
              context :tasks do
         | 
| @@ -33,4 +33,13 @@ shared_context "a Celluloid Task" do |task_class| | |
| 33 33 | 
             
                subject.should_not be_running
         | 
| 34 34 | 
             
              end
         | 
| 35 35 |  | 
| 36 | 
            +
              it "raises exceptions outside" do
         | 
| 37 | 
            +
                task = task_class.new(task_type) do
         | 
| 38 | 
            +
                  raise "failure"
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
                expect do
         | 
| 41 | 
            +
                  task.resume
         | 
| 42 | 
            +
                end.to raise_exception("failure")
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 36 45 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: celluloid
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.13.0. | 
| 4 | 
            +
              version: 0.13.0.pre2
         | 
| 5 5 | 
             
              prerelease: 7
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013- | 
| 12 | 
            +
            date: 2013-03-17 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: timers
         | 
| @@ -101,7 +101,7 @@ extra_rdoc_files: [] | |
| 101 101 | 
             
            files:
         | 
| 102 102 | 
             
            - README.md
         | 
| 103 103 | 
             
            - lib/celluloid/actor.rb
         | 
| 104 | 
            -
            - lib/celluloid/ | 
| 104 | 
            +
            - lib/celluloid/autostart.rb
         | 
| 105 105 | 
             
            - lib/celluloid/calls.rb
         | 
| 106 106 | 
             
            - lib/celluloid/condition.rb
         | 
| 107 107 | 
             
            - lib/celluloid/core_ext.rb
         | 
    
        data/lib/celluloid/boot.rb
    DELETED
    
    | @@ -1,23 +0,0 @@ | |
| 1 | 
            -
            # Things to run after Celluloid is fully loaded
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            # Configure default systemwide settings
         | 
| 4 | 
            -
            Celluloid.task_class = Celluloid::TaskFiber
         | 
| 5 | 
            -
            Celluloid.logger     = Logger.new(STDERR)
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            # Launch default services
         | 
| 8 | 
            -
            # FIXME: We should set up the supervision hierarchy here
         | 
| 9 | 
            -
            Celluloid::Notifications::Fanout.supervise_as :notifications_fanout
         | 
| 10 | 
            -
            Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            # Terminate all actors at exit
         | 
| 13 | 
            -
            at_exit do
         | 
| 14 | 
            -
              if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION >= "1.9"
         | 
| 15 | 
            -
                # workaround for MRI bug losing exit status in at_exit block
         | 
| 16 | 
            -
                # http://bugs.ruby-lang.org/issues/5218
         | 
| 17 | 
            -
                exit_status = $!.status if $!.is_a?(SystemExit)
         | 
| 18 | 
            -
                Celluloid.shutdown
         | 
| 19 | 
            -
                exit exit_status if exit_status
         | 
| 20 | 
            -
              else
         | 
| 21 | 
            -
                Celluloid.shutdown
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         |