solid_objects 0.15.2 → 0.16.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +151 -0
  3. data/README.md +1 -1
  4. data/app/models/solid_objects/administration_event.rb +7 -0
  5. data/app/models/solid_objects/redrive.rb +7 -0
  6. data/benchmark/support.rb +2 -8
  7. data/db/migrate/20260922000000_add_solid_objects_administration_events.rb +26 -0
  8. data/db/migrate/20260922000001_add_solid_objects_redrives.rb +32 -0
  9. data/db/migrate/20260923000000_add_solid_objects_completed_idempotency_keys.rb +10 -0
  10. data/docs/adr/0011-wake-up-strategy.md +11 -1
  11. data/docs/architecture.md +41 -5
  12. data/docs/dashboard.md +10 -0
  13. data/docs/fit.md +6 -0
  14. data/docs/operations.md +153 -7
  15. data/docs/realtime.md +32 -26
  16. data/docs/roadmap.md +60 -32
  17. data/examples/at_least_once/boot.rb +2 -8
  18. data/lib/solid_objects/activation.rb +13 -6
  19. data/lib/solid_objects/actor.rb +134 -8
  20. data/lib/solid_objects/actor_snapshot.rb +8 -5
  21. data/lib/solid_objects/administration_audit.rb +30 -0
  22. data/lib/solid_objects/client.rb +81 -0
  23. data/lib/solid_objects/configuration.rb +47 -2
  24. data/lib/solid_objects/context.rb +10 -4
  25. data/lib/solid_objects/dead_letter_manager.rb +42 -6
  26. data/lib/solid_objects/dead_letter_scope.rb +143 -0
  27. data/lib/solid_objects/dead_row.rb +15 -0
  28. data/lib/solid_objects/doctor.rb +24 -5
  29. data/lib/solid_objects/errors.rb +11 -0
  30. data/lib/solid_objects/executor.rb +41 -3
  31. data/lib/solid_objects/message_reference.rb +29 -9
  32. data/lib/solid_objects/outcome.rb +31 -0
  33. data/lib/solid_objects/process_registry.rb +3 -1
  34. data/lib/solid_objects/redrive_manager.rb +130 -0
  35. data/lib/solid_objects/redrive_runner.rb +60 -0
  36. data/lib/solid_objects/redrive_task.rb +14 -0
  37. data/lib/solid_objects/reference.rb +5 -0
  38. data/lib/solid_objects/schema_bootstrap.rb +27 -0
  39. data/lib/solid_objects/supervisor.rb +43 -0
  40. data/lib/solid_objects/test_helper.rb +2 -0
  41. data/lib/solid_objects/version.rb +1 -1
  42. data/lib/solid_objects/wake_up.rb +12 -0
  43. data/lib/solid_objects/wake_up_adapters/postgresql.rb +12 -0
  44. data/lib/solid_objects/wake_up_adapters/redis.rb +12 -0
  45. data/lib/solid_objects/wake_up_adapters.rb +206 -11
  46. data/lib/solid_objects/wake_up_capability.rb +15 -0
  47. data/lib/solid_objects.rb +46 -3
  48. data/sig/generated/lib/solid_objects/activation.rbs +7 -0
  49. data/sig/generated/lib/solid_objects/actor.rbs +93 -2
  50. data/sig/generated/lib/solid_objects/administration_audit.rbs +11 -0
  51. data/sig/generated/lib/solid_objects/client.rbs +12 -0
  52. data/sig/generated/lib/solid_objects/configuration.rbs +54 -28
  53. data/sig/generated/lib/solid_objects/context.rbs +11 -6
  54. data/sig/generated/lib/solid_objects/dead_letter_manager.rbs +9 -0
  55. data/sig/generated/lib/solid_objects/dead_letter_scope.rbs +58 -0
  56. data/sig/generated/lib/solid_objects/dead_row.rbs +30 -0
  57. data/sig/generated/lib/solid_objects/doctor.rbs +3 -0
  58. data/sig/generated/lib/solid_objects/errors.rbs +8 -0
  59. data/sig/generated/lib/solid_objects/executor.rbs +9 -0
  60. data/sig/generated/lib/solid_objects/message_reference.rbs +8 -0
  61. data/sig/generated/lib/solid_objects/outcome.rbs +52 -0
  62. data/sig/generated/lib/solid_objects/redrive_manager.rbs +43 -0
  63. data/sig/generated/lib/solid_objects/redrive_runner.rbs +22 -0
  64. data/sig/generated/lib/solid_objects/redrive_task.rbs +33 -0
  65. data/sig/generated/lib/solid_objects/reference.rbs +5 -2
  66. data/sig/generated/lib/solid_objects/schema_bootstrap.rbs +11 -0
  67. data/sig/generated/lib/solid_objects/supervisor.rbs +15 -0
  68. data/sig/generated/lib/solid_objects/wake_up.rbs +5 -0
  69. data/sig/generated/lib/solid_objects/wake_up_adapters/postgresql.rbs +5 -0
  70. data/sig/generated/lib/solid_objects/wake_up_adapters/redis.rbs +5 -0
  71. data/sig/generated/lib/solid_objects/wake_up_adapters.rbs +75 -9
  72. data/sig/generated/lib/solid_objects/wake_up_capability.rbs +28 -0
  73. data/sig/generated/lib/solid_objects.rbs +14 -2
  74. data/sig/generated/models/solid_objects/administration_event.rbs +6 -0
  75. data/sig/generated/models/solid_objects/redrive.rbs +6 -0
  76. data/sig/public/reminder_payload.rbs +3 -0
  77. metadata +28 -2
