solid_objects 0.2.0 → 0.3.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +223 -15
  4. data/benchmark/adoption_latency.rb +5 -0
  5. data/benchmark/support.rb +35 -0
  6. data/docs/architecture.md +62 -15
  7. data/docs/authorization.md +98 -0
  8. data/docs/benchmarks.md +75 -1
  9. data/docs/correctness.md +19 -1
  10. data/docs/database-schema.md +5 -0
  11. data/docs/development.md +45 -4
  12. data/docs/fit.md +98 -0
  13. data/docs/migrating-existing-state.md +140 -0
  14. data/docs/operations.md +94 -4
  15. data/docs/roadmap.md +12 -3
  16. data/docs/security.md +28 -3
  17. data/docs/state-migrations.md +6 -0
  18. data/lib/generators/solid_objects/templates/solid_objects.rb +45 -0
  19. data/lib/solid_objects/activation.rb +33 -4
  20. data/lib/solid_objects/actor.rb +47 -6
  21. data/lib/solid_objects/actor_definition.rb +2 -0
  22. data/lib/solid_objects/actor_snapshot.rb +10 -4
  23. data/lib/solid_objects/application_write_guard.rb +24 -0
  24. data/lib/solid_objects/caller_process.rb +28 -0
  25. data/lib/solid_objects/cli.rb +44 -5
  26. data/lib/solid_objects/client.rb +98 -5
  27. data/lib/solid_objects/commit_action_registry.rb +42 -0
  28. data/lib/solid_objects/configuration.rb +27 -1
  29. data/lib/solid_objects/database_adapter.rb +28 -1
  30. data/lib/solid_objects/database_adapters/mysql.rb +46 -0
  31. data/lib/solid_objects/database_adapters/postgresql.rb +29 -0
  32. data/lib/solid_objects/database_adapters/sqlite.rb +28 -0
  33. data/lib/solid_objects/doctor.rb +311 -0
  34. data/lib/solid_objects/errors.rb +144 -0
  35. data/lib/solid_objects/executor.rb +64 -4
  36. data/lib/solid_objects/instance_pruner.rb +97 -0
  37. data/lib/solid_objects/message_pruner.rb +97 -0
  38. data/lib/solid_objects/message_reference.rb +9 -0
  39. data/lib/solid_objects/process_pruner.rb +49 -0
  40. data/lib/solid_objects/reference.rb +5 -0
  41. data/lib/solid_objects/state_snapshot.rb +41 -0
  42. data/lib/solid_objects/sync_deadline.rb +57 -0
  43. data/lib/solid_objects/sync_diagnostics.rb +133 -0
  44. data/lib/solid_objects/synchronous_invocation.rb +26 -7
  45. data/lib/solid_objects/test_helper.rb +78 -0
  46. data/lib/solid_objects/version.rb +1 -1
  47. data/lib/solid_objects/worker.rb +1 -1
  48. data/lib/solid_objects.rb +34 -0
  49. data/lib/tasks/solid_objects_tasks.rake +10 -0
  50. data/sig/generated/lib/solid_objects/activation.rbs +3 -0
  51. data/sig/generated/lib/solid_objects/actor.rbs +26 -0
  52. data/sig/generated/lib/solid_objects/application_write_guard.rbs +8 -0
  53. data/sig/generated/lib/solid_objects/caller_process.rbs +11 -0
  54. data/sig/generated/lib/solid_objects/cli.rbs +11 -2
  55. data/sig/generated/lib/solid_objects/client.rbs +15 -0
  56. data/sig/generated/lib/solid_objects/commit_action_registry.rbs +43 -0
  57. data/sig/generated/lib/solid_objects/configuration.rbs +27 -7
  58. data/sig/generated/lib/solid_objects/database_adapter.rbs +9 -0
  59. data/sig/generated/lib/solid_objects/database_adapters/mysql.rbs +8 -0
  60. data/sig/generated/lib/solid_objects/database_adapters/postgresql.rbs +8 -0
  61. data/sig/generated/lib/solid_objects/database_adapters/sqlite.rbs +8 -0
  62. data/sig/generated/lib/solid_objects/doctor.rbs +111 -0
  63. data/sig/generated/lib/solid_objects/errors.rbs +118 -0
  64. data/sig/generated/lib/solid_objects/executor.rbs +12 -0
  65. data/sig/generated/lib/solid_objects/instance_pruner.rbs +36 -0
  66. data/sig/generated/lib/solid_objects/message_pruner.rbs +42 -0
  67. data/sig/generated/lib/solid_objects/message_reference.rbs +3 -0
  68. data/sig/generated/lib/solid_objects/process_pruner.rbs +27 -0
  69. data/sig/generated/lib/solid_objects/reference.rbs +3 -0
  70. data/sig/generated/lib/solid_objects/state_snapshot.rbs +30 -0
  71. data/sig/generated/lib/solid_objects/sync_deadline.rbs +31 -0
  72. data/sig/generated/lib/solid_objects/sync_diagnostics.rbs +34 -0
  73. data/sig/generated/lib/solid_objects/synchronous_invocation.rbs +3 -0
  74. data/sig/generated/lib/solid_objects/test_helper.rbs +25 -0
  75. data/sig/generated/lib/solid_objects.rbs +12 -0
  76. metadata +26 -1
