celluloid 0.18.0.pre → 0.18.0
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.
- checksums.yaml +5 -5
 - data/CHANGES.md +258 -39
 - data/CONDUCT.md +13 -0
 - data/CONTRIBUTING.md +39 -0
 - data/README.md +54 -165
 - data/REFACTOR.md +1 -0
 - data/architecture.md +120 -0
 - data/examples/basic_usage.rb +1 -1
 - data/examples/configurations.rb +78 -0
 - data/examples/futures.rb +1 -1
 - data/examples/ring.rb +5 -4
 - data/examples/simple_pmap.rb +1 -1
 - data/examples/stack.rb +2 -2
 - data/examples/supervisors_and_registry.rb +82 -0
 - data/examples/timers.rb +2 -2
 - data/lib/celluloid.rb +72 -47
 - data/lib/celluloid/actor.rb +27 -17
 - data/lib/celluloid/actor/system.rb +13 -29
 - data/lib/celluloid/autostart.rb +5 -5
 - data/lib/celluloid/call/async.rb +2 -0
 - data/lib/celluloid/call/sync.rb +10 -3
 - data/lib/celluloid/calls.rb +5 -12
 - data/lib/celluloid/cell.rb +5 -9
 - data/lib/celluloid/condition.rb +3 -3
 - data/lib/celluloid/core_ext.rb +0 -2
 - data/lib/celluloid/debug.rb +3 -0
 - data/lib/celluloid/exceptions.rb +2 -2
 - data/lib/celluloid/future.rb +7 -9
 - data/lib/celluloid/group.rb +12 -8
 - data/lib/celluloid/group/pool.rb +1 -3
 - data/lib/celluloid/group/spawner.rb +2 -6
 - data/lib/celluloid/internals/call_chain.rb +15 -0
 - data/lib/celluloid/internals/cpu_counter.rb +62 -0
 - data/lib/celluloid/internals/handlers.rb +42 -0
 - data/lib/celluloid/internals/links.rb +38 -0
 - data/lib/celluloid/internals/logger.rb +104 -0
 - data/lib/celluloid/internals/method.rb +34 -0
 - data/lib/celluloid/internals/properties.rb +32 -0
 - data/lib/celluloid/internals/receivers.rb +64 -0
 - data/lib/celluloid/internals/registry.rb +102 -0
 - data/lib/celluloid/internals/responses.rb +46 -0
 - data/lib/celluloid/internals/signals.rb +24 -0
 - data/lib/celluloid/internals/stack.rb +74 -0
 - data/lib/celluloid/internals/stack/dump.rb +12 -0
 - data/lib/celluloid/internals/stack/states.rb +72 -0
 - data/lib/celluloid/internals/stack/summary.rb +12 -0
 - data/lib/celluloid/internals/task_set.rb +51 -0
 - data/lib/celluloid/internals/thread_handle.rb +52 -0
 - data/lib/celluloid/internals/uuid.rb +40 -0
 - data/lib/celluloid/logging/incident.rb +21 -0
 - data/lib/celluloid/logging/incident_logger.rb +147 -0
 - data/lib/celluloid/logging/incident_reporter.rb +49 -0
 - data/lib/celluloid/logging/log_event.rb +20 -0
 - data/lib/celluloid/logging/ring_buffer.rb +64 -0
 - data/lib/celluloid/mailbox.rb +22 -9
 - data/lib/celluloid/mailbox/evented.rb +13 -5
 - data/lib/celluloid/notifications.rb +95 -0
 - data/lib/celluloid/pool.rb +6 -0
 - data/lib/celluloid/probe.rb +81 -0
 - data/lib/celluloid/proxy/abstract.rb +9 -9
 - data/lib/celluloid/proxy/async.rb +1 -1
 - data/lib/celluloid/proxy/block.rb +2 -2
 - data/lib/celluloid/proxy/cell.rb +1 -1
 - data/lib/celluloid/proxy/future.rb +2 -4
 - data/lib/celluloid/proxy/sync.rb +1 -3
 - data/lib/celluloid/rspec.rb +22 -33
 - data/lib/celluloid/supervision.rb +17 -0
 - data/lib/celluloid/supervision/configuration.rb +169 -0
 - data/lib/celluloid/supervision/configuration/injections.rb +8 -0
 - data/lib/celluloid/supervision/configuration/instance.rb +113 -0
 - data/lib/celluloid/supervision/constants.rb +123 -0
 - data/lib/celluloid/supervision/container.rb +144 -0
 - data/lib/celluloid/supervision/container/behavior.rb +89 -0
 - data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
 - data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
 - data/lib/celluloid/supervision/container/injections.rb +8 -0
 - data/lib/celluloid/supervision/container/instance.rb +116 -0
 - data/lib/celluloid/supervision/container/pool.rb +210 -0
 - data/lib/celluloid/supervision/service.rb +27 -0
 - data/lib/celluloid/supervision/supervise.rb +34 -0
 - data/lib/celluloid/supervision/validation.rb +40 -0
 - data/lib/celluloid/supervision/version.rb +5 -0
 - data/lib/celluloid/system_events.rb +11 -6
 - data/lib/celluloid/task.rb +25 -12
 - data/lib/celluloid/task/fibered.rb +2 -0
 - data/lib/celluloid/task/threaded.rb +3 -3
 - data/lib/celluloid/test.rb +5 -2
 - data/lib/celluloid/thread.rb +0 -2
 - data/lib/celluloid/version.rb +1 -1
 - data/spec/celluloid/block_spec.rb +29 -32
 - data/spec/celluloid/calls_spec.rb +5 -15
 - data/spec/celluloid/future_spec.rb +2 -2
 - data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
 - data/spec/celluloid/internals/links_spec.rb +43 -0
 - data/spec/celluloid/internals/properties_spec.rb +40 -0
 - data/spec/celluloid/internals/registry_spec.rb +62 -0
 - data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
 - data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
 - data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
 - data/spec/celluloid/internals/uuid_spec.rb +9 -0
 - data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
 - data/spec/celluloid/mailbox/evented_spec.rb +11 -22
 - data/spec/celluloid/misc/leak_spec.rb +3 -4
 - data/spec/celluloid/notifications_spec.rb +140 -0
 - data/spec/celluloid/probe_spec.rb +102 -0
 - data/spec/celluloid/proxy_spec.rb +30 -30
 - data/spec/celluloid/supervision/behavior_spec.rb +74 -0
 - data/spec/celluloid/supervision/configuration_spec.rb +181 -0
 - data/spec/celluloid/supervision/container_spec.rb +72 -0
 - data/spec/celluloid/supervision/instance_spec.rb +13 -0
 - data/spec/celluloid/supervision/root_spec.rb +28 -0
 - data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
 - data/spec/celluloid/task/fibered_spec.rb +1 -3
 - data/spec/celluloid/task/threaded_spec.rb +1 -3
 - data/spec/shared/actor_examples.rb +58 -33
 - data/spec/shared/group_examples.rb +2 -2
 - data/spec/shared/mailbox_examples.rb +1 -1
 - data/spec/shared/stack_examples.rb +87 -0
 - data/spec/shared/task_examples.rb +2 -3
 - data/spec/spec_helper.rb +2 -4
 - data/spec/support/configure_rspec.rb +2 -3
 - data/spec/support/coverage.rb +2 -4
 - data/spec/support/crash_checking.rb +2 -2
 - data/spec/support/examples/actor_class.rb +3 -8
 - data/spec/support/examples/call_class.rb +2 -2
 - data/spec/support/examples/container_class.rb +35 -0
 - data/spec/support/examples/evented_mailbox_class.rb +1 -2
 - data/spec/support/examples/stack_classes.rb +58 -0
 - data/spec/support/examples/stack_methods.rb +23 -0
 - data/spec/support/examples/subordinate_class.rb +19 -0
 - data/spec/support/logging.rb +2 -34
 - data/spec/support/loose_threads.rb +3 -16
 - data/spec/support/reset_class_variables.rb +5 -1
 - data/spec/support/stubbing.rb +1 -1
 - metadata +91 -323
 - data/culture/CONDUCT.md +0 -38
 - data/culture/GSoC/1010-why_we_will_participate.md +0 -17
 - data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
 - data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
 - data/culture/GSoC/1040-getting_students_involved.md +0 -5
 - data/culture/GSoC/1050-student_involvement_after.md +0 -5
 - data/culture/GSoC/README.md +0 -16
 - data/culture/Gemfile +0 -9
 - data/culture/LICENSE.txt +0 -22
 - data/culture/README.md +0 -22
 - data/culture/Rakefile +0 -5
 - data/culture/SYNC.md +0 -70
 - data/culture/celluloid-culture.gemspec +0 -18
 - data/culture/gems/README.md +0 -39
 - data/culture/gems/dependencies.yml +0 -93
 - data/culture/gems/loader.rb +0 -101
 - data/culture/rubocop/README.md +0 -38
 - data/culture/rubocop/lint.yml +0 -8
 - data/culture/rubocop/metrics.yml +0 -15
 - data/culture/rubocop/perf.yml +0 -0
 - data/culture/rubocop/rubocop.yml +0 -5
 - data/culture/rubocop/style.yml +0 -61
 - data/culture/spec/gems_spec.rb +0 -2
 - data/culture/spec/spec_helper.rb +0 -0
 - data/culture/spec/sync_spec.rb +0 -2
 - data/culture/sync.rb +0 -56
 - data/culture/tasks/rspec.rake +0 -5
 - data/culture/tasks/rubocop.rake +0 -2
 - data/lib/celluloid/actor/manager.rb +0 -7
 - data/lib/celluloid/backported.rb +0 -2
 - data/lib/celluloid/current.rb +0 -2
 - data/lib/celluloid/deprecate.rb +0 -34
 - data/lib/celluloid/fiber.rb +0 -32
 - data/lib/celluloid/managed.rb +0 -3
 - data/lib/celluloid/notices.rb +0 -15
 - data/spec/deprecate/actor_system_spec.rb +0 -72
 - data/spec/deprecate/block_spec.rb +0 -52
 - data/spec/deprecate/calls_spec.rb +0 -39
 - data/spec/deprecate/evented_mailbox_spec.rb +0 -34
 - data/spec/deprecate/future_spec.rb +0 -32
 - data/spec/deprecate/internal_pool_spec.rb +0 -4
 - data/spec/support/env.rb +0 -21
 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "logger"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Celluloid
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Subscribes to log incident topics to report on them.
         
     | 
