solid_objects 0.16.1 → 0.17.1
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 +4 -4
- data/CHANGELOG.md +100 -0
- data/README.md +9 -0
- data/Rakefile +5 -0
- data/app/models/solid_objects/message.rb +15 -0
- data/docs/agents.md +253 -0
- data/docs/architecture.md +16 -6
- data/docs/authorization.md +10 -3
- data/docs/observability.md +186 -0
- data/docs/operations.md +10 -8
- data/docs/realtime.md +4 -3
- data/docs/reminders.md +3 -1
- data/docs/roadmap.md +17 -1
- data/docs/security.md +2 -2
- data/docs/transmission.md +17 -6
- data/docs/virtual-actors.md +226 -0
- data/examples/quickstart/README.md +246 -0
- data/examples/quickstart/app/actors/ticket_sale.rb +22 -0
- data/examples/quickstart/smoke.rb +421 -0
- data/lib/solid_objects/activation.rb +6 -3
- data/lib/solid_objects/actor.rb +29 -2
- data/lib/solid_objects/actor_channel.rb +9 -1
- data/lib/solid_objects/actor_snapshot.rb +14 -8
- data/lib/solid_objects/broadcast_executor.rb +1 -0
- data/lib/solid_objects/client.rb +15 -1
- data/lib/solid_objects/configuration.rb +4 -0
- data/lib/solid_objects/database_adapters/sqlite.rb +7 -1
- data/lib/solid_objects/diagnostics.rb +83 -0
- data/lib/solid_objects/effect_executor.rb +4 -0
- data/lib/solid_objects/errors.rb +3 -0
- data/lib/solid_objects/executor.rb +34 -16
- data/lib/solid_objects/instrumentation.rb +22 -1
- data/lib/solid_objects/log_subscriber.rb +1 -1
- data/lib/solid_objects/mailbox.rb +5 -1
- data/lib/solid_objects/message_reference.rb +9 -9
- data/lib/solid_objects/observer_registry.rb +47 -0
- data/lib/solid_objects/payload_broadcast.rb +9 -8
- data/lib/solid_objects/reference.rb +19 -0
- data/lib/solid_objects/reminder_scheduler.rb +5 -0
- data/lib/solid_objects/state_snapshot.rb +1 -0
- data/lib/solid_objects/supervisor.rb +3 -6
- data/lib/solid_objects/synchronous_invocation.rb +1 -21
- data/lib/solid_objects/telemetry.rb +137 -0
- data/lib/solid_objects/version.rb +1 -1
- data/lib/solid_objects/wake_up_adapters/postgresql.rb +1 -2
- data/lib/solid_objects/wake_up_adapters/redis.rb +1 -2
- data/lib/solid_objects/worker.rb +1 -2
- data/lib/solid_objects.rb +10 -0
- data/sig/generated/lib/solid_objects/actor.rbs +9 -0
- data/sig/generated/lib/solid_objects/actor_channel.rbs +3 -0
- data/sig/generated/lib/solid_objects/actor_snapshot.rbs +7 -2
- data/sig/generated/lib/solid_objects/client.rbs +3 -0
- data/sig/generated/lib/solid_objects/configuration.rbs +7 -3
- data/sig/generated/lib/solid_objects/diagnostics.rbs +25 -0
- data/sig/generated/lib/solid_objects/errors.rbs +3 -0
- data/sig/generated/lib/solid_objects/executor.rbs +10 -2
- data/sig/generated/lib/solid_objects/message_reference.rbs +6 -6
- data/sig/generated/lib/solid_objects/observer_registry.rbs +29 -0
- data/sig/generated/lib/solid_objects/payload_broadcast.rbs +2 -4
- data/sig/generated/lib/solid_objects/reference.rbs +9 -0
- data/sig/generated/lib/solid_objects/synchronous_invocation.rbs +0 -3
- data/sig/generated/lib/solid_objects/telemetry.rbs +30 -0
- data/sig/generated/lib/solid_objects.rbs +3 -0
- data/sig/generated/models/solid_objects/message.rbs +3 -0
- data/sig/public/json_value.rbs +3 -0
- data/sig/public/telemetry.rbs +49 -0
- data/sig/support/framework.rbs +5 -0
- metadata +24 -9
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module SolidObjects
|
|
4
4
|
class PayloadBroadcast
|
|
5
|
-
MAXIMUM_PAYLOAD_BYTES = 1_048_576
|
|
6
5
|
REVISION_OBSERVABLE = "solid_objects.revision"
|
|
7
6
|
|
|
8
7
|
# @rbs @snapshot: ActorSnapshot
|
|
@@ -42,7 +41,7 @@ module SolidObjects
|
|
|
42
41
|
def rendered_payload(handler)
|
|
43
42
|
payload = Serialization.dump(
|
|
44
43
|
evaluated_payload(handler),
|
|
45
|
-
max_bytes:
|
|
44
|
+
max_bytes: SolidObjects.configuration.max_payload_bytes
|
|
46
45
|
)
|
|
47
46
|
return payload if payload.is_a?(Hash) || payload.is_a?(Array)
|
|
48
47
|
|
|
@@ -56,10 +55,12 @@ module SolidObjects
|
|
|
56
55
|
# unaffected.
|
|
57
56
|
# @rbs (ActorDefinition::Handler) -> untyped
|
|
58
57
|
def evaluated_payload(handler)
|
|
59
|
-
actor = snapshot.
|
|
60
|
-
actor.
|
|
58
|
+
actor = snapshot.build_actor
|
|
59
|
+
actor.read_projection("payload.#{name}") do
|
|
60
|
+
actor.instance_exec(actor, authorization_context, &handler.block)
|
|
61
|
+
end
|
|
61
62
|
rescue NameError => error
|
|
62
|
-
raise unless class_level_receiver?(error)
|
|
63
|
+
raise unless class_level_receiver?(error, actor)
|
|
63
64
|
|
|
64
65
|
raise InvalidPayloadBroadcast,
|
|
65
66
|
"payload broadcast #{name.inspect} called #{error.name.inspect} on the " \
|
|
@@ -70,9 +71,9 @@ module SolidObjects
|
|
|
70
71
|
# Distinguishes a block that relied on the old class-level receiver from an
|
|
71
72
|
# ordinary typo, so the one behaviour change reports itself instead of
|
|
72
73
|
# surfacing as an unexplained NameError.
|
|
73
|
-
# @rbs (NameError[
|
|
74
|
-
def class_level_receiver?(error)
|
|
75
|
-
error.receiver.equal?(
|
|
74
|
+
# @rbs (NameError[BasicObject], Actor?) -> bool
|
|
75
|
+
def class_level_receiver?(error, actor)
|
|
76
|
+
error.receiver.equal?(actor) &&
|
|
76
77
|
snapshot.actor_class.respond_to?(error.name)
|
|
77
78
|
rescue ArgumentError, NameError
|
|
78
79
|
false
|
|
@@ -16,6 +16,25 @@ module SolidObjects
|
|
|
16
16
|
freeze
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
# @rbs (?limit: Integer, ?authorization_context: untyped) -> actor_diagnostics
|
|
20
|
+
def diagnostics(limit: 100, authorization_context: nil)
|
|
21
|
+
Diagnostics.new(self).summary(limit:, authorization_context:)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @rbs (?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
25
|
+
def observe(authorization_context: nil, &block)
|
|
26
|
+
Diagnostics.new(self).observe(authorization_context:, &block)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @rbs (String, ?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
30
|
+
def on(name, authorization_context: nil, &block)
|
|
31
|
+
raise ArgumentError, "an actor observer requires a block" unless block
|
|
32
|
+
|
|
33
|
+
observe(authorization_context:) do |event|
|
|
34
|
+
block.call(event) if event.fetch("name") == "solid_objects.#{name}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
19
38
|
# @rbs (?available_at: Time?, ?idempotency_key: String?, ?authorization_context: untyped) -> OperationDispatcher
|
|
20
39
|
def async(available_at: nil, idempotency_key: nil, authorization_context: nil)
|
|
21
40
|
OperationDispatcher.new(
|
|
@@ -166,9 +166,14 @@ module SolidObjects
|
|
|
166
166
|
mailbox.announce(message)
|
|
167
167
|
SolidObjects.instrument(
|
|
168
168
|
:"reminder.enqueued",
|
|
169
|
+
instance_id: reminder.instance_id,
|
|
170
|
+
message_id: message.id,
|
|
171
|
+
attempt: message.attempt_count,
|
|
172
|
+
lateness_milliseconds: [ (((now || database_adapter.database_now) - reminder.next_run_at) * 1000).round, 0 ].max,
|
|
169
173
|
reminder_id: reminder.id,
|
|
170
174
|
actor_type: reminder.actor_type,
|
|
171
175
|
actor_id: reminder.actor_id,
|
|
176
|
+
operation: reminder.operation,
|
|
172
177
|
occurrence: reminder.occurrence
|
|
173
178
|
)
|
|
174
179
|
MessageReference.from_message(message)
|
|
@@ -10,6 +10,7 @@ module SolidObjects
|
|
|
10
10
|
actor_snapshot = ActorSnapshot.new(reference)
|
|
11
11
|
@actor_class = actor_snapshot.actor_class
|
|
12
12
|
@data = Serialization.readonly_copy(actor_snapshot.actor.state.to_h)
|
|
13
|
+
SolidObjects.instrument(:"snapshot.read", actor_type: reference.actor_type, actor_id: reference.actor_id, instance_id: actor_snapshot.instance_id.zero? ? nil : actor_snapshot.instance_id, revision: actor_snapshot.revision)
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
# @rbs () -> Hash[String, untyped]
|
|
@@ -97,8 +97,7 @@ module SolidObjects
|
|
|
97
97
|
rescue => error
|
|
98
98
|
SolidObjects.instrument(
|
|
99
99
|
:"supervisor.monitor_failed",
|
|
100
|
-
error_class: error.class.name
|
|
101
|
-
error_message: error.message
|
|
100
|
+
error_class: error.class.name
|
|
102
101
|
)
|
|
103
102
|
end
|
|
104
103
|
sleep SolidObjects.configuration.supervisor_monitor_interval
|
|
@@ -161,8 +160,7 @@ module SolidObjects
|
|
|
161
160
|
failures += 1
|
|
162
161
|
SolidObjects.instrument(
|
|
163
162
|
:"supervisor.retention_failed",
|
|
164
|
-
error_class: error.class.name
|
|
165
|
-
error_message: error.message
|
|
163
|
+
error_class: error.class.name
|
|
166
164
|
)
|
|
167
165
|
end
|
|
168
166
|
wait_for_next_retention(failures)
|
|
@@ -220,8 +218,7 @@ module SolidObjects
|
|
|
220
218
|
rescue => error
|
|
221
219
|
SolidObjects.instrument(
|
|
222
220
|
:"supervisor.redrive_failed",
|
|
223
|
-
error_class: error.class.name
|
|
224
|
-
error_message: error.message
|
|
221
|
+
error_class: error.class.name
|
|
225
222
|
)
|
|
226
223
|
false
|
|
227
224
|
end
|
|
@@ -78,27 +78,7 @@ module SolidObjects
|
|
|
78
78
|
|
|
79
79
|
# @rbs (Message) -> untyped
|
|
80
80
|
def completed_result(message)
|
|
81
|
-
|
|
82
|
-
if message.dead?
|
|
83
|
-
raise MessageFailed.new(
|
|
84
|
-
"actor message failed permanently",
|
|
85
|
-
message_id: message.id,
|
|
86
|
-
details: message.error || {}
|
|
87
|
-
)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
Serialization.readonly_copy(message.result)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# @rbs (Message) -> bot
|
|
94
|
-
def raise_rejection(message)
|
|
95
|
-
rejection = message.rejection
|
|
96
|
-
raise Rejected.new(
|
|
97
|
-
code: rejection.fetch("code"),
|
|
98
|
-
message: rejection.fetch("message"),
|
|
99
|
-
details: rejection.fetch("details"),
|
|
100
|
-
message_id: message.id
|
|
101
|
-
)
|
|
81
|
+
message.result!
|
|
102
82
|
end
|
|
103
83
|
|
|
104
84
|
# @rbs () -> ProcessRegistry
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
|
|
3
|
+
module SolidObjects
|
|
4
|
+
module Telemetry
|
|
5
|
+
FIELDS = %w[
|
|
6
|
+
activationGeneration activationOwnerId actorId actorType ageMilliseconds attempt broadcastId
|
|
7
|
+
broadcastWorkers byteCount code commitAction component componentCount count currentIntervalMilliseconds
|
|
8
|
+
deliveryMode depth durationMilliseconds effectId effectName effectWorkers errorName failureCount
|
|
9
|
+
generation idlePollingIntervalMilliseconds incarnation instanceId intervalMilliseconds
|
|
10
|
+
latenessMilliseconds messageId name nextRunAt occurrence operation outboxKind outcome ownerId payload
|
|
11
|
+
phase pollingIntervalMilliseconds previousIntervalMilliseconds previousRunAt processId processKind
|
|
12
|
+
reason reminderId reminderSchedulers requestId retryable revision role sequence status thresholdBytes
|
|
13
|
+
timeoutMilliseconds truncated waitingOn workers
|
|
14
|
+
].freeze #: Array[String]
|
|
15
|
+
ALIASES = {
|
|
16
|
+
"errorClass" => "errorName",
|
|
17
|
+
"stateRevision" => "revision",
|
|
18
|
+
"durationMs" => "durationMilliseconds",
|
|
19
|
+
"commitActionName" => "commitAction",
|
|
20
|
+
"payloadName" => "payload"
|
|
21
|
+
}.freeze #: Hash[String, String]
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
# @rbs (Effect | Broadcast) -> void
|
|
25
|
+
def outbox(record)
|
|
26
|
+
return unless SolidObjects.configuration.instrumentation || ActiveSupport::Notifications.notifier.listening?("solid_objects.outbox.age")
|
|
27
|
+
|
|
28
|
+
instance = record.instance
|
|
29
|
+
SolidObjects.instrument(
|
|
30
|
+
:"outbox.age",
|
|
31
|
+
instance_id: record.instance_id,
|
|
32
|
+
actor_type: instance.actor_type,
|
|
33
|
+
actor_id: instance.actor_id,
|
|
34
|
+
message_id: record.message_id,
|
|
35
|
+
attempt: record.attempt_count,
|
|
36
|
+
outbox_kind: record.is_a?(Effect) ? "effect" : "broadcast",
|
|
37
|
+
age_milliseconds: [ ((SolidObjects.database_adapter.database_now - record.available_at) * 1000).round, 0 ].max,
|
|
38
|
+
**outbox_identity(record)
|
|
39
|
+
)
|
|
40
|
+
rescue
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @rbs (Symbol, Hash[Symbol, Object]) -> void
|
|
45
|
+
def emit(name, payload)
|
|
46
|
+
observer = SolidObjects.configuration.instrumentation
|
|
47
|
+
return unless observer
|
|
48
|
+
|
|
49
|
+
deliver(observer, event(name, payload))
|
|
50
|
+
rescue
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @rbs (event_observer, portable_event) -> void
|
|
55
|
+
def deliver(observer, event)
|
|
56
|
+
observer.call(event)
|
|
57
|
+
rescue => error
|
|
58
|
+
log_delivery_failure(event.fetch("name"), error)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @rbs (Symbol, Hash[Symbol, Object]) -> portable_event
|
|
62
|
+
def event(name, payload)
|
|
63
|
+
attributes = safe_attributes(payload)
|
|
64
|
+
adapter = DatabaseAdapter.family(Record.connection).to_s
|
|
65
|
+
event_name = "solid_objects.#{name}"
|
|
66
|
+
labels = { "event" => event_name, "adapter" => adapter, "actorType" => attributes["actorType"].to_s }
|
|
67
|
+
metrics = [ { "name" => "solid_objects.events", "kind" => "counter", "unit" => "1", "value" => 1, "labels" => labels } ]
|
|
68
|
+
[
|
|
69
|
+
[ "durationMilliseconds", "solid_objects.duration", "histogram", "ms" ],
|
|
70
|
+
[ "latenessMilliseconds", "solid_objects.reminder.lateness", "histogram", "ms" ],
|
|
71
|
+
[ "ageMilliseconds", "solid_objects.outbox.age", "histogram", "ms" ],
|
|
72
|
+
[ "depth", "solid_objects.mailbox.depth", "gauge", "1" ]
|
|
73
|
+
].each do |field, metric, kind, unit|
|
|
74
|
+
value = attributes[field]
|
|
75
|
+
next unless value.is_a?(Numeric) && value.finite?
|
|
76
|
+
|
|
77
|
+
metrics << { "name" => metric, "kind" => kind, "unit" => unit, "value" => [ value, 0 ].max, "labels" => labels }
|
|
78
|
+
end
|
|
79
|
+
Serialization.readonly_copy(
|
|
80
|
+
"schemaVersion" => 1,
|
|
81
|
+
"name" => event_name,
|
|
82
|
+
"occurredAt" => Time.now.utc.iso8601(3),
|
|
83
|
+
"adapter" => adapter,
|
|
84
|
+
"actorType" => attributes["actorType"]&.to_s,
|
|
85
|
+
"actorId" => attributes["actorId"]&.to_s,
|
|
86
|
+
"incarnation" => (attributes["incarnation"] || attributes["instanceId"])&.to_s,
|
|
87
|
+
"revision" => attributes["revision"]&.to_s,
|
|
88
|
+
"messageId" => attributes["messageId"]&.to_s,
|
|
89
|
+
"attempt" => attributes.fetch("attempt", 0),
|
|
90
|
+
"attributes" => attributes,
|
|
91
|
+
"metrics" => metrics
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @rbs (Hash[Symbol, Object]) -> Hash[String, telemetry_value]
|
|
96
|
+
def safe_attributes(payload)
|
|
97
|
+
payload.each_with_object({}) do |(key, value), attributes|
|
|
98
|
+
value = value.to_s if key == :reason && value.is_a?(Symbol)
|
|
99
|
+
if %i[previous_interval current_interval].include?(key) && value.is_a?(Numeric)
|
|
100
|
+
attributes["#{key.to_s.camelize(:lower)}Milliseconds"] = (value * 1000).round
|
|
101
|
+
next
|
|
102
|
+
end
|
|
103
|
+
name = key.to_s.camelize(:lower)
|
|
104
|
+
name = ALIASES.fetch(name, name)
|
|
105
|
+
next unless FIELDS.include?(name)
|
|
106
|
+
next unless value.nil? || value.is_a?(String) || value.is_a?(Numeric) || value == true || value == false
|
|
107
|
+
|
|
108
|
+
value = value.camelize(:lower) if name == "waitingOn" && value.is_a?(String)
|
|
109
|
+
value = value.to_s if !value.nil? && (name.end_with?("Id") || %w[revision sequence generation activationGeneration].include?(name))
|
|
110
|
+
attributes[name] = value
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
# @rbs (Effect | Broadcast) -> Hash[Symbol, String | Integer]
|
|
117
|
+
def outbox_identity(record)
|
|
118
|
+
return { effect_id: record.effect_id, effect_name: record.name } if record.is_a?(Effect)
|
|
119
|
+
|
|
120
|
+
{ broadcast_id: record.broadcast_id, revision: record.message.sequence }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @rbs (String, Exception) -> void
|
|
124
|
+
def log_delivery_failure(event_name, error)
|
|
125
|
+
SolidObjects.configuration.logger.error(
|
|
126
|
+
{
|
|
127
|
+
event: "solid_objects.instrumentation.failed",
|
|
128
|
+
instrumentation_event: event_name,
|
|
129
|
+
error_class: error.class.name
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
rescue
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
data/lib/solid_objects/worker.rb
CHANGED
|
@@ -69,8 +69,7 @@ module SolidObjects
|
|
|
69
69
|
SolidObjects.configuration.logger.error(
|
|
70
70
|
event: "solid_objects.worker.error",
|
|
71
71
|
process_id: process_registry.process_record&.id,
|
|
72
|
-
error_class: error.class.name
|
|
73
|
-
error_message: error.message
|
|
72
|
+
error_class: error.class.name
|
|
74
73
|
)
|
|
75
74
|
0
|
|
76
75
|
end
|
data/lib/solid_objects.rb
CHANGED
|
@@ -16,6 +16,8 @@ require "solid_objects/sync_deadline"
|
|
|
16
16
|
require "solid_objects/callable_keywords"
|
|
17
17
|
require "solid_objects/configuration"
|
|
18
18
|
require "solid_objects/instrumentation"
|
|
19
|
+
require "solid_objects/telemetry"
|
|
20
|
+
require "solid_objects/diagnostics"
|
|
19
21
|
require "solid_objects/log_subscriber"
|
|
20
22
|
require "solid_objects/serialization"
|
|
21
23
|
require "solid_objects/context"
|
|
@@ -67,6 +69,7 @@ require "solid_objects/effect_payload"
|
|
|
67
69
|
require "solid_objects/effect_recovery_coordinator"
|
|
68
70
|
require "solid_objects/process_heartbeat"
|
|
69
71
|
require "solid_objects/commit_action_registry"
|
|
72
|
+
require "solid_objects/observer_registry"
|
|
70
73
|
require "solid_objects/lease"
|
|
71
74
|
require "solid_objects/lease_renewer"
|
|
72
75
|
# The reminder scheduler and the effect executor enqueue through the mailbox,
|
|
@@ -139,6 +142,11 @@ module SolidObjects
|
|
|
139
142
|
commit_action_registry.register(name, handler)
|
|
140
143
|
end
|
|
141
144
|
|
|
145
|
+
# @rbs () -> ObserverRegistry
|
|
146
|
+
def observer_registry
|
|
147
|
+
@observer_registry ||= ObserverRegistry.new
|
|
148
|
+
end
|
|
149
|
+
|
|
142
150
|
# @rbs () -> Client
|
|
143
151
|
def client
|
|
144
152
|
require "solid_objects/client"
|
|
@@ -203,6 +211,8 @@ module SolidObjects
|
|
|
203
211
|
@caller_process = nil
|
|
204
212
|
@effect_registry = EffectRegistry.new
|
|
205
213
|
@commit_action_registry = CommitActionRegistry.new
|
|
214
|
+
@observer_registry&.clear
|
|
215
|
+
@observer_registry = ObserverRegistry.new
|
|
206
216
|
@dead_letters = nil
|
|
207
217
|
@redrives = nil
|
|
208
218
|
@administration = nil
|
|
@@ -348,6 +348,12 @@ module SolidObjects
|
|
|
348
348
|
# @rbs () -> void
|
|
349
349
|
def discard_intents: () -> void
|
|
350
350
|
|
|
351
|
+
# @rbs () -> Integer
|
|
352
|
+
def intent_count: () -> Integer
|
|
353
|
+
|
|
354
|
+
# @rbs [Result] (String) { () -> Result } -> Result
|
|
355
|
+
def read_projection: [Result] (String) { () -> Result } -> Result
|
|
356
|
+
|
|
351
357
|
private
|
|
352
358
|
|
|
353
359
|
attr_reader effect_intents: untyped
|
|
@@ -360,6 +366,9 @@ module SolidObjects
|
|
|
360
366
|
|
|
361
367
|
attr_reader outbound_message_intents: untyped
|
|
362
368
|
|
|
369
|
+
# @rbs () -> Array[Array[Hash[Symbol, Object]]]
|
|
370
|
+
def intent_snapshot: () -> Array[Array[Hash[Symbol, Object]]]
|
|
371
|
+
|
|
363
372
|
# @rbs (String) { () -> untyped } -> untyped
|
|
364
373
|
def guard_application_writes: (String) { () -> untyped } -> untyped
|
|
365
374
|
|
|
@@ -12,6 +12,8 @@ module SolidObjects
|
|
|
12
12
|
|
|
13
13
|
@revision: Integer
|
|
14
14
|
|
|
15
|
+
@state_data: Hash[String, json_value]
|
|
16
|
+
|
|
15
17
|
@observable_values: Hash[String, untyped]?
|
|
16
18
|
|
|
17
19
|
@observable_value_cache: Hash[String, untyped]
|
|
@@ -35,11 +37,14 @@ module SolidObjects
|
|
|
35
37
|
# @rbs (Symbol | String) -> untyped
|
|
36
38
|
def observable_value: (Symbol | String) -> untyped
|
|
37
39
|
|
|
40
|
+
# @rbs () -> Actor
|
|
41
|
+
def build_actor: () -> Actor
|
|
42
|
+
|
|
38
43
|
private
|
|
39
44
|
|
|
40
45
|
attr_reader instance: untyped
|
|
41
46
|
|
|
42
|
-
# @rbs () ->
|
|
43
|
-
def
|
|
47
|
+
# @rbs () -> Hash[String, json_value]
|
|
48
|
+
def migrated_state: () -> Hash[String, json_value]
|
|
44
49
|
end
|
|
45
50
|
end
|
|
@@ -16,6 +16,9 @@ module SolidObjects
|
|
|
16
16
|
# @rbs (MessageReference, timeout: Numeric, ?authorization_context: untyped) -> untyped
|
|
17
17
|
def wait: (MessageReference, timeout: Numeric, ?authorization_context: untyped) -> untyped
|
|
18
18
|
|
|
19
|
+
# @rbs (MessageReference, ?authorization_context: untyped) -> Message
|
|
20
|
+
def read_message: (MessageReference, ?authorization_context: untyped) -> Message
|
|
21
|
+
|
|
19
22
|
# @rbs (?reference: Reference?, ?request_id: String?, ?idempotency_key: String?, ?authorization_context: untyped) -> MessageReference?
|
|
20
23
|
def find_by: (?reference: Reference?, ?request_id: String?, ?idempotency_key: String?, ?authorization_context: untyped) -> MessageReference?
|
|
21
24
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module SolidObjects
|
|
4
4
|
class Configuration
|
|
5
|
-
@
|
|
5
|
+
@reminder_scheduler_count: Integer
|
|
6
6
|
|
|
7
7
|
@broadcast_worker_count: Integer
|
|
8
8
|
|
|
@@ -36,6 +36,8 @@ module SolidObjects
|
|
|
36
36
|
|
|
37
37
|
@table_name_prefix: String
|
|
38
38
|
|
|
39
|
+
@transmission_actor_type_resolver: Proc
|
|
40
|
+
|
|
39
41
|
@administration_identity: Proc
|
|
40
42
|
|
|
41
43
|
@authorize_transmission: Proc
|
|
@@ -64,9 +66,9 @@ module SolidObjects
|
|
|
64
66
|
|
|
65
67
|
@logger: untyped
|
|
66
68
|
|
|
67
|
-
@
|
|
69
|
+
@instrumentation: event_observer?
|
|
68
70
|
|
|
69
|
-
@
|
|
71
|
+
@connects_to: Hash[Symbol, untyped]?
|
|
70
72
|
|
|
71
73
|
@polling_interval: Float
|
|
72
74
|
|
|
@@ -214,6 +216,8 @@ module SolidObjects
|
|
|
214
216
|
|
|
215
217
|
attr_accessor transmission_actor_type_resolver: untyped
|
|
216
218
|
|
|
219
|
+
attr_accessor instrumentation: event_observer?
|
|
220
|
+
|
|
217
221
|
# @rbs @additional_components: Array[untyped]
|
|
218
222
|
attr_reader additional_components: untyped
|
|
219
223
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated from lib/solid_objects/diagnostics.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module SolidObjects
|
|
4
|
+
class Diagnostics
|
|
5
|
+
# @rbs @reference: Reference
|
|
6
|
+
# @rbs (Reference) -> void
|
|
7
|
+
def initialize: (Reference) -> void
|
|
8
|
+
|
|
9
|
+
# @rbs (?limit: Integer, ?authorization_context: untyped) -> actor_diagnostics
|
|
10
|
+
def summary: (?limit: Integer, ?authorization_context: untyped) -> actor_diagnostics
|
|
11
|
+
|
|
12
|
+
# @rbs (?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
13
|
+
def observe: (?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
attr_reader reference: Reference
|
|
18
|
+
|
|
19
|
+
# @rbs (Symbol, ?authorization_context: untyped) -> void
|
|
20
|
+
def authorize!: (Symbol, ?authorization_context: untyped) -> void
|
|
21
|
+
|
|
22
|
+
# @rbs (Array[Time?], now: Time, limit: Integer) -> diagnostic_summary
|
|
23
|
+
def summarize: (Array[Time?], now: Time, limit: Integer) -> diagnostic_summary
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -4,6 +4,8 @@ module SolidObjects
|
|
|
4
4
|
class Executor
|
|
5
5
|
@completion_transaction: untyped
|
|
6
6
|
|
|
7
|
+
@started_at: Float
|
|
8
|
+
|
|
7
9
|
@message: Message
|
|
8
10
|
|
|
9
11
|
@activation: Activation
|
|
@@ -26,8 +28,8 @@ module SolidObjects
|
|
|
26
28
|
# @rbs (MessageContext) -> untyped
|
|
27
29
|
def invoke_actor: (MessageContext) -> untyped
|
|
28
30
|
|
|
29
|
-
# @rbs (Hash[String,
|
|
30
|
-
def
|
|
31
|
+
# @rbs (Hash[String, json_value], Hash[String, json_value]) -> void
|
|
32
|
+
def ensure_query_is_read_only!: (Hash[String, json_value], Hash[String, json_value]) -> void
|
|
31
33
|
|
|
32
34
|
# @rbs (Hash[String, untyped], Hash[String, untyped]) -> Hash[String, untyped]
|
|
33
35
|
def changed_observables: (Hash[String, untyped], Hash[String, untyped]) -> Hash[String, untyped]
|
|
@@ -103,6 +105,12 @@ module SolidObjects
|
|
|
103
105
|
# @rbs (message: Message, error_details: Hash[String, untyped], now: Time) -> DeadLetter
|
|
104
106
|
def create_dead_letter: (message: Message, error_details: Hash[String, untyped], now: Time) -> DeadLetter
|
|
105
107
|
|
|
108
|
+
# @rbs () -> bool
|
|
109
|
+
def recovery_message?: () -> bool
|
|
110
|
+
|
|
111
|
+
# @rbs () -> (Integer | Float)
|
|
112
|
+
def elapsed_milliseconds: () -> (Integer | Float)
|
|
113
|
+
|
|
106
114
|
# @rbs () -> Hash[Symbol, untyped]
|
|
107
115
|
def instrumentation_payload: () -> Hash[Symbol, untyped]
|
|
108
116
|
end
|
|
@@ -28,14 +28,14 @@ module SolidObjects
|
|
|
28
28
|
# @rbs (id: Integer, request_id: String, actor_type: String, actor_id: String, sequence: Integer) -> void
|
|
29
29
|
def initialize: (id: Integer, request_id: String, actor_type: String, actor_id: String, sequence: Integer) -> void
|
|
30
30
|
|
|
31
|
-
# @rbs () -> String
|
|
32
|
-
def status: () -> String
|
|
31
|
+
# @rbs (?authorization_context: untyped) -> String
|
|
32
|
+
def status: (?authorization_context: untyped) -> String
|
|
33
33
|
|
|
34
|
-
# @rbs () ->
|
|
35
|
-
def result: () ->
|
|
34
|
+
# @rbs (?authorization_context: untyped) -> json_value
|
|
35
|
+
def result: (?authorization_context: untyped) -> json_value
|
|
36
36
|
|
|
37
|
-
# @rbs () -> Outcome
|
|
38
|
-
def outcome: () -> Outcome
|
|
37
|
+
# @rbs (?authorization_context: untyped) -> Outcome
|
|
38
|
+
def outcome: (?authorization_context: untyped) -> Outcome
|
|
39
39
|
|
|
40
40
|
# @rbs (?timeout: Numeric, ?authorization_context: untyped) -> untyped
|
|
41
41
|
def wait: (?timeout: Numeric, ?authorization_context: untyped) -> untyped
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Generated from lib/solid_objects/observer_registry.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module SolidObjects
|
|
4
|
+
class ObserverRegistry
|
|
5
|
+
MAXIMUM_OBSERVERS: ::Integer
|
|
6
|
+
|
|
7
|
+
@subscriptions: Array[Object]
|
|
8
|
+
|
|
9
|
+
@mutex: Mutex
|
|
10
|
+
|
|
11
|
+
# @rbs () -> void
|
|
12
|
+
def initialize: () -> void
|
|
13
|
+
|
|
14
|
+
# @rbs () { (ActiveSupport::Notifications::Event) -> void } -> Proc
|
|
15
|
+
def subscribe: () { (ActiveSupport::Notifications::Event) -> void } -> Proc
|
|
16
|
+
|
|
17
|
+
# @rbs () -> void
|
|
18
|
+
def clear: () -> void
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
attr_reader subscriptions: Array[Object]
|
|
23
|
+
|
|
24
|
+
attr_reader mutex: Mutex
|
|
25
|
+
|
|
26
|
+
# @rbs (Object) -> void
|
|
27
|
+
def unsubscribe: (Object) -> void
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module SolidObjects
|
|
4
4
|
class PayloadBroadcast
|
|
5
|
-
MAXIMUM_PAYLOAD_BYTES: ::Integer
|
|
6
|
-
|
|
7
5
|
REVISION_OBSERVABLE: ::String
|
|
8
6
|
|
|
9
7
|
@snapshot: ActorSnapshot
|
|
@@ -39,8 +37,8 @@ module SolidObjects
|
|
|
39
37
|
# Distinguishes a block that relied on the old class-level receiver from an
|
|
40
38
|
# ordinary typo, so the one behaviour change reports itself instead of
|
|
41
39
|
# surfacing as an unexplained NameError.
|
|
42
|
-
# @rbs (NameError[
|
|
43
|
-
def class_level_receiver?: (NameError[
|
|
40
|
+
# @rbs (NameError[BasicObject], Actor?) -> bool
|
|
41
|
+
def class_level_receiver?: (NameError[BasicObject], Actor?) -> bool
|
|
44
42
|
|
|
45
43
|
# @rbs () -> void
|
|
46
44
|
def authorize!: () -> void
|
|
@@ -13,6 +13,15 @@ module SolidObjects
|
|
|
13
13
|
# @rbs (actor_type: String, actor_id: String) -> void
|
|
14
14
|
def initialize: (actor_type: String, actor_id: String) -> void
|
|
15
15
|
|
|
16
|
+
# @rbs (?limit: Integer, ?authorization_context: untyped) -> actor_diagnostics
|
|
17
|
+
def diagnostics: (?limit: Integer, ?authorization_context: untyped) -> actor_diagnostics
|
|
18
|
+
|
|
19
|
+
# @rbs (?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
20
|
+
def observe: (?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
21
|
+
|
|
22
|
+
# @rbs (String, ?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
23
|
+
def on: (String, ?authorization_context: untyped) { (portable_event) -> void } -> Proc
|
|
24
|
+
|
|
16
25
|
# @rbs (?available_at: Time?, ?idempotency_key: String?, ?authorization_context: untyped) -> OperationDispatcher
|
|
17
26
|
def async: (?available_at: Time?, ?idempotency_key: String?, ?authorization_context: untyped) -> OperationDispatcher
|
|
18
27
|
|