@@ -0,0 +1,133 @@
1
+ # rbs_inline: enabled
2
+
3
+ module SolidObjects
4
+ class SyncDiagnostics
5
+ # @rbs (Message, timeout: Numeric) -> SyncTimeout
6
+ def call(message, timeout:)
7
+ message = Message.uncached { Message.find(message.id) }
8
+ instance = Instance.uncached { Instance.find(message.instance_id) }
9
+ blocker = earlier_blocker(message)
10
+ status = message_status(message)
11
+ waiting_on = waiting_reason(message, instance, blocker)
12
+ activation = activation_details(instance)
13
+ error = SyncTimeout.new(
14
+ timeout:,
15
+ actor_type: message.actor_type,
16
+ actor_id: message.actor_id,
17
+ message_name: message.message_name,
18
+ message_id: message.id,
19
+ request_id: message.request_id,
20
+ sequence: message.sequence,
21
+ status:,
22
+ waiting_on:,
23
+ activation:,
24
+ blocker: blocker_details(blocker)
25
+ )
26
+ SolidObjects.instrument(
27
+ :"sync.timeout",
28
+ message_id: message.id,
29
+ request_id: message.request_id,
30
+ actor_type: message.actor_type,
31
+ actor_id: message.actor_id,
32
+ sequence: message.sequence,
33
+ status:,
34
+ waiting_on:,
35
+ activation_owner_id: activation["owner_id"],
36
+ activation_generation: activation["generation"]
37
+ )
38
+ error
39
+ end
40
+
41
+ private
42
+
43
+ # @rbs (Message) -> String
44
+ def message_status(message)
45
+ return "rejected" if message.rejected?
46
+ return "completed" if message.completed?
47
+ return "dead" if message.dead?
48
+ return "claimed" if ClaimedMessage.where(message_id: message.id).exists?
49
+ return "ready" if ReadyMessage.where(message_id: message.id).exists?
50
+
51
+ "unknown"
52
+ end
53
+
54
+ # @rbs (Message, Instance, Message?) -> String
55
+ def waiting_reason(message, instance, blocker)
56
+ return "actor_paused" if instance.paused_at
57
+ return "activation_held" if live_activation?(instance)
58
+ return "earlier_message" if blocker
59
+ return "message_claimed" if ClaimedMessage.where(message_id: message.id).exists?
60
+
61
+ ready_message = ReadyMessage.find_by(message_id: message.id)
62
+ return "not_yet_available" if future?(ready_message)
63
+ return "ready_unclaimed" if ready_message
64
+
65
+ "unknown"
66
+ end
67
+
68
+ # @rbs (ReadyMessage?) -> bool
69
+ def future?(ready_message)
70
+ ready_message&.available_at.present? &&
71
+ ready_message.available_at > SolidObjects.database_adapter.database_now
72
+ end
73
+
74
+ # @rbs (Instance) -> bool
75
+ def live_activation?(instance)
76
+ instance.activation_owner_id.present? &&
77
+ instance.activation_expires_at.present? &&
78
+ instance.activation_expires_at > SolidObjects.database_adapter.database_now
79
+ end
80
+
81
+ # @rbs (Message) -> Message?
82
+ def earlier_blocker(message)
83
+ ready = Message
84
+ .joins(:ready_message)
85
+ .where(instance_id: message.instance_id, sequence: ...message.sequence)
86
+ .order(:sequence)
87
+ .first
88
+ claimed = Message
89
+ .joins(:claimed_message)
90
+ .where(instance_id: message.instance_id, sequence: ...message.sequence)
91
+ .order(:sequence)
92
+ .first
93
+
94
+ [ ready, claimed ].compact.min_by(&:sequence)
95
+ end
96
+
97
+ # @rbs (Instance) -> Hash[String, untyped]
98
+ def activation_details(instance)
99
+ process_record = Process.find_by(id: instance.activation_owner_id)
100
+ {
101
+ "owner_id" => instance.activation_owner_id,
102
+ "generation" => instance.activation_generation,
103
+ "expires_at" => instance.activation_expires_at&.iso8601(6),
104
+ "process" => process_details(process_record)
105
+ }
106
+ end
107
+
108
+ # @rbs (Process?) -> Hash[String, untyped]?
109
+ def process_details(process_record)
110
+ return unless process_record
111
+
112
+ {
113
+ "kind" => process_record.kind,
114
+ "hostname" => process_record.hostname,
115
+ "pid" => process_record.pid,
116
+ "last_heartbeat_at" => process_record.last_heartbeat_at&.iso8601(6),
117
+ "shutdown_state" => process_record.shutdown_state
118
+ }
119
+ end
120
+
121
+ # @rbs (Message?) -> Hash[String, untyped]?
122
+ def blocker_details(blocker)
123
+ return unless blocker
124
+
125
+ {
126
+ "message_id" => blocker.id,
127
+ "sequence" => blocker.sequence,
128
+ "message_name" => blocker.message_name,
129
+ "status" => message_status(blocker)
130
+ }
131
+ end
132
+ end
133
+ end
@@ -2,12 +2,26 @@
2
2
 