data/lib/solid_objects.rb CHANGED
@@ -26,7 +26,14 @@ require "solid_objects/actor_definition"
26
26
  require "solid_objects/application_write_guard"
27
27
  require "solid_objects/actor"
28
28
  require "solid_objects/reference"
29
+ require "solid_objects/outcome"
29
30
  require "solid_objects/message_reference"
31
+ require "solid_objects/administration_audit"
32
+ require "solid_objects/redrive_task"
33
+ require "solid_objects/redrive_manager"
34
+ require "solid_objects/redrive_runner"
35
+ require "solid_objects/dead_row"
36
+ require "solid_objects/dead_letter_scope"
30
37
  require "solid_objects/dead_letter_manager"
31
38
  require "solid_objects/message_pruner"
32
39
  require "solid_objects/instance_pruner"
@@ -49,6 +56,7 @@ require "solid_objects/actor_view"
49
56
  require "solid_objects/actor_channel"
50
57
  require "solid_objects/action_cable_broadcast_adapter"
51
58
  require "solid_objects/database_adapter"
59
+ require "solid_objects/wake_up_capability"
52
60
  require "solid_objects/wake_up"
53
61
  require "solid_objects/wake_up_adapters/postgresql"
54
62
  require "solid_objects/wake_up_adapters/redis"
@@ -78,6 +86,8 @@ require "solid_objects/engine" if defined?(Rails::Engine)
78
86
  module SolidObjects
79
87
  extend Instrumentation
80
88
 
89
+ @wake_up_mutex = Thread::Mutex.new
90
+
81
91
  class << self
82
92
  # @rbs () -> Configuration
83
93
  def configuration
@@ -157,6 +167,11 @@ module SolidObjects
157
167
  @dead_letters ||= DeadLetterManager.new
158
168
  end
159
169
 
170
+ # @rbs () -> RedriveManager
171
+ def redrives
172
+ @redrives ||= RedriveManager.new
173
+ end
174
+
160
175
  # @rbs () -> Administration
161
176
  def administration
162
177
  @administration ||= Administration.new
@@ -180,15 +195,16 @@ module SolidObjects
180
195
  # @rbs () -> void
181
196
  def reset!
182
197
  ProcessRegistry.reset_polling_warning! if defined?(ProcessRegistry)
198
+ reset_wake_up!
183
199
  @configuration = Configuration.new
184
200
  @registry = ActorRegistry.new
185
201
  @client = nil
186
202
  @database_adapter = nil
187
- @wake_up = nil
188
203
  @caller_process = nil
189
204
  @effect_registry = EffectRegistry.new
190
205
  @commit_action_registry = CommitActionRegistry.new
191
206
  @dead_letters = nil
207
+ @redrives = nil
192
208
  @administration = nil
193
209
  end
194
210
 
@@ -198,9 +214,36 @@ module SolidObjects
198
214
  @database_adapter ||= DatabaseAdapter.for(SolidObjects::Record.connection)