| 
      
 5 
     | 
    
         
            +
              class IncidentReporter
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Celluloid
         
     | 
| 
      
 7 
     | 
    
         
            +
                include Celluloid::Notifications
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # get the time from the event
         
     | 
| 
      
 10 
     | 
    
         
            +
                class Formatter < ::Logger::Formatter
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def call(severity, _time, progname, msg)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    super(severity, msg.time, progname, msg.message)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def initialize(*args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  subscribe(/log\.incident/, :report)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @logger = ::Logger.new(*args)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @logger.formatter = Formatter.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @silenced = false
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def report(_topic, incident)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  return if @silenced
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  header = "INCIDENT"
         
     | 
| 
      
 27 
     | 
    
         
            +
                  header << " AT #{incident.triggering_event.time}" if incident.triggering_event
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @logger << header
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @logger << "\n"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @logger << "====================\n"
         
     | 
| 
      
 31 
     | 
    
         
            +
                  incident.events.each do |event|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @logger.add(event.severity, event, event.progname)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @logger << "====================\n"
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def silence
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @silenced = true
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def unsilence
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @silenced = false
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def silenced?
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @silenced
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Celluloid
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Wraps a single log event.
         
     | 
| 
      
 3 
     | 
    
         
            +
              class LogEvent
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_accessor :id, :severity, :message, :progname, :time
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(severity, message, progname, time = Time.now, &_block)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # This id should be ordered. For now relies on Celluloid::UUID to be ordered.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # May want to use a generation/counter strategy for independence of uuid.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @id = Internals::UUID.generate
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @severity = severity
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @message = block_given? ? yield : message
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @progname = progname
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @time = time
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def <=>(other)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @id <=> other.id
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Celluloid
         
     | 
| 
      
 2 
     | 
    
         
            +
              class RingBuffer
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(size)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @size = size
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @start = 0
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @count = 0
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @buffer = Array.new(size)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @mutex = Mutex.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def full?
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @count == @size
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def empty?
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @count == 0
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def push(value)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 21 
     | 
    
         
            +
                    stop = (@start + @count) % @size
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @buffer[stop] = value
         
     | 
| 
      
 23 
     | 
    
         
            +
                    if full?
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @start = (@start + 1) % @size
         
     | 
| 
      
 25 
     | 
    
         
            +
                    else
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @count += 1
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                    value
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
                alias << push
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def shift
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 35 
     | 
    
         
            +
                    remove_element
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def flush
         
     | 
| 
      
 40 
     | 
    
         
            +
                  values = []
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    values << remove_element until empty?
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  values
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def clear
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @buffer = Array.new(@size)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @start = 0
         
     | 
| 
      
 50 
     | 
    
         
            +
                  @count = 0
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                private
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def remove_element
         
     | 
| 
      
 56 
     | 
    
         
            +
                  return nil if empty?
         
     | 
| 
      
 57 
     | 
    
         
            +
                  value = @buffer[@start]
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @buffer[@start] = nil
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @start = (@start + 1) % @size
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @count -= 1
         
     | 
| 
      
 61 
     | 
    
         
            +
                  value
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/celluloid/mailbox.rb
    CHANGED
    
    | 
         @@ -1,5 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "thread"
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            module Celluloid
         
     | 
| 
       4 
2 
     | 
    
         
             
              class MailboxDead < Celluloid::Error; end # you can't receive from the dead
         
     | 
| 
       5 
3 
     | 
    
         
             
              class MailboxShutdown < Celluloid::Error; end # raised if the mailbox can no longer be used
         
     | 
| 
         @@ -41,7 +39,11 @@ module Celluloid 
     | 
|
| 
       41 
39 
     | 
    
         
             
                    @condition.signal
         
     | 
| 
       42 
40 
     | 
    
         
             
                    nil
         
     | 
| 
       43 
41 
     | 
    
         
             
                  ensure
         
     | 
| 
       44 
     | 
    
         
            -
                     
     | 
| 
      
 42 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 43 
     | 
    
         
            +
                      @mutex.unlock
         
     | 
| 
      
 44 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 45 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
       45 
47 
     | 
    
         
             
                  end
         
     | 
| 
       46 
48 
     | 
    
         
             
                end
         
     | 
| 
       47 
49 
     | 
    
         | 
| 
         @@ -52,7 +54,7 @@ module Celluloid 
     | 
|
| 
       52 
54 
     | 
    
         | 
| 
       53 
55 
     | 
    
         
             
                  @mutex.lock
         
     | 
| 
       54 
56 
     | 
    
         
             
                  begin
         
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
      
 57 
     | 
    
         
            +
                    raise MailboxDead, "attempted to receive from a dead mailbox" if @dead
         
     | 
| 
       56 
58 
     | 
    
         | 
| 
       57 
59 
     | 
    
         
             
                    message = nil
         
     | 
| 
       58 
60 
     | 
    
         
             
                    Timers::Wait.for(timeout) do |remaining|
         
     | 
| 
         @@ -63,7 +65,11 @@ module Celluloid 
     | 
|
| 
       63 
65 
     | 
    
         
             
                      @condition.wait(@mutex, remaining)
         
     | 
| 
       64 
66 
     | 
    
         
             
                    end
         
     | 
| 
       65 
67 
     | 
    
         
             
                  ensure
         
     | 
| 
       66 
     | 
    
         
            -
                     
     | 
| 
      
 68 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 69 
     | 
    
         
            +
                      @mutex.unlock
         
     | 
| 
      
 70 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 71 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 72 
     | 
    
         
            +
                    end
         
     | 
| 
       67 
73 
     | 
    
         
             
                  end
         
     | 
| 
       68 
74 
     | 
    
         | 
| 
       69 
75 
     | 
    
         
             
                  message
         
     | 
| 
         @@ -73,17 +79,17 @@ module Celluloid 
     | 
|
| 
       73 
79 
     | 
    
         
             
                # timeout is exceeded, raise a TaskTimeout.
         
     | 
| 
       74 
80 
     | 
    
         
             
                def receive(timeout = nil, &block)
         
     | 
| 
       75 
81 
     | 
    
         
             
                  message = nil
         
     | 
| 
       76 
     | 
    
         
            -
                  Timers::Wait.for(timeout) do | 
     | 
| 
      
 82 
     | 
    
         
            +
                  Timers::Wait.for(timeout) do |_remaining|
         
     | 
| 
       77 
83 
     | 
    
         
             
                    message = check(timeout, &block)
         
     | 
| 
       78 
84 
     | 
    
         
             
                    break if message
         
     | 
| 
       79 
85 
     | 
    
         
             
                  end
         
     | 
| 
       80 
86 
     | 
    
         
             
                  return message if message
         
     | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
      
 87 
     | 
    
         
            +
                  raise TaskTimeout, "receive timeout exceeded"
         
     | 
| 
       82 
88 
     | 
    
         
             
                end
         
     | 
| 
       83 
89 
     | 
    
         | 
| 
       84 
90 
     | 
    
         
             
                # Shut down this mailbox and clean up its contents
         
     | 
| 
       85 
91 
     | 
    
         
             
                def shutdown
         
     | 
| 
       86 
     | 
    
         
            -
                   
     | 
| 
      
 92 
     | 
    
         
            +
                  raise MailboxDead, "mailbox already shutdown" if @dead
         
     | 
| 
       87 
93 
     | 
    
         | 
| 
       88 
94 
     | 
    
         
             
                  @mutex.lock
         
     | 
| 
       89 
95 
     | 
    
         
             
                  begin
         
     | 
| 
         @@ -92,7 +98,11 @@ module Celluloid 
     | 
|
| 
       92 
98 
     | 
    
         
             
                    @messages = []
         
     | 
| 
       93 
99 
     | 
    
         
             
                    @dead = true
         
     | 
| 
       94 
100 
     | 
    
         
             
                  ensure
         
     | 
| 
       95 
     | 
    
         
            -
                     
     | 
| 
      
 101 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 102 
     | 
    
         
            +
                      @mutex.unlock
         
     | 
| 
      
 103 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 104 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
       96 
106 
     | 
    
         
             
                  end
         
     | 
| 
       97 
107 
     | 
    
         | 
| 
       98 
108 
     | 
    
         
             
                  messages.each do |msg|
         
     | 
| 
         @@ -147,7 +157,10 @@ module Celluloid 
     | 
|
| 
       147 
157 
     | 
    
         
             
                end
         
     | 
| 
       148 
158 
     | 
    
         | 
| 
       149 
159 
     | 
    
         
             
                def dead_letter(message)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
         
     | 
| 
      
 161 
     | 
    
         
            +
                  # rubocop:disable Style/GlobalVars
         
     | 
| 
       150 
162 
     | 
    
         
             
                  Internals::Logger.debug "Discarded message (mailbox is dead): #{message}" if $CELLULOID_DEBUG
         
     | 
| 
      
 163 
     | 
    
         
            +
                  # rubocop:enable Style/GlobalVars
         
     | 
| 
       151 
164 
     | 
    
         
             
                end
         
     | 
| 
       152 
165 
     | 
    
         | 
| 
       153 
166 
     | 
    
         
             
                def mailbox_full
         
     | 
| 
         @@ -26,13 +26,17 @@ module Celluloid 
     | 
|
| 
       26 
26 
     | 
    
         
             
                        @messages << message
         
     | 
| 
       27 
27 
     | 
    
         
             
                      end
         
     | 
| 
       28 
28 
     | 
    
         
             
                    ensure
         
     | 
| 
       29 
     | 
    
         
            -
                       
     | 
| 
      
 29 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 30 
     | 
    
         
            +
                        @mutex.unlock
         
     | 
| 
      
 31 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 32 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
       30 
34 
     | 
    
         
             
                    end
         
     | 
| 
       31 
35 
     | 
    
         
             
                    begin
         
     | 
| 
       32 
36 
     | 
    
         
             
                      current_actor = Thread.current[:celluloid_actor]
         
     | 
| 
       33 
37 
     | 
    
         
             
                      @reactor.wakeup unless current_actor && current_actor.mailbox == self
         
     | 
| 
       34 
     | 
    
         
            -
                    rescue
         
     | 
| 
       35 
     | 
    
         
            -
                      Internals::Logger.crash "reactor crashed",  
     | 
| 
      
 38 
     | 
    
         
            +
                    rescue => ex
         
     | 
| 
      
 39 
     | 
    
         
            +
                      Internals::Logger.crash "reactor crashed", ex
         
     | 
| 
       36 
40 
     | 
    
         
             
                      dead_letter(message)
         
     | 
| 
       37 
41 
     | 
    
         
             
                    end
         
     | 
| 
       38 
42 
     | 
    
         
             
                    nil
         
     | 
| 
         @@ -50,7 +54,7 @@ module Celluloid 
     | 
|
| 
       50 
54 
     | 
    
         
             
                    @reactor.run_once(timeout)
         
     | 
| 
       51 
55 
     | 
    
         | 
| 
       52 
56 
     | 
    
         
             
                    # No message was received:
         
     | 
| 
       53 
     | 
    
         
            -
                     
     | 
| 
      
 57 
     | 
    
         
            +
                    nil
         
     | 
| 
       54 
58 
     | 
    
         
             
                  end
         
     | 
| 
       55 
59 
     | 
    
         | 
| 
       56 
60 
     | 
    
         
             
                  # Obtain the next message from the mailbox that matches the given block
         
     | 
| 
         @@ -59,7 +63,11 @@ module Celluloid 
     | 
|
| 
       59 
63 
     | 
    
         
             
                    begin
         
     | 
| 
       60 
64 
     | 
    
         
             
                      super(&block)
         
     | 
| 
       61 
65 
     | 
    
         
             
                    ensure
         
     | 
| 
       62 
     | 
    
         
            -
                       
     | 
| 
      
 66 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 67 
     | 
    
         
            +
                        @mutex.unlock
         
     | 
| 
      
 68 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 69 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
       63 
71 
     | 
    
         
             
                    end
         
     | 
| 
       64 
72 
     | 
    
         
             
                  end
         
     | 
| 
       65 
73 
     | 
    
         | 
| 
         @@ -0,0 +1,95 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Celluloid
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Notifications
         
     | 
| 
      
 3 
     | 
    
         
            +
                def self.notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                  Actor[:notifications_fanout] || raise(DeadActorError, "notifications fanout actor not running")
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def publish(pattern, *args)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  Celluloid::Notifications.notifier.publish(pattern, *args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                rescue DeadActorError
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Bad shutdown logic. Oh well....
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # TODO: needs a tests
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                module_function :publish
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def subscribe(pattern, method)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Celluloid::Notifications.notifier.subscribe(Actor.current, pattern, method)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def unsubscribe(*args)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  Celluloid::Notifications.notifier.unsubscribe(*args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                class Fanout
         
     | 
| 
      
 25 
     | 
    
         
            +
                  include Celluloid
         
     | 
| 
      
 26 
     | 
    
         
            +
                  trap_exit :prune
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 29 
     | 
    
         
            +
                    @subscribers = []
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @listeners_for = {}
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def subscribe(actor, pattern, method)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    subscriber = Subscriber.new(actor, pattern, method).tap do |s|
         
     | 
| 
      
 35 
     | 
    
         
            +
                      @subscribers << s
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    link actor
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @listeners_for.clear
         
     | 
| 
      
 39 
     | 
    
         
            +
                    subscriber
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def unsubscribe(subscriber)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @subscribers.reject! { |s| s.matches?(subscriber) }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @listeners_for.clear
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def publish(pattern, *args)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    listeners_for(pattern).each { |s| s.publish(pattern, *args) }
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def listeners_for(pattern)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @listeners_for[pattern] ||= @subscribers.select { |s| s.subscribed_to?(pattern) }
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def listening?(pattern)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    listeners_for(pattern).any?
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def prune(actor, _reason = nil)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @subscribers.reject! { |s| s.actor == actor }
         
     | 
| 
      
 61 
     | 
    
         
            +
                    @listeners_for.clear
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                class Subscriber
         
     | 
| 
      
 66 
     | 
    
         
            +
                  attr_accessor :actor, :pattern, :method
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  def initialize(actor, pattern, method)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    @actor = actor
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @pattern = pattern
         
     | 
| 
      
 71 
     | 
    
         
            +
                    @method = method
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def publish(pattern, *args)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    actor.async method, pattern, *args
         
     | 
| 
      
 76 
     | 
    
         
            +
                  rescue DeadActorError
         
     | 
| 
      
 77 
     | 
    
         
            +
                    # TODO: needs a tests
         
     | 
| 
      
 78 
     | 
    
         
            +
                    # Bad shutdown logic. Oh well....
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  def subscribed_to?(pattern)
         
     | 
| 
      
 82 
     | 
    
         
            +
                    !pattern || @pattern === pattern.to_s || @pattern === pattern
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  def matches?(subscriber_or_pattern)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    self === subscriber_or_pattern ||
         
     | 
| 
      
 87 
     | 
    
         
            +
                      @pattern && @pattern === subscriber_or_pattern
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              def self.publish(*args)
         
     | 
| 
      
 93 
     | 
    
         
            +
                Notifications.publish(*args)
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "celluloid"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
         
     | 
| 
      
 4 
     | 
    
         
            +
            # rubocop:disable Style/GlobalVars
         
     | 
| 
      
 5 
     | 
    
         
            +
            $CELLULOID_MONITORING = true
         
     | 
| 
      
 6 
     | 
    
         
            +
            # rubocop:enable Style/GlobalVars
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module Celluloid
         
     | 
| 
      
 9 
     | 
    
         
            +
              class Probe
         
     | 
| 
      
 10 
     | 
    
         
            +
                include Celluloid
         
     | 
| 
      
 11 
     | 
    
         
            +
                include Celluloid::Notifications
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                NOTIFICATIONS_TOPIC_BASE = "celluloid.events.%s".freeze
         
     | 
| 
      
 14 
     | 
    
         
            +
                EVENTS_BUFFER = Queue.new
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 18 
     | 
    
         
            +
                    # spawn the actor if not found
         
     | 
| 
      
 19 
     | 
    
         
            +
                    supervise_as(:probe_actor) unless Actor[:probe_actor] && Actor[:probe_actor].alive?
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def run_without_supervision
         
     | 
| 
      
 23 
     | 
    
         
            +
                    Actor[:probe_actor] = Celluloid::Probe.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def actor_created(actor)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    trigger_event(:actor_created, actor)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def actor_named(actor)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    trigger_event(:actor_named, actor)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def actor_died(actor)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    trigger_event(:actor_died, actor)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def actors_linked(a, b)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    a = find_actor(a)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    b = find_actor(b)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    trigger_event(:actors_linked, a, b)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  private
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def trigger_event(name, *args)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
         
     | 
| 
      
 48 
     | 
    
         
            +
                    # rubocop:disable Style/GlobalVars
         
     | 
| 
      
 49 
     | 
    
         
            +
                    return unless $CELLULOID_MONITORING
         
     | 
| 
      
 50 
     | 
    
         
            +
                    # rubocop:enable Style/GlobalVars
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    EVENTS_BUFFER << [name, args]
         
     | 
| 
      
 53 
     | 
    
         
            +
                    probe_actor = Actor[:probe_actor]
         
     | 
| 
      
 54 
     | 
    
         
            +
                    probe_actor.async.process_queue if probe_actor
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def find_actor(obj)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    if obj.__send__(:class) == Actor
         
     | 
| 
      
 59 
     | 
    
         
            +
                      obj
         
     | 
| 
      
 60 
     | 
    
         
            +
                    elsif owner = obj.instance_variable_get(OWNER_IVAR)
         
     | 
| 
      
 61 
     | 
    
         
            +
                      owner
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 67 
     | 
    
         
            +
                  async.process_queue
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def process_queue
         
     | 
| 
      
 71 
     | 
    
         
            +
                  until EVENTS_BUFFER.empty?
         
     | 
| 
      
 72 
     | 
    
         
            +
                    event = EVENTS_BUFFER.pop
         
     | 
| 
      
 73 
     | 
    
         
            +
                    dispatch_event(*event)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                def dispatch_event(cmd, args)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  publish(NOTIFICATIONS_TOPIC_BASE % cmd, args)
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     |