3
3
  require "solid_objects/activation_manager"
4
4
  require "solid_objects/lease_renewer"
5
+ require "solid_objects/sync_diagnostics"
5
6
 
6
7
  module SolidObjects
7
8
  class SynchronousInvocation
8
9
  # @rbs (MessageReference, timeout: Numeric) -> untyped
9
10
  def call(message_reference, timeout:)
10
- deadline = monotonic_now + timeout.to_f
11
+ return call_before_deadline(message_reference, timeout:) if SyncDeadline.active?
12
+
13
+ SyncDeadline.with(timeout:) do
14
+ call_before_deadline(message_reference, timeout:)
15
+ end
16
+ rescue ActiveRecord::RecordNotFound
17
+ raise ActorDestroyed, "actor was destroyed while waiting for its result"
18
+ end
19
+
20
+ private
21
+
22
+ # @rbs (MessageReference, timeout: Numeric) -> untyped
23
+ def call_before_deadline(message_reference, timeout:)
24
+ deadline = monotonic_now + SyncDeadline.remaining
11
25
 
12
26
  loop do
13
27
  message = load_message(message_reference)
@@ -15,17 +29,22 @@ module SolidObjects
15
29
 
16
30
  remaining = deadline - monotonic_now
17
31
  unless remaining.positive?
18
- raise SyncTimeout, "actor invocation timed out after #{timeout} seconds"
32
+ message = load_message(message_reference)
33
+ return completed_result(message) if message.completed? || message.dead?
34
+
35
+ raise SyncDiagnostics.new.call(message, timeout:)
19
36
  end
20
37
 
21
38
  processed = assist(message, deadline:)
22
- wait(remaining) if processed.zero?
39
+ remaining = deadline - monotonic_now
40
+ wait(remaining) if processed.zero? && remaining.positive?
23
41
  end