199
215
  end
200
216
 
201
- # @rbs () -> WakeUp
217
+ # @rbs () -> untyped
202
218
  def wake_up
203
- @wake_up ||= configuration.wake_up_adapter || WakeUp.new
219
+ @wake_up || @wake_up_mutex.synchronize { @wake_up ||= resolve_wake_up }
220
+ end
221
+
222
+ # @rbs () -> void
223
+ def reset_wake_up!
224
+ @wake_up_mutex.synchronize { @wake_up = nil }
225
+ WakeUpAdapters.reset_pooled_warning!
226
+ end
227
+
228
+ # @rbs () -> untyped
229
+ def resolve_wake_up
230
+ WakeUpAdapters.build(configuration.wake_up_adapter)
231
+ rescue ArgumentError
232
+ raise
233
+ rescue ActiveRecord::ActiveRecordError, SystemCallError, IOError => error
234
+ unreachable_wake_up(error)
235
+ end
236
+
237
+ # @rbs (Exception) -> untyped
238
+ def unreachable_wake_up(error)
239
+ adapter = WakeUp.new
240
+ adapter.capability = WakeUpCapability.new(
241
+ adapter: :in_process,
242
+ crosses_processes: false,
243
+ measured_floor_ms: nil,
244
+ reason: "the database could not be reached to select an adapter: #{error.class}"
245
+ )
246
+ adapter
204
247
  end
205
248
  end
206
249
  end
@@ -10,6 +10,10 @@ module SolidObjects
10
10
 
11
11
  @actor_class: Class
12
12
 
13
+ @instance_id: Integer
14
+
15
+ @actor_id: String
16
+
13
17
  @lease: Lease
14
18
 
15
19
  attr_reader lease: untyped
@@ -59,6 +63,9 @@ module SolidObjects
59
63
  # @rbs (Instance) -> Actor
60
64
  def build_actor: (Instance) -> Actor
61
65
 
66
+ # @rbs (Hash[String, untyped]) -> Actor
67
+ def new_actor: (Hash[String, untyped]) -> Actor
68
+
62
69
  # @rbs () -> void
63
70
  def release_lease: () -> void
64
71
 
@@ -58,6 +58,8 @@ module SolidObjects
58
58
 
59
59
  REMINDER_KEY_SEPARATOR: ::String
60
60
 
61
+ REMINDER_HANDLE_KEY: ::String
62
+
61
63
  class ReminderIntent < Data
62
64
  attr_reader name(): untyped
63
65
 
@@ -79,6 +81,55 @@ module SolidObjects
79
81
  def members: () -> [ :name, :operation, :at, :arguments, :interval_seconds, :missed_policy ]
80
82
  end
81
83
 
84
+ class UnscheduleIntent < Data
85
+ attr_reader name(): untyped
86
+
87
+ def self.new: (untyped name) -> instance
88
+ | (name: untyped) -> instance
89
+
90
+ def self.members: () -> [ :name ]
91
+
92
+ def members: () -> [ :name ]
93
+ end
94
+
95
+ class UnscheduleAllIntent < Data
96
+ attr_reader operation(): untyped
97
+
98
+ def self.new: (untyped operation) -> instance
99
+ | (operation: untyped) -> instance
100
+
101
+ def self.members: () -> [ :operation ]
102
+
103
+ def members: () -> [ :operation ]
104
+ end
105
+
106
+ class ReminderStatus < Data
107
+ attr_reader name(): untyped
108
+
109
+ attr_reader operation(): untyped
110
+
111
+ attr_reader key(): untyped
112
+
113
+ attr_reader next_run_at(): untyped
114
+
115
+ attr_reader interval_seconds(): untyped
116
+
117
+ attr_reader missed_policy(): untyped
118
+
119
+ attr_reader occurrence(): untyped
120
+
121
+ attr_reader status(): untyped
122
+
123
+ attr_reader handle(): untyped
124
+
125
+ def self.new: (untyped name, untyped operation, untyped key, untyped next_run_at, untyped interval_seconds, untyped missed_policy, untyped occurrence, untyped status, untyped handle) -> instance
126
+ | (name: untyped, operation: untyped, key: untyped, next_run_at: untyped, interval_seconds: untyped, missed_policy: untyped, occurrence: untyped, status: untyped, handle: untyped) -> instance
127
+
128
+ def self.members: () -> [ :name, :operation, :key, :next_run_at, :interval_seconds, :missed_policy, :occurrence, :status, :handle ]
129
+
130
+ def members: () -> [ :name, :operation, :key, :next_run_at, :interval_seconds, :missed_policy, :occurrence, :status, :handle ]
131
+ end
132
+
82
133
  class OutboundMessageIntent < Data
