Class: SolidObjects::Actor
- Inherits:
-
Object
- Object
- SolidObjects::Actor
show all
- Defined in:
- lib/solid_objects/actor.rb,
sig/generated/lib/solid_objects/actor.rbs
Defined Under Namespace
Classes: EffectIntent, OutboundMessageIntent, ReminderIntent
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#activate ⇒ void
-
#current_message ⇒ MessageContext?
-
#deactivate ⇒ void
-
#discard_intents ⇒ void
-
#drain_effect_intents ⇒ Array[EffectIntent]
-
#drain_outbound_message_intents ⇒ Array[OutboundMessageIntent]
-
#drain_reminder_intents ⇒ Array[ReminderIntent]
-
#emit(name, on_success: nil, on_failure: nil, **arguments) ⇒ nil
-
#initialize(actor_id:, state:) ⇒ Actor
constructor
-
#invoke(message_name, arguments) ⇒ Object
-
#keyword_arguments(arguments) ⇒ Hash[Symbol, untyped]
-
#observable_values ⇒ Hash[String, untyped]
-
#reject(code, message, details: {}) ⇒ bot
-
#schedule(name, at:, every: nil, missed: :latest, arguments: {}) ⇒ nil
-
#send_to(reference, message_name, available_at: nil, idempotency_key: nil, **arguments) ⇒ nil
-
#stage_outbound_message(reference, message_name, arguments, available_at: nil, idempotency_key: nil) ⇒ OutboundMessageIntent
-
#validate_effect_callback!(message_name) ⇒ void
Constructor Details
#initialize(actor_id:, state:) ⇒ Actor
Returns a new instance of Actor.
140
141
142
143
144
145
146
|
# File 'lib/solid_objects/actor.rb', line 140
def initialize(actor_id:, state:)
@actor_id = actor_id
@state = state
@effect_intents = []
@reminder_intents = []
@outbound_message_intents = []
end
|
Instance Attribute Details
#actor_id ⇒ Object
137
138
139
|
# File 'lib/solid_objects/actor.rb', line 137
def actor_id
@actor_id
end
|
#effect_intents ⇒ Object
Returns the value of attribute effect_intents.
269
270
271
|
# File 'lib/solid_objects/actor.rb', line 269
def effect_intents
@effect_intents
end
|
#outbound_message_intents ⇒ Object
Returns the value of attribute outbound_message_intents.
269
270
271
|
# File 'lib/solid_objects/actor.rb', line 269
def outbound_message_intents
@outbound_message_intents
end
|
#reminder_intents ⇒ Object
Returns the value of attribute reminder_intents.
269
270
271
|
# File 'lib/solid_objects/actor.rb', line 269
def reminder_intents
@reminder_intents
end
|
#state ⇒ Object
137
138
139
|
# File 'lib/solid_objects/actor.rb', line 137
def state
@state
end
|
Class Method Details
.actor_type(value = nil) ⇒ String
18
19
20
21
22
23
24
25
|
# File 'lib/solid_objects/actor.rb', line 18
def actor_type(value = nil)
if value
@actor_type = value.to_s
SolidObjects.register_actor(@actor_type, self)
end
@actor_type ||= default_actor_type
end
|
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# File 'lib/solid_objects/actor.rb', line 28
def attribute(name, default: nil)
attribute_name = name.to_sym
ensure_attribute_methods_available!(attribute_name)
attribute = definition.add_attribute(attribute_name, default:)
@defining_attribute_methods = true
begin
define_method(attribute_name) { state.fetch(attribute_name) }
define_method(:"#{attribute_name}=") { |value| state.write(attribute_name, value) }
generated_attribute_methods[attribute_name] = true
generated_attribute_methods[:"#{attribute_name}="] = true
ensure
@defining_attribute_methods = false
end
attribute
end
|
89
90
91
|
# File 'lib/solid_objects/actor.rb', line 89
def definition
(@definition ||= ActorDefinition.new).synchronize_instance_messages(self)
end
|
.ensure_registered! ⇒ Class
.inherited(subclass) ⇒ void
This method returns an undefined value.
11
12
13
14
15
|
# File 'lib/solid_objects/actor.rb', line 11
def inherited(subclass)
super
subclass.instance_variable_set(:@definition, definition.duplicate)
subclass.instance_variable_set(:@generated_attribute_methods, generated_attribute_methods.dup)
end
|
45
46
47
|
# File 'lib/solid_objects/actor.rb', line 45
def message(name, &block)
definition.add_message(name, block)
end
|
66
67
68
|
# File 'lib/solid_objects/actor.rb', line 66
def migrate_state(from:, to:, &block)
definition.add_state_migration(from, to, block)
end
|
.observable(name, &block) ⇒ void
This method returns an undefined value.
55
56
57
|
# File 'lib/solid_objects/actor.rb', line 55
def observable(name, &block)
definition.add_observable(name, block)
end
|
.on_activate { ... } ⇒ Proc
71
72
73
74
|
# File 'lib/solid_objects/actor.rb', line 71
def on_activate(&block)
definition.activation_hooks << block
block
end
|
.on_deactivate { ... } ⇒ Proc
77
78
79
80
|
# File 'lib/solid_objects/actor.rb', line 77
def on_deactivate(&block)
definition.deactivation_hooks << block
block
end
|
50
51
52
|
# File 'lib/solid_objects/actor.rb', line 50
def query(name, &block)
definition.add_query(name, block)
end
|
83
84
85
86
|
# File 'lib/solid_objects/actor.rb', line 83
def ref(actor_id)
ensure_registered!
Reference.new(actor_type:, actor_id: actor_id.to_s)
end
|
.state_version(version = nil) ⇒ Integer
60
61
62
63
|
# File 'lib/solid_objects/actor.rb', line 60
def state_version(version = nil)
definition.set_state_version(version) if version
definition.state_version
end
|
Instance Method Details
#activate ⇒ void
This method returns an undefined value.
224
225
226
|
# File 'lib/solid_objects/actor.rb', line 224
def activate
self.class.definition.activation_hooks.each { |hook| instance_exec(&hook) }
end
|
#deactivate ⇒ void
This method returns an undefined value.
229
230
231
|
# File 'lib/solid_objects/actor.rb', line 229
def deactivate
self.class.definition.deactivation_hooks.each { |hook| instance_exec(&hook) }
end
|
#discard_intents ⇒ void
This method returns an undefined value.
261
262
263
264
265
|
# File 'lib/solid_objects/actor.rb', line 261
def discard_intents
effect_intents.clear
reminder_intents.clear
outbound_message_intents.clear
end
|
#drain_effect_intents ⇒ Array[EffectIntent]
246
247
248
|
# File 'lib/solid_objects/actor.rb', line 246
def drain_effect_intents
effect_intents.shift(effect_intents.length)
end
|
256
257
258
|
# File 'lib/solid_objects/actor.rb', line 256
def drain_outbound_message_intents
outbound_message_intents.shift(outbound_message_intents.length)
end
|
#drain_reminder_intents ⇒ Array[ReminderIntent]
251
252
253
|
# File 'lib/solid_objects/actor.rb', line 251
def drain_reminder_intents
reminder_intents.shift(reminder_intents.length)
end
|
#emit(name, on_success: nil, on_failure: nil, **arguments) ⇒ nil
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/solid_objects/actor.rb', line 164
def emit(name, on_success: nil, on_failure: nil, **arguments)
validate_effect_callback!(on_success)
validate_effect_callback!(on_failure)
EffectIntent.new(
name: name.to_s,
arguments: Serialization.dump(arguments),
success_message_name: on_success&.to_s,
failure_message_name: on_failure&.to_s
).tap do |intent|
effect_intents << intent
end
nil
end
|
#invoke(message_name, arguments) ⇒ Object
208
209
210
211
212
213
214
|
# File 'lib/solid_objects/actor.rb', line 208
def invoke(message_name, arguments)
handler = self.class.definition.messages[message_name.to_sym] ||
self.class.definition.queries[message_name.to_sym]
raise UnknownMessage, "unknown message #{message_name.inspect} for #{self.class.actor_type}" unless handler
instance_exec(**keyword_arguments(arguments), &handler.block)
end
|
#keyword_arguments(arguments) ⇒ Hash[Symbol, untyped]
272
273
274
|
# File 'lib/solid_objects/actor.rb', line 272
def keyword_arguments(arguments)
arguments.each_with_object({}) { |(key, value), converted| converted[key.to_sym] = value }
end
|
#observable_values ⇒ Hash[String, untyped]
217
218
219
220
221
|
# File 'lib/solid_objects/actor.rb', line 217
def observable_values
self.class.definition.observables.each_with_object({}) do |(name, handler), values|
values[name.to_s] = Serialization.dump(instance_exec(&handler.block))
end
end
|
#reject(code, message, details: {}) ⇒ bot
154
155
156
157
158
159
160
161
|
# File 'lib/solid_objects/actor.rb', line 154
def reject(code, message, details: {})
rejection_code = code.to_s
unless rejection_code.match?(/\A[a-z][a-z0-9_]*\z/)
raise ArgumentError, "rejection code must contain lowercase letters, digits, and underscores"
end
raise Rejected.new(code: rejection_code, message:, details:)
end
|
#schedule(name, at:, every: nil, missed: :latest, arguments: {}) ⇒ nil
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
# File 'lib/solid_objects/actor.rb', line 179
def schedule(name, at:, every: nil, missed: :latest, arguments: {})
interval_seconds = every&.to_f
if interval_seconds && !interval_seconds.positive?
raise ArgumentError, "reminder interval must be positive"
end
missed_policy = missed.to_s
unless %w[all latest].include?(missed_policy)
raise ArgumentError, "missed reminder policy must be all or latest"
end
ReminderIntent.new(
name: name.to_s,
at:,
arguments: Serialization.dump(arguments),
interval_seconds:,
missed_policy:
).tap do |intent|
reminder_intents << intent
end
nil
end
|
#send_to(reference, message_name, available_at: nil, idempotency_key: nil, **arguments) ⇒ nil
202
203
204
205
|
# File 'lib/solid_objects/actor.rb', line 202
def send_to(reference, message_name, available_at: nil, idempotency_key: nil, **arguments)
stage_outbound_message(reference, message_name, arguments, available_at:, idempotency_key:)
nil
end
|
#stage_outbound_message(reference, message_name, arguments, available_at: nil, idempotency_key: nil) ⇒ OutboundMessageIntent
234
235
236
237
238
239
240
241
242
243
|
# File 'lib/solid_objects/actor.rb', line 234
def stage_outbound_message(reference, message_name, arguments, available_at: nil, idempotency_key: nil)
OutboundMessageIntent.new(
actor_type: reference.actor_type,
actor_id: reference.actor_id,
message_name: message_name.to_s,
arguments: Serialization.dump(arguments),
available_at:,
idempotency_key:
).tap { |intent| outbound_message_intents << intent }
end
|
#validate_effect_callback!(message_name) ⇒ void
This method returns an undefined value.
277
278
279
280
281
282
|
# File 'lib/solid_objects/actor.rb', line 277
def validate_effect_callback!(message_name)
return unless message_name
return if self.class.definition.messages.key?(message_name.to_sym)
raise UnknownMessage, "unknown effect callback message #{message_name.inspect}"
end
|