celluloid 0.18.0.pre → 0.18.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.
- checksums.yaml +5 -5
- data/CHANGES.md +114 -39
- data/CONDUCT.md +13 -0
- data/CONTRIBUTING.md +39 -0
- data/README.md +59 -55
- 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 +1 -1
- 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/backported.rb +6 -2
- 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/current.rb +3 -1
- 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/managed.rb +6 -3
- 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/{culture/rubocop/perf.yml → lib/celluloid/supervision/container/tree.rb} +0 -0
- data/lib/celluloid/supervision/deprecate.rb +9 -0
- data/lib/celluloid/supervision/deprecate/supervise.rb +105 -0
- data/lib/celluloid/supervision/deprecate/validation.rb +54 -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 -316
- 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/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/deprecate.rb +0 -34
- data/lib/celluloid/fiber.rb +0 -32
- 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,40 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
module Internals
|
5
|
+
# Clearly Ruby doesn't have enough UUID libraries
|
6
|
+
# This one aims to be fast and simple with good support for multiple threads
|
7
|
+
# If there's a better UUID library I can use with similar multithreaded
|
8
|
+
# performance, I certainly wouldn't mind using a gem for this!
|
9
|
+
module UUID
|
10
|
+
values = SecureRandom.hex(9).match(/(.{8})(.{4})(.{3})(.{3})/)
|
11
|
+
PREFIX = "#{values[1]}-#{values[2]}-4#{values[3]}-8#{values[4]}".freeze
|
12
|
+
BLOCK_SIZE = 0x10000
|
13
|
+
|
14
|
+
@counter = 0
|
15
|
+
@counter_mutex = Mutex.new
|
16
|
+
|
17
|
+
def self.generate
|
18
|
+
thread = Thread.current
|
19
|
+
|
20
|
+
unless thread.uuid_limit
|
21
|
+
@counter_mutex.synchronize do
|
22
|
+
block_base = @counter
|
23
|
+
@counter += BLOCK_SIZE
|
24
|
+
thread.uuid_counter = block_base
|
25
|
+
thread.uuid_limit = @counter - 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
counter = thread.uuid_counter
|
30
|
+
if thread.uuid_counter >= thread.uuid_limit
|
31
|
+
thread.uuid_counter = thread.uuid_limit = nil
|
32
|
+
else
|
33
|
+
thread.uuid_counter += 1
|
34
|
+
end
|
35
|
+
|
36
|
+
"#{PREFIX}-#{format('%012x', counter)}".freeze
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Celluloid
|
2
|
+
# Wraps all events and context for a single incident.
|
3
|
+
class Incident
|
4
|
+
attr_accessor :pid
|
5
|
+
attr_accessor :events, :triggering_event
|
6
|
+
|
7
|
+
def initialize(events, triggering_event = nil)
|
8
|
+
@events = events
|
9
|
+
@triggering_event = triggering_event
|
10
|
+
@pid = $PROCESS_ID
|
11
|
+
end
|
12
|
+
|
13
|
+
# Merge two incidents together. This may be useful if two incidents occur at the same time.
|
14
|
+
def merge(*other_incidents)
|
15
|
+
merged_events = other_incidents.flatten.inject(events) do |events, incident|
|
16
|
+
events += incident.events
|
17
|
+
end
|
18
|
+
Incident.new(merged_events.sort, triggering_event)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
# A logger that holds all messages in circular buffers, then flushes the buffers
|
5
|
+
# when an event occurs at a configurable severity threshold.
|
6
|
+
#
|
7
|
+
# Unlike ruby's Logger, this class only supports a single progname.
|
8
|
+
class IncidentLogger
|
9
|
+
module Severity
|
10
|
+
include ::Logger::Severity
|
11
|
+
|
12
|
+
TRACE = -1
|
13
|
+
|
14
|
+
def severity_to_string(severity)
|
15
|
+
case severity
|
16
|
+
when TRACE then "TRACE"
|
17
|
+
when DEBUG then "DEBUG"
|
18
|
+
when INFO then "INFO"
|
19
|
+
when WARN then "WARN"
|
20
|
+
when ERROR then "ERROR"
|
21
|
+
when FATAL then "FATAL"
|
22
|
+
when UNKNOWN then "UNKNOWN"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
include Severity
|
27
|
+
|
28
|
+
# The progname (facility) for this instance.
|
29
|
+
attr_accessor :progname
|
30
|
+
|
31
|
+
# The logging level. Messages below this severity will not be logged at all.
|
32
|
+
attr_accessor :level
|
33
|
+
|
34
|
+
# The incident threshold. Messages at or above this severity will generate an
|
35
|
+
# incident and be published to incident reporters.
|
36
|
+
attr_accessor :threshold
|
37
|
+
|
38
|
+
# The buffer size limit. Each log level will retain this number of messages
|
39
|
+
# at maximum.
|
40
|
+
attr_accessor :sizelimit
|
41
|
+
|
42
|
+
attr_accessor :buffers
|
43
|
+
|
44
|
+
# Create a new IncidentLogger.
|
45
|
+
def initialize(progname = nil, options = {})
|
46
|
+
@progname = progname || "default"
|
47
|
+
@level = options[:level] || DEBUG
|
48
|
+
@threshold = options[:threshold] || ERROR
|
49
|
+
@sizelimit = options[:sizelimit] || 100
|
50
|
+
|
51
|
+
@buffer_mutex = Mutex.new
|
52
|
+
@buffers = Hash.new do |progname_hash, pn|
|
53
|
+
@buffer_mutex.synchronize do
|
54
|
+
progname_hash[pn] = Hash.new do |severity_hash, severity|
|
55
|
+
severity_hash[severity] = RingBuffer.new(@sizelimit)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# When the IncidentLogger itself encounters an error, it falls back to logging to stderr
|
61
|
+
@fallback_logger = ::Logger.new(STDERR)
|
62
|
+
@fallback_logger.progname = "FALLBACK"
|
63
|
+
end
|
64
|
+
|
65
|
+
# add an event.
|
66
|
+
def add(severity, message = nil, progname = nil, &block)
|
67
|
+
progname ||= @progname
|
68
|
+
severity ||= UNKNOWN
|
69
|
+
|
70
|
+
return event.id if severity < @level
|
71
|
+
|
72
|
+
if message.nil? && !block_given?
|
73
|
+
message = progname
|
74
|
+
progname = @progname
|
75
|
+
end
|
76
|
+
|
77
|
+
event = LogEvent.new(severity, message, progname, &block)
|
78
|
+
|
79
|
+
@buffers[progname][severity] << event
|
80
|
+
|
81
|
+
if severity >= @threshold
|
82
|
+
begin
|
83
|
+
Celluloid::Notifications.notifier.async.publish(incident_topic, create_incident(event))
|
84
|
+
rescue => ex
|
85
|
+
@fallback_logger.error(ex)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
event.id
|
89
|
+
end
|
90
|
+
alias log add
|
91
|
+
|
92
|
+
# See docs for Logger#info
|
93
|
+
def trace(progname = nil, &block)
|
94
|
+
add(TRACE, nil, progname, &block)
|
95
|
+
end
|
96
|
+
|
97
|
+
def debug(progname = nil, &block)
|
98
|
+
add(DEBUG, nil, progname, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
def info(progname = nil, &block)
|
102
|
+
add(INFO, nil, progname, &block)
|
103
|
+
end
|
104
|
+
|
105
|
+
def warn(progname = nil, &block)
|
106
|
+
add(WARN, nil, progname, &block)
|
107
|
+
end
|
108
|
+
|
109
|
+
def error(progname = nil, &block)
|
110
|
+
add(ERROR, nil, progname, &block)
|
111
|
+
end
|
112
|
+
|
113
|
+
def fatal(progname = nil, &block)
|
114
|
+
add(FATAL, nil, progname, &block)
|
115
|
+
end
|
116
|
+
|
117
|
+
def unknown(progname = nil, &block)
|
118
|
+
add(UNKNOWN, nil, progname, &block)
|
119
|
+
end
|
120
|
+
|
121
|
+
def flush
|
122
|
+
messages = []
|
123
|
+
@buffer_mutex.synchronize do
|
124
|
+
@buffers.each do |_progname, severities|
|
125
|
+
severities.each do |_severity, buffer|
|
126
|
+
messages += buffer.flush
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
messages.sort
|
131
|
+
end
|
132
|
+
|
133
|
+
def clear
|
134
|
+
@buffer_mutex.synchronize do
|
135
|
+
@buffers.each(&:clear)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def create_incident(event = nil)
|
140
|
+
Incident.new(flush, event)
|
141
|
+
end
|
142
|
+
|
143
|
+
def incident_topic
|
144
|
+
"log.incident.#{@progname}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -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
|
|