83
134
  attr_reader actor_type(): untyped
84
135
 
@@ -172,8 +223,8 @@ module SolidObjects
172
223
 
173
224
  attr_reader state: untyped
174
225
 
175
- # @rbs (actor_id: String, state: State) -> void
176
- def initialize: (actor_id: String, state: State) -> void
226
+ # @rbs (actor_id: String, state: State, ?instance_id: Integer?) -> void
227
+ def initialize: (actor_id: String, state: State, ?instance_id: Integer?) -> void
177
228
 
178
229
  # @rbs () -> MessageContext?
179
230
  def current_message: () -> MessageContext?
@@ -201,6 +252,46 @@ module SolidObjects
201
252
  # @rbs (at: Time, ?every: Numeric?, ?missed: Symbol | String, ?key: (String | Symbol | Integer)?) -> OperationDispatcher
202
253
  def schedule: (at: Time, ?every: Numeric?, ?missed: Symbol | String, ?key: (String | Symbol | Integer)?) -> OperationDispatcher
203
254
 
255
+ # @rbs (Symbol | String | reminder_handle, ?key: (String | Symbol | Integer)?) -> nil
256
+ def unschedule: (Symbol | String | reminder_handle, ?key: (String | Symbol | Integer)?) -> nil
257
+
258
+ # @rbs (Symbol | String) -> nil
259
+ def unschedule_all: (Symbol | String) -> nil
260
+
261
+ # @rbs (Symbol | String | reminder_handle, ?key: (String | Symbol | Integer)?) -> ReminderStatus?
262
+ def reminder: (Symbol | String | reminder_handle, ?key: (String | Symbol | Integer)?) -> ReminderStatus?
263
+
264
+ # @rbs (Symbol | String) -> Array[ReminderStatus]
265
+ def reminders: (Symbol | String) -> Array[ReminderStatus]
266
+
267
+ attr_reader instance_id: untyped
268
+
269
+ # @rbs (Symbol | String) -> String
270
+ def validated_reminder_operation: (Symbol | String) -> String
271
+
272
+ # @rbs (String) -> nil
273
+ def unschedule_name: (String) -> nil
274
+
275
+ # @rbs (reminder_handle, key: untyped) -> String
276
+ def handle_name: (reminder_handle, key: untyped) -> String
277
+
278
+ # The view is the committed schedule with this turn's staged intents applied
279
+ # in order, so a read agrees with what the commit will leave behind.
280
+ # @rbs () -> Hash[String, ReminderStatus]
281
+ def reminder_view: () -> Hash[String, ReminderStatus]
282
+
283
+ # @rbs () -> Hash[String, ReminderStatus]
284
+ def committed_reminders: () -> Hash[String, ReminderStatus]
285
+
286
+ # @rbs (Hash[String, ReminderStatus], untyped) -> void
287
+ def apply_reminder_intent: (Hash[String, ReminderStatus], untyped) -> void
288
+
289
+ # @rbs (name: String, operation: String, next_run_at: Time?, interval_seconds: untyped, missed_policy: String, occurrence: Integer, status: String) -> ReminderStatus
290
+ def reminder_status: (name: String, operation: String, next_run_at: Time?, interval_seconds: untyped, missed_policy: String, occurrence: Integer, status: String) -> ReminderStatus
291
+
292
+ # @rbs (name: String, operation: String) -> String?
293
+ def reminder_key_of: (name: String, operation: String) -> String?
294
+
204
295
  # @rbs ((String | Symbol | Integer)?) -> String?
205
296
  def validated_reminder_key: ((String | Symbol | Integer)?) -> String?
206
297
 