24
- rescue ActiveRecord::RecordNotFound
25
- raise ActorDestroyed, "actor was destroyed while waiting for its result"
26
- end
42
+ rescue DatabaseDeadlineExceeded
43
+ message = load_message(message_reference)
44
+ return completed_result(message) if message.completed? || message.dead?
27
45
 
28
- private
46
+ raise SyncDiagnostics.new.call(message, timeout:)
47
+ end
29
48
 
30
49
  # @rbs (MessageReference) -> Message
31
50
  def load_message(message_reference)
@@ -0,0 +1,78 @@
1
+ # rbs_inline: enabled
2
+
3
+ require "solid_objects"
4
+
5
+ module SolidObjects
6
+ module TestHelper
7
+ class << self
8
+ # @rbs (Class) -> void
9
+ def included(test_case)
10
+ test_case.use_transactional_tests = false if test_case.respond_to?(:use_transactional_tests=)
11
+ test_case.setup { reset_actors! }
12
+ test_case.teardown { reset_actors! }
13
+ end
14
+
15
+ # @rbs () -> void
16
+ def reset_actors!
17
+ SolidObjects.reset_caller_process!
18
+ Instance.delete_all
19
+ Process.delete_all
20
+ end
21
+ end
22
+
23
+ # @rbs () -> void
24
+ def reset_actors!
25
+ TestHelper.reset_actors!
26
+ end
27
+
28
+ # @rbs (?roles: Array[Symbol], ?max_passes: Integer) -> Integer
29
+ def drain_solid_objects(
30
+ roles: [ :reminders, :actors, :effects, :broadcasts ],
31
+ max_passes: 1_000
32
+ )
33
+ runners = build_solid_objects_runners(roles)
34
+ total = 0
35
+
36
+ max_passes.times do
37
+ processed = runners.sum { |runner| solid_objects_runner_result(runner) }
38
+ break if processed.zero?
39
+
40
+ total += processed
41
+ end
42
+
43
+ total
44
+ ensure
45
+ runners&.uniq&.each(&:stop)
46
+ end
47
+
48
+ private
49
+
50
+ # @rbs (Array[Symbol]) -> Array[Worker | EffectExecutor | ReminderScheduler | BroadcastExecutor]
51
+ def build_solid_objects_runners(roles)
52
+ unknown_roles = roles - [ :actors, :effects, :reminders, :broadcasts ]
53
+ raise ArgumentError, "unknown Solid Objects test roles: #{unknown_roles.join(", ")}" if unknown_roles.any?
54
+
55
+ runners = {}
56
+ runners[:actors] = Worker.new if roles.include?(:actors)
57
+ runners[:effects] = EffectExecutor.new if roles.include?(:effects)
58
+ runners[:reminders] = ReminderScheduler.new if roles.include?(:reminders)
59
+ runners[:broadcasts] = BroadcastExecutor.new if roles.include?(:broadcasts)
60
+
61
+ [
62
+ runners[:reminders],
63
+ runners[:actors],
64
+ runners[:effects],
65
+ runners[:actors],
66
+ runners[:broadcasts]
67
+ ].compact
68
+ end
69
+
70
+ # @rbs (Worker | EffectExecutor | ReminderScheduler | BroadcastExecutor) -> Integer
71
+ def solid_objects_runner_result(runner)
72
+ result = runner.run_once
73
+ return result if result.is_a?(Integer)
74
+
75
+ result ? 1 : 0
76
+ end
77
+ end
78
+ end
@@ -1,5 +1,5 @@
1
1
  # rbs_inline: enabled
2
2
 
3
3
  module SolidObjects
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -43,7 +43,7 @@ module SolidObjects
43
43
  rescue ActorDestroyed
44
44
  release_activation(activation) if activation
45
45
  0
46
- rescue StateMigrationError, LostActivation => error
46
+ rescue StateMigrationError, ApplicationWriteForbidden, LostActivation => error
47
47
  release_activation(activation) if activation