@@ -0,0 +1,11 @@
1
+ # Generated from lib/solid_objects/administration_audit.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ module AdministrationAudit
5
+ # @rbs (action: String, kind: String, ?subject_id: untyped, ?filters: Hash[Symbol | String, untyped]?, ?actor: String?) -> void
6
+ def self?.record: (action: String, kind: String, ?subject_id: untyped, ?filters: Hash[Symbol | String, untyped]?, ?actor: String?) -> void
7
+
8
+ # @rbs (untyped) -> String?
9
+ def self?.identity: (untyped) -> String?
10
+ end
11
+ 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 (?reference: Reference?, ?request_id: String?, ?idempotency_key: String?, ?authorization_context: untyped) -> MessageReference?
20
+ def find_by: (?reference: Reference?, ?request_id: String?, ?idempotency_key: String?, ?authorization_context: untyped) -> MessageReference?
21
+
19
22
  # @rbs (Reference, ?authorization_context: untyped) -> StateSnapshot
20
23
  def snapshot: (Reference, ?authorization_context: untyped) -> StateSnapshot
21
24
 
@@ -29,6 +32,15 @@ module SolidObjects
29
32
  # @rbs (reference: Reference, operation: Symbol | String, arguments: Hash[Symbol | String, untyped], idempotency_key: String?, timeout: Numeric) -> MessageReference
30
33
  def enqueue_sync: (reference: Reference, operation: Symbol | String, arguments: Hash[Symbol | String, untyped], idempotency_key: String?, timeout: Numeric) -> MessageReference
31
34
 
35
+ # @rbs (Message?, authorization_context: untyped) -> MessageReference?
36
+ def readable_message: (Message?, authorization_context: untyped) -> MessageReference?
37
+
38
+ # @rbs (Message, authorization_context: untyped) -> bool
39
+ def authorized_to_read?: (Message, authorization_context: untyped) -> bool
40
+
41
+ # @rbs (actor_type: String, actor_id: String, operation: String, arguments: Hash[String, untyped], authorization_context: untyped) -> bool
42
+ def authorized_to_invoke?: (actor_type: String, actor_id: String, operation: String, arguments: Hash[String, untyped], authorization_context: untyped) -> bool
43
+
32
44
  # @rbs (MessageReference, Message) -> void
33
45
  def validate_message_reference!: (MessageReference, Message) -> void
34
46
 
@@ -2,65 +2,71 @@
2
2
 
3
3
  module SolidObjects
4
4
  class Configuration
5
- @process_alive_threshold: Float
5
+ @transmission_actor_type_resolver: Proc
6
6
 
7
- @shutdown_timeout: Float
7
+ @broadcast_worker_count: Integer
8
8
 
9
- @supervisor_monitor_interval: Float
9
+ @effect_worker_count: Integer
10
10
 
11
- @retention_interval: Float
11
+ @worker_count: Integer
12
12
 
13
- @dead_process_cleanup_interval: Float
13
+ @redrive_batch_pause: Float
14
14
 
15
- @message_retention: Numeric
15
+ @redrive_batch_size: Integer
16
16
 
17
- @message_retention_by_actor_type: Hash[String, Numeric]
17
+ @retained_idempotency_keys_bytes: Integer
18
18
 
19
- @instance_retention_by_actor_type: Hash[String, Numeric]
19
+ @retained_idempotency_keys: Integer
20
+
21
+ @prune_batch_size: Integer
20
22
 
21
23
  @process_retention: Numeric
22
24
 
23
- @prune_batch_size: Integer
25
+ @instance_retention_by_actor_type: Hash[String, Numeric]
24
26
 
25
- @worker_count: Integer
27
+ @message_retention_by_actor_type: Hash[String, Numeric]
26
28
 
27
- @effect_worker_count: Integer
29
+ @message_retention: Numeric
28
30
 
29
- @broadcast_worker_count: Integer
31
+ @dead_process_cleanup_interval: Float
30
32
 
31
- @reminder_scheduler_count: Integer
33
+ @retention_interval: Float
32
34
 
33
- @connects_to: Hash[Symbol, untyped]?
35
+ @supervisor_monitor_interval: Float
34
36
 
35
- @logger: untyped
37
+ @table_name_prefix: String
36
38
 
37
- @stream_signing_secret: String?
39
+ @administration_identity: Proc
38
40
 
39
- @broadcast_adapter: Proc?
41
+ @authorize_transmission: Proc
40
42
 
41
- @wake_up_adapter: untyped
43
+ @authorize_administration: Proc
42
44
 
43
- @component_path_resolver: Proc?
45
+ @authorize_subscription: Proc
44
46
 
45
- @component_authorization_context: Proc
47
+ @authorize_destroy: Proc
46
48
 
47
- @payload_authorization_context: Proc
49
+ @authorize_query: Proc
48
50
 
49
51
  @authorize_message: Proc
50
52
 
51
- @authorize_query: Proc
53
+ @payload_authorization_context: Proc
52
54
 
53
- @authorize_destroy: Proc
55
+ @component_authorization_context: Proc
54
56
 
55
- @authorize_subscription: Proc
57
+ @component_path_resolver: Proc?
56
58
 
57
- @authorize_administration: Proc
59
+ @wake_up_adapter: untyped
58
60
 
59
- @authorize_transmission: Proc
61
+ @broadcast_adapter: Proc?
60
62
 
61
- @transmission_actor_type_resolver: Proc
63
+ @stream_signing_secret: String?
62
64
 
63
- @table_name_prefix: String
65
+ @logger: untyped
66
+
67
+ @connects_to: Hash[Symbol, untyped]?
68
+
69
+ @reminder_scheduler_count: Integer
64
70
 
65
71
  @polling_interval: Float
66
72
 
@@ -98,6 +104,10 @@ module SolidObjects
98
104
 
99
105
  @process_heartbeat_interval: Float
100
106
 
107
+ @process_alive_threshold: Float
108
+
109
+ @shutdown_timeout: Float
110
+
101
111
  attr_accessor table_name_prefix: untyped
102
112
 
103
113
  attr_accessor polling_interval: untyped
@@ -156,6 +166,14 @@ module SolidObjects
156
166
 
157
167
  attr_accessor prune_batch_size: untyped
158
168
 
169
+ attr_accessor retained_idempotency_keys: untyped
170
+
171
+ attr_accessor retained_idempotency_keys_bytes: untyped
172
+
173
+ attr_accessor redrive_batch_size: untyped
174
+
175
+ attr_accessor redrive_batch_pause: untyped
176
+
159
177
  attr_accessor worker_count: untyped
160
178
 
161
179
  attr_accessor effect_worker_count: untyped
@@ -192,6 +210,8 @@ module SolidObjects
192
210
 
193
211
  attr_accessor authorize_transmission: untyped
194
212
 
213
+ attr_accessor administration_identity: untyped
214
+
195
215
  attr_accessor transmission_actor_type_resolver: untyped
196
216
 
197
217
  # @rbs @additional_components: Array[untyped]
@@ -230,6 +250,12 @@ module SolidObjects
230
250
 
231
251
  private
232
252
 
253
+ # @rbs () -> void
254
+ def validate_wake_up_adapter!: () -> void
255
+
256
+ # @rbs () -> void
257
+ def validate_wake_up_object!: () -> void
258
+
233
259
  # @rbs () -> Hash[Symbol, Numeric]
234
260
  def positive_values: () -> Hash[Symbol, Numeric]
235
261
 
@@ -30,12 +30,14 @@ module SolidObjects
30
30
 
31
31
  attr_reader authorization_context(): untyped
32
32
 
33
- def self.new: (untyped actor, untyped message, untyped authorization_context) -> instance
34
- | (actor: untyped, message: untyped, authorization_context: untyped) -> instance
33
+ attr_reader instance_id(): untyped
35
34
 
36
- def self.members: () -> [ :actor, :message, :authorization_context ]
35
+ def self.new: (untyped actor, untyped message, untyped authorization_context, untyped instance_id) -> instance
36
+ | (actor: untyped, message: untyped, authorization_context: untyped, instance_id: untyped) -> instance
37
37
 
38
- def members: () -> [ :actor, :message, :authorization_context ]
38
+ def self.members: () -> [ :actor, :message, :authorization_context, :instance_id ]
39
+
40
+ def members: () -> [ :actor, :message, :authorization_context, :instance_id ]
39
41
  end
40
42
 
41
43
  # @rbs () -> Frame?
@@ -50,7 +52,10 @@ module SolidObjects
50
52
  # @rbs () -> untyped