48
48
  SolidObjects.configuration.logger.error(
49
49
  event: "solid_objects.worker.error",
data/lib/solid_objects.rb CHANGED
@@ -12,6 +12,7 @@ require "securerandom"
12
12
 
13
13
  require "solid_objects/version"
14
14
  require "solid_objects/errors"
15
+ require "solid_objects/sync_deadline"
15
16
  require "solid_objects/configuration"
16
17
  require "solid_objects/instrumentation"
17
18
  require "solid_objects/log_subscriber"
@@ -20,19 +21,25 @@ require "solid_objects/context"
20
21
  require "solid_objects/actor_registry"
21
22
  require "solid_objects/state"
22
23
  require "solid_objects/actor_definition"
24
+ require "solid_objects/application_write_guard"
23
25
  require "solid_objects/actor"
24
26
  require "solid_objects/reference"
25
27
  require "solid_objects/message_reference"
26
28
  require "solid_objects/dead_letter_manager"
29
+ require "solid_objects/message_pruner"
30
+ require "solid_objects/instance_pruner"
31
+ require "solid_objects/process_pruner"
27
32
  require "solid_objects/stream_name"
28
33
  require "solid_objects/dom_identity"
29
34
  require "solid_objects/stream_token"
30
35
  require "solid_objects/turbo_stream_renderer"
31
36
  require "solid_objects/actor_snapshot"
37
+ require "solid_objects/state_snapshot"
32
38
  require "solid_objects/actor_view"
33
39
  require "solid_objects/action_cable_broadcast_adapter"
34
40
  require "solid_objects/wake_up"
35
41
  require "solid_objects/effect_registry"
42
+ require "solid_objects/commit_action_registry"
36
43
  require "solid_objects/lease"
37
44
  require "solid_objects/lease_renewer"
38
45
  require "solid_objects/worker"
@@ -72,6 +79,16 @@ module SolidObjects
72
79
  effect_registry.register(name, handler)
73
80
  end
74
81
 
82
+ # @rbs () -> CommitActionRegistry
83
+ def commit_action_registry
84
+ @commit_action_registry ||= CommitActionRegistry.new
85
+ end
86
+
87
+ # @rbs (String | Symbol) { (Hash[String, untyped], CommitActionContext) -> untyped } -> Proc
88
+ def register_commit_action(name, &handler)
89
+ commit_action_registry.register(name, handler)
90
+ end
91
+
75
92
  # @rbs () -> Client
76
93
  def client
77
94
  require "solid_objects/client"
@@ -84,6 +101,17 @@ module SolidObjects
84
101
  @caller_process ||= CallerProcess.new
85
102
  end
86
103
 
104
+ # @rbs () -> bool
105
+ def reset_caller_process!
106
+ caller_process = @caller_process
107
+ @caller_process = nil
108
+ return false unless caller_process
109
+
110
+ caller_process.stop
111
+ rescue ActiveRecord::ActiveRecordError
112
+ false
113
+ end
114
+
87
115
  # @rbs () -> DeadLetterManager
88
116
  def dead_letters
89
117
  @dead_letters ||= DeadLetterManager.new
@@ -99,6 +127,11 @@ module SolidObjects
99
127
  registry.register(type, actor_class)
100
128
  end
101
129
 
130
+ # @rbs (untyped) -> untyped
131
+ def mutable_copy(value)
132
+ Serialization.deep_copy(value)
133
+ end
134
+
102
135
  # @rbs () -> void
103
136
  def reset!
104
137
  @configuration = Configuration.new
@@ -108,6 +141,7 @@ module SolidObjects
108
141
  @wake_up = nil
109
142
  @caller_process = nil
110
143
  @effect_registry = EffectRegistry.new
144
+ @commit_action_registry = CommitActionRegistry.new
111
145
  @dead_letters = nil
112
146
  end
113
147
 
@@ -0,0 +1,10 @@
1
+ require "solid_objects/doctor"
2
+
3
+ namespace :solid_objects do
4
+ desc "Verify the Solid Objects installation"
5
+ task doctor: :environment do
6
+ report = SolidObjects::Doctor.new.call
7
+ puts report
8
+ abort "Solid Objects doctor failed" unless report.healthy?
9
+ end
10
+ end
@@ -59,6 +59,9 @@ module SolidObjects
59
59
  # @rbs (Instance) -> Actor
60
60
  def build_actor: (Instance) -> Actor
61
61
 
62
+ # @rbs () -> void
63
+ def release_lease: () -> void
64
+
62
65
  # @rbs () -> Message?
63
66
  def claim_next_message: () -> Message?
64
67
 
@@ -19,6 +19,19 @@ module SolidObjects
19
19
  def members: () -> [ :name, :arguments, :success_message_name, :failure_message_name ]
20
20
  end
21
21
 
22
+ class CommitActionIntent < Data
23
+ attr_reader name(): untyped
24
+
25
+ attr_reader arguments(): untyped
26
+
27
+ def self.new: (untyped name, untyped arguments) -> instance
28
+ | (name: untyped, arguments: untyped) -> instance
29
+
30
+ def self.members: () -> [ :name, :arguments ]
31
+
32
+ def members: () -> [ :name, :arguments ]
33
+ end
34
+
22
35
  class ReminderIntent < Data
23
36
  attr_reader name(): untyped
24
37
 
@@ -114,6 +127,8 @@ module SolidObjects
114
127
 
115
128
  @reminder_intents: Array[ReminderIntent]
116
129
 
130
+ @commit_action_intents: Array[CommitActionIntent]
131
+
117
132
  @effect_intents: Array[EffectIntent]
118
133
 
119
134
  @state: State
@@ -136,6 +151,9 @@ module SolidObjects
136
151
  # @rbs (Symbol | String, ?on_success: Symbol | String?, ?on_failure: Symbol | String?, **untyped) -> nil
137
152
  def emit: (Symbol | String, ?on_success: Symbol | String?, ?on_failure: Symbol | String?, **untyped) -> nil
138
153
 
154
+ # @rbs (Symbol | String, **untyped) -> nil
155
+ def commit_action: (Symbol | String, **untyped) -> nil
156
+
139
157
  # @rbs (Symbol | String, at: Time, ?every: Numeric?, ?missed: Symbol | String, arguments: Hash[Symbol | String, untyped]) -> nil
140
158
  def schedule: (Symbol | String, at: Time, arguments: Hash[Symbol | String, untyped], ?every: Numeric?, ?missed: Symbol | String) -> nil
141
159
 
@@ -160,6 +178,9 @@ module SolidObjects
160
178
  # @rbs () -> Array[EffectIntent]
161
179
  def drain_effect_intents: () -> Array[EffectIntent]
162
180
 
181
+ # @rbs () -> Array[CommitActionIntent]
182
+ def drain_commit_action_intents: () -> Array[CommitActionIntent]
183
+
163
184
  # @rbs () -> Array[ReminderIntent]
164
185
  def drain_reminder_intents: () -> Array[ReminderIntent]
165
186
 
@@ -173,10 +194,15 @@ module SolidObjects
173
194
 
174
195
  attr_reader effect_intents: untyped
175
196
 
197
+ attr_reader commit_action_intents: untyped
198
+
176
199
  attr_reader reminder_intents: untyped
177
200
 
178
201
  attr_reader outbound_message_intents: untyped
179
202
 
203
+ # @rbs (String) { () -> untyped } -> untyped
204
+ def guard_application_writes: (String) { () -> untyped } -> untyped
205
+
180
206
  # @rbs (Hash[String, untyped]) -> Hash[Symbol, untyped]
181
207
  def keyword_arguments: (Hash[String, untyped]) -> Hash[Symbol, untyped]
182
208
 
@@ -0,0 +1,8 @@
1
+ # Generated from lib/solid_objects/application_write_guard.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ class ApplicationWriteGuard
5
+ # @rbs (actor_type: String, actor_id: String, operation: String) { () -> untyped } -> untyped
6
+ def self.call: (actor_type: String, actor_id: String, operation: String) { () -> untyped } -> untyped
7
+ end
8
+ end
@@ -8,12 +8,17 @@ module SolidObjects
8
8
 
9
9
  @registry: ProcessRegistry?
10
10
 
11
+ @shutdown_hook_installed: bool
12
+
11
13
  # @rbs () -> void
12
14
  def initialize: () -> void
13
15
 
14
16
  # @rbs () -> ProcessRegistry
15
17
  def process_registry: () -> ProcessRegistry
16
18
 
19
+ # @rbs () -> bool
20
+ def stop: () -> bool
21
+
17
22
  private
18
23
 
19
24
  attr_reader mutex: untyped
@@ -28,5 +33,11 @@ module SolidObjects
28
33
 
29
34
  # @rbs () -> ProcessRegistry
30
35
  def register: () -> ProcessRegistry
36
+
37
+ # @rbs () -> void
38
+ def install_shutdown_hook: () -> void
39
+
40
+ # @rbs () -> bool
41
+ def stop_after_exit: () -> bool
31
42
  end
32
43
  end
@@ -11,6 +11,15 @@ module SolidObjects
11
11
  # @rbs () -> void
12
12
  def cleanup: () -> void
13
13
 
14
+ # @rbs () -> void
15
+ def prune_messages: () -> void
16
+
17
+ # @rbs () -> void
18
+ def prune_instances: () -> void
19
+
20
+ # @rbs () -> void
21
+ def prune_processes: () -> void
22
+
14
23
  # @rbs () -> void
15
24
  def dead_letters: () -> void
16
25
 
@@ -25,7 +34,7 @@ module SolidObjects
25
34
  # @rbs (Symbol, Integer) -> Integer
26
35
  def numeric_option: (Symbol, Integer) -> Integer
27
36
 
28
- # @rbs (Symbol) -> void
29
- def authorize_administration!: (Symbol) -> void
37
+ # @rbs (Symbol, resource: String) -> void
38
+ def authorize_administration!: (Symbol, resource: String) -> void
30
39
  end
31
40
  end
@@ -13,6 +13,12 @@ module SolidObjects
13
13
  # @rbs (Reference, Symbol | String, Hash[Symbol | String, untyped], timeout: Numeric, ?idempotency_key: String?, ?authorization_context: untyped) -> untyped
14
14
  def sync: (Reference, Symbol | String, Hash[Symbol | String, untyped], timeout: Numeric, ?idempotency_key: String?, ?authorization_context: untyped) -> untyped
15
15
 
16
+ # @rbs (MessageReference, timeout: Numeric, ?authorization_context: untyped) -> untyped
17
+ def wait: (MessageReference, timeout: Numeric, ?authorization_context: untyped) -> untyped
18
+
19
+ # @rbs (Reference, ?authorization_context: untyped) -> StateSnapshot
20
+ def snapshot: (Reference, ?authorization_context: untyped) -> StateSnapshot
21
+
16
22
  # @rbs (Reference, ?authorization_context: untyped) -> bool
17
23
  def destroy: (Reference, ?authorization_context: untyped) -> bool
18
24
 
@@ -20,6 +26,15 @@ module SolidObjects
20
26
 
21
27
  attr_reader mailbox: untyped
22
28
 
29
+ # @rbs (Reference, Symbol | String, Hash[Symbol | String, untyped], idempotency_key: String?, timeout: Numeric) -> MessageReference
30
+ def enqueue_sync: (Reference, Symbol | String, Hash[Symbol | String, untyped], idempotency_key: String?, timeout: Numeric) -> MessageReference
31
+
32
+ # @rbs (MessageReference, Message) -> void
33
+ def validate_message_reference!: (MessageReference, Message) -> void
34
+
35
+ # @rbs (Reference, Symbol | String) -> void
36
+ def reject_sync_inside_transaction!: (Reference, Symbol | String) -> void
37
+
23
38
  # @rbs (Proc, Reference, Symbol | String, Hash[Symbol | String, untyped], authorization_context: untyped) -> void
24
39
  def authorize!: (Proc, Reference, Symbol | String, Hash[Symbol | String, untyped], authorization_context: untyped) -> void
25
40
 
@@ -0,0 +1,43 @@
1
+ # Generated from lib/solid_objects/commit_action_registry.rb with RBS::Inline
2
+
3
+ module SolidObjects
4
+ class CommitActionContext < Data
5
+ attr_reader message_id(): untyped
6
+
7
+ attr_reader request_id(): untyped
8
+
9
+ attr_reader actor_type(): untyped
10
+
11
+ attr_reader actor_id(): untyped
12
+
13
+ attr_reader activation_generation(): untyped
14
+
15
+ def self.new: (untyped message_id, untyped request_id, untyped actor_type, untyped actor_id, untyped activation_generation) -> instance
16
+ | (message_id: untyped, request_id: untyped, actor_type: untyped, actor_id: untyped, activation_generation: untyped) -> instance
17
+
18
+ def self.members: () -> [ :message_id, :request_id, :actor_type, :actor_id, :activation_generation ]
19
+
20
+ def members: () -> [ :message_id, :request_id, :actor_type, :actor_id, :activation_generation ]
21
+ end
22
+
23
+ class CommitActionRegistry
24
+ @handlers: Hash[String, Proc]
25
+
26
+ @mutex: Mutex
27
+
28
+ # @rbs () -> void
29
+ def initialize: () -> void
30
+
31
+ # @rbs (String | Symbol, Proc) -> Proc
32
+ def register: (String | Symbol, Proc) -> Proc
33
+
34
+ # @rbs (String | Symbol) -> Proc
35
+ def fetch: (String | Symbol) -> Proc
36
+
37
+ private
38
+
39
+ attr_reader handlers: untyped
40
+
41
+ attr_reader mutex: untyped
42
+ end
43
+ end
@@ -2,16 +2,22 @@
2
2
 
3
3
  module SolidObjects
4
4
  class Configuration
5
- @max_attempts: Integer
6
-
7
- @retry_delay: Proc
8
-
9
- @process_heartbeat_interval: Float
5
+ @table_name_prefix: String
10
6
 
11
7
  @process_alive_threshold: Float
12
8
 
13
9
  @shutdown_timeout: Float
14
10
 
11
+ @message_retention: Numeric
12
+
13
+ @message_retention_by_actor_type: Hash[String, Numeric]
14
+
15
+ @instance_retention_by_actor_type: Hash[String, Numeric]
16
+
17
+ @process_retention: Numeric
18
+
19
+ @prune_batch_size: Integer
20
+
15
21
  @worker_count: Integer
16
22
 
17
23
  @effect_worker_count: Integer
@@ -40,8 +46,6 @@ module SolidObjects
40
46
 
41
47
  @authorize_administration: Proc
42
48
 
43
- @table_name_prefix: String
44
-
45
49
  @polling_interval: Float
46
50
 
47
51
  @sync_polling_interval: Float
@@ -66,6 +70,12 @@ module SolidObjects
66
70
 
67
71
  @max_result_bytes: Integer
68
72
 
73
+ @max_attempts: Integer
74
+
75
+ @retry_delay: Proc
76
+
77
+ @process_heartbeat_interval: Float
78
+
69
79
  attr_accessor table_name_prefix: untyped
70
80
 
71
81
  attr_accessor polling_interval: untyped
@@ -102,6 +112,16 @@ module SolidObjects
102
112
 
103
113
  attr_accessor shutdown_timeout: untyped
104
114
 
115
+ attr_accessor message_retention: untyped
116
+
117
+ attr_accessor message_retention_by_actor_type: untyped
118
+
119
+ attr_accessor instance_retention_by_actor_type: untyped
120
+
121
+ attr_accessor process_retention: untyped
122
+
123
+ attr_accessor prune_batch_size: untyped
124
+
105
125
  attr_accessor worker_count: untyped
106
126
 
107
127
  attr_accessor effect_worker_count: untyped
@@ -36,6 +36,15 @@ module SolidObjects
36
36
 
37
37
  attr_reader fixed_connection: untyped
38
38
 
39
+ # @rbs (untyped) { () -> untyped } -> untyped
40
+ def with_transaction_deadline: (untyped) { () -> untyped } -> untyped
41
+
42
+ # @rbs (untyped) -> void
43
+ def configure_transaction_deadline: (untyped) -> void
44
+
45
+ # @rbs (Exception) -> bool
46
+ def deadline_error?: (Exception) -> bool
47
+
39
48
  # @rbs () { (untyped) -> untyped } -> untyped
40
49
  def with_connection: () { (untyped) -> untyped } -> untyped
41
50
  end