51
53
  def self.authorization_context: () -> untyped
52
54
 
53
- # @rbs (actor: Actor?, message: MessageContext?, authorization_context: untyped) { () -> untyped } -> untyped
54
- def self.with: (actor: Actor?, message: MessageContext?, authorization_context: untyped) { () -> untyped } -> untyped
55
+ # @rbs () -> Integer?
56
+ def self.current_instance_id: () -> Integer?
57
+
58
+ # @rbs (actor: Actor?, message: MessageContext?, ?authorization_context: untyped, ?instance_id: Integer?) { () -> untyped } -> untyped
59
+ def self.with: (actor: Actor?, message: MessageContext?, ?authorization_context: untyped, ?instance_id: Integer?) { () -> untyped } -> untyped
55
60
  end
56
61
  end
@@ -8,8 +8,17 @@ module SolidObjects
8
8
  # @rbs (Integer, ?authorization_context: untyped) -> MessageReference
9
9
  def retry: (Integer, ?authorization_context: untyped) -> MessageReference
10
10
 
11
+ # @rbs () -> DeadLetterScope
12
+ def effects: () -> DeadLetterScope
13
+
14
+ # @rbs () -> DeadLetterScope
15
+ def broadcasts: () -> DeadLetterScope
16
+
11
17
  private
12
18
 
19
+ # @rbs (DeadLetter) -> MessageReference
20
+ def enqueue_retry: (DeadLetter) -> MessageReference
21
+
13
22
  # @rbs (Symbol, authorization_context: untyped, ?dead_letter_id: Integer?) -> void
14
23
  def authorize!: (Symbol, authorization_context: untyped, ?dead_letter_id: Integer?) -> void
15
24
  end
@@ -0,0 +1,58 @@
1
+ # Generated from lib/solid_objects/dead_letter_scope.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ class DeadLetterScope
5
+ DEAD: ::String
6
+
7
+ PENDING: ::String
8
+
9
+ @identifier: Symbol
10
+
11
+ @resource: String
12
+
13
+ @model: untyped
14
+
15
+ attr_reader resource: untyped
16
+
17
+ attr_reader kind: untyped
18
+
19
+ # @rbs (model: untyped, resource: String, identifier: Symbol, kind: String) -> void
20
+ def initialize: (model: untyped, resource: String, identifier: Symbol, kind: String) -> void
21
+
22
+ # @rbs (String) -> DeadLetterScope
23
+ def self.for_kind: (String) -> DeadLetterScope
24
+
25
+ # @rbs (?authorization_context: untyped) -> Array[DeadRow]
26
+ def all: (?authorization_context: untyped) -> Array[DeadRow]
27
+
28
+ # @rbs (String, ?authorization_context: untyped) -> untyped
29
+ def retry: (String, ?authorization_context: untyped) -> untyped
30
+
31
+ # @rbs (?actor_type: String?, ?failed_after: untyped, ?limit: Integer?, ?authorization_context: untyped) -> RedriveTask
32
+ def redrive: (?actor_type: String?, ?failed_after: untyped, ?limit: Integer?, ?authorization_context: untyped) -> RedriveTask
33
+
34
+ # @rbs () -> ActiveRecord::Relation[untyped]
35
+ def dead: () -> ActiveRecord::Relation[untyped]
36
+
37
+ # @rbs (Hash[String, untyped], ?dead_before: untyped) -> ActiveRecord::Relation[untyped]
38
+ def matching: (Hash[String, untyped], ?dead_before: untyped) -> ActiveRecord::Relation[untyped]
39
+
40
+ # @rbs (Array[untyped]) -> Integer
41
+ def revive_all: (Array[untyped]) -> Integer
42
+
43
+ # @rbs (untyped) -> Integer
44
+ def revive: (untyped) -> Integer
45
+
46
+ # @rbs (Symbol, authorization_context: untyped, ?resource_id: String?) -> void
47
+ def authorize!: (Symbol, authorization_context: untyped, ?resource_id: String?) -> void
48
+
49
+ private
50
+
51
+ attr_reader model: untyped
52
+
53
+ attr_reader identifier: untyped
54
+
55
+ # @rbs () -> Hash[Symbol, untyped]
56
+ def revival_attributes: () -> Hash[Symbol, untyped]
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ # Generated from lib/solid_objects/dead_row.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ class DeadRow < Data
5
+ attr_reader id(): untyped
6
+
7
+ attr_reader kind(): untyped
8
+
9
+ attr_reader actor_type(): untyped
10
+
11
+ attr_reader actor_id(): untyped
12
+
13
+ attr_reader status(): untyped
14
+
15
+ attr_reader attempt_count(): untyped
16
+
17
+ attr_reader available_at(): untyped
18
+
19
+ attr_reader failed_at(): untyped
20
+
21
+ attr_reader error(): untyped
22
+
23
+ def self.new: (untyped id, untyped kind, untyped actor_type, untyped actor_id, untyped status, untyped attempt_count, untyped available_at, untyped failed_at, untyped error) -> instance
24
+ | (id: untyped, kind: untyped, actor_type: untyped, actor_id: untyped, status: untyped, attempt_count: untyped, available_at: untyped, failed_at: untyped, error: untyped) -> instance
25
+
26
+ def self.members: () -> [ :id, :kind, :actor_type, :actor_id, :status, :attempt_count, :available_at, :failed_at, :error ]
27
+
28
+ def members: () -> [ :id, :kind, :actor_type, :actor_id, :status, :attempt_count, :available_at, :failed_at, :error ]
29
+ end
30
+ end
@@ -75,6 +75,9 @@ module SolidObjects
75
75
  # @rbs () -> Check
76
76
  def check_database_server: () -> Check
77
77
 
78
+ # @rbs () -> Check
79
+ def check_wake_up: () -> Check
80
+
78
81
  # @rbs () -> Check
79
82
  def check_runtime: () -> Check
80
83
 
@@ -232,4 +232,12 @@ module SolidObjects
232
232
 
233
233
  class ActorCallCycle < Error
234
234
  end
235
+
236
+ class MessagePruned < Error
237
+ # @rbs @idempotency_key: String
238
+ attr_reader idempotency_key: untyped
239
+
240
+ # @rbs (String) -> void
241
+ def initialize: (String) -> void
242
+ end
235
243
  end
@@ -65,6 +65,12 @@ module SolidObjects
65
65
  # @rbs (Instance, Array[Actor::ReminderIntent]) -> Array[Hash[Symbol, untyped]]
66
66
  def schedule_reminders: (Instance, Array[Actor::ReminderIntent]) -> Array[Hash[Symbol, untyped]]
67
67
 
68
+ # A cancel reports nothing, because a reminder that no longer exists did not
69
+ # move. Deleting the row rather than marking it keeps a later schedule of the
70
+ # same name free of a tombstone.
71
+ # @rbs (Instance, Actor::UnscheduleIntent | Actor::UnscheduleAllIntent) -> nil
72
+ def cancel_reminder: (Instance, Actor::UnscheduleIntent | Actor::UnscheduleAllIntent) -> nil
73
+
68
74
  # Arguments are omitted deliberately: a reminder carries application data
69
75
  # and this event exists to be logged.
70
76
  # @rbs (Reminder, Time?) -> Hash[Symbol, untyped]?
@@ -88,6 +94,9 @@ module SolidObjects
88
94
  # @rbs () -> ClaimedMessage
89
95
  def matching_claim!: () -> ClaimedMessage
90
96
 
97
+ # @rbs (Instance, Message) -> Array[Hash[String, untyped]]
98
+ def remembered_keys: (Instance, Message) -> Array[Hash[String, untyped]]
99
+
91
100
  # @rbs (Exception) -> Hash[String, untyped]
92
101
  def serialized_error: (Exception) -> Hash[String, untyped]
93
102
 
@@ -34,7 +34,15 @@ module SolidObjects
34
34
  # @rbs () -> untyped
35
35
  def result: () -> untyped
36
36
 
37
+ # @rbs () -> Outcome
38
+ def outcome: () -> Outcome
39
+
37
40
  # @rbs (?timeout: Numeric, ?authorization_context: untyped) -> untyped
38
41
  def wait: (?timeout: Numeric, ?authorization_context: untyped) -> untyped
42
+
43
+ private
44
+
45
+ # @rbs (Message) -> String
46
+ def status_of: (Message) -> String
39
47
  end
40
48
  end