solid_objects 0.14.2 → 0.14.3
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 +53 -0
- data/README.md +121 -522
- data/benchmark/state_size.rb +5 -0
- data/benchmark/support.rb +63 -0
- data/docs/adr/0006-at-least-once-delivery.md +1 -1
- data/docs/architecture.md +7 -6
- data/docs/authorization.md +4 -4
- data/docs/benchmarks.md +48 -3
- data/docs/correctness.md +2 -2
- data/docs/fit.md +24 -7
- data/docs/local-testing.md +3 -3
- data/docs/migrating-existing-state.md +1 -1
- data/docs/operations.md +32 -4
- data/docs/realtime.md +2 -2
- data/docs/reminders.md +6 -6
- data/docs/research/solid_queue.md +1 -1
- data/docs/roadmap.md +9 -1
- data/lib/solid_objects/configuration.rb +7 -0
- data/lib/solid_objects/executor.rb +37 -16
- data/lib/solid_objects/instrumentation.rb +33 -0
- data/lib/solid_objects/serialization.rb +18 -5
- data/lib/solid_objects/version.rb +1 -1
- data/sig/generated/lib/solid_objects/configuration.rbs +7 -3
- data/sig/generated/lib/solid_objects/executor.rbs +7 -4
- data/sig/generated/lib/solid_objects/instrumentation.rbs +11 -0
- data/sig/generated/lib/solid_objects/serialization.rbs +16 -0
- metadata +3 -2
|
@@ -4,17 +4,26 @@ module SolidObjects
|
|
|
4
4
|
module Serialization
|
|
5
5
|
MAX_NESTING = 100
|
|
6
6
|
|
|
7
|
+
Dumped = Data.define(:value, :byte_size)
|
|
8
|
+
|
|
7
9
|
class << self
|
|
8
10
|
# @rbs (untyped, ?max_bytes: Integer?) -> untyped
|
|
9
11
|
def dump(value, max_bytes: nil)
|
|
12
|
+
return normalize(value) unless max_bytes
|
|
13
|
+
|
|
14
|
+
dump_with_byte_size(value, max_bytes:).value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @rbs (untyped, ?max_bytes: Integer?) -> Dumped
|
|
18
|
+
def dump_with_byte_size(value, max_bytes: nil)
|
|
10
19
|
normalized = normalize(value)
|
|
11
|
-
|
|
20
|
+
byte_size = JSON.generate(normalized, max_nesting: MAX_NESTING).bytesize
|
|
12
21
|
|
|
13
|
-
if max_bytes &&
|
|
22
|
+
if max_bytes && byte_size > max_bytes
|
|
14
23
|
raise PayloadTooLarge, "serialized value exceeds #{max_bytes} bytes"
|
|
15
24
|
end
|
|
16
25
|
|
|
17
|
-
normalized
|
|
26
|
+
Dumped.new(value: normalized, byte_size:)
|
|
18
27
|
rescue JSON::GeneratorError, EncodingError => error
|
|
19
28
|
raise InvalidPayload, error.message
|
|
20
29
|
end
|
|
@@ -60,7 +69,11 @@ module SolidObjects
|
|
|
60
69
|
raise InvalidPayload, "serialized value is nested too deeply" if depth > MAX_NESTING
|
|
61
70
|
|
|
62
71
|
case value
|
|
63
|
-
when nil, true, false,
|
|
72
|
+
when nil, true, false, Integer
|
|
73
|
+
value
|
|
74
|
+
when String
|
|
75
|
+
raise InvalidPayload, "strings must hold valid #{value.encoding} bytes" unless value.valid_encoding?
|
|
76
|
+
|
|
64
77
|
value
|
|
65
78
|
when Float
|
|
66
79
|
raise InvalidPayload, "non-finite numbers are not supported" unless value.finite?
|
|
@@ -89,7 +102,7 @@ module SolidObjects
|
|
|
89
102
|
|
|
90
103
|
# @rbs (untyped) -> String
|
|
91
104
|
def normalize_key(key)
|
|
92
|
-
return key if key.is_a?(String)
|
|
105
|
+
return normalize(key) if key.is_a?(String)
|
|
93
106
|
return key.to_s if key.is_a?(Symbol)
|
|
94
107
|
|
|
95
108
|
raise InvalidPayload, "JSON object keys must be strings or symbols"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module SolidObjects
|
|
4
4
|
class Configuration
|
|
5
|
-
@
|
|
5
|
+
@process_alive_threshold: Float
|
|
6
6
|
|
|
7
7
|
@shutdown_timeout: Float
|
|
8
8
|
|
|
@@ -60,6 +60,8 @@ module SolidObjects
|
|
|
60
60
|
|
|
61
61
|
@transmission_actor_type_resolver: Proc
|
|
62
62
|
|
|
63
|
+
@table_name_prefix: String
|
|
64
|
+
|
|
63
65
|
@polling_interval: Float
|
|
64
66
|
|
|
65
67
|
@idle_polling_interval: Float
|
|
@@ -84,6 +86,8 @@ module SolidObjects
|
|
|
84
86
|
|
|
85
87
|
@max_state_bytes: Integer
|
|
86
88
|
|
|
89
|
+
@warn_state_bytes: Integer
|
|
90
|
+
|
|
87
91
|
@max_result_bytes: Integer
|
|
88
92
|
|
|
89
93
|
@max_attempts: Integer
|
|
@@ -94,8 +98,6 @@ module SolidObjects
|
|
|
94
98
|
|
|
95
99
|
@process_heartbeat_interval: Float
|
|
96
100
|
|
|
97
|
-
@process_alive_threshold: Float
|
|
98
|
-
|
|
99
101
|
attr_accessor table_name_prefix: untyped
|
|
100
102
|
|
|
101
103
|
attr_accessor polling_interval: untyped
|
|
@@ -122,6 +124,8 @@ module SolidObjects
|
|
|
122
124
|
|
|
123
125
|
attr_accessor max_state_bytes: untyped
|
|
124
126
|
|
|
127
|
+
attr_accessor warn_state_bytes: untyped
|
|
128
|
+
|
|
125
129
|
attr_accessor max_result_bytes: untyped
|
|
126
130
|
|
|
127
131
|
attr_accessor max_attempts: untyped
|
|
@@ -24,14 +24,17 @@ module SolidObjects
|
|
|
24
24
|
# @rbs (MessageContext) -> untyped
|
|
25
25
|
def invoke_actor: (MessageContext) -> untyped
|
|
26
26
|
|
|
27
|
-
# @rbs (Hash[String, untyped]) -> void
|
|
28
|
-
def ensure_query_did_not_mutate_state!: (Hash[String, untyped]) -> void
|
|
27
|
+
# @rbs (Hash[String, untyped], Hash[String, untyped]) -> void
|
|
28
|
+
def ensure_query_did_not_mutate_state!: (Hash[String, untyped], Hash[String, untyped]) -> void
|
|
29
29
|
|
|
30
30
|
# @rbs (Hash[String, untyped], Hash[String, untyped]) -> Hash[String, untyped]
|
|
31
31
|
def changed_observables: (Hash[String, untyped], Hash[String, untyped]) -> Hash[String, untyped]
|
|
32
32
|
|
|
33
|
-
# @rbs (untyped, Hash[String, untyped], state_changed: bool) -> void
|
|
34
|
-
def complete: (untyped, Hash[String, untyped], state_changed: bool) -> void
|
|
33
|
+
# @rbs (untyped, Hash[String, untyped], state_after: Hash[String, untyped], state_changed: bool) -> void
|
|
34
|
+
def complete: (untyped, Hash[String, untyped], state_after: Hash[String, untyped], state_changed: bool) -> void
|
|
35
|
+
|
|
36
|
+
# @rbs (Integer) -> void
|
|
37
|
+
def report_large_state: (Integer) -> void
|
|
35
38
|
|
|
36
39
|
# @rbs (Array[Actor::CommitActionIntent]) -> void
|
|
37
40
|
def execute_commit_actions: (Array[Actor::CommitActionIntent]) -> void
|
|
@@ -4,5 +4,16 @@ module SolidObjects
|
|
|
4
4
|
module Instrumentation
|
|
5
5
|
# @rbs (Symbol, **untyped) { (Hash[Symbol, untyped]) -> untyped } -> untyped
|
|
6
6
|
def instrument: (Symbol, **untyped) { (Hash[Symbol, untyped]) -> untyped } -> untyped
|
|
7
|
+
|
|
8
|
+
# @rbs (Symbol, **untyped) -> void
|
|
9
|
+
def instrument_after_commit: (Symbol, **untyped) -> void
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# @rbs (Symbol, Exception) -> void
|
|
14
|
+
def report_instrumentation_failure: (Symbol, Exception) -> void
|
|
15
|
+
|
|
16
|
+
# @rbs (Symbol, Exception) -> void
|
|
17
|
+
def log_instrumentation_failure: (Symbol, Exception) -> void
|
|
7
18
|
end
|
|
8
19
|
end
|
|
@@ -4,9 +4,25 @@ module SolidObjects
|
|
|
4
4
|
module Serialization
|
|
5
5
|
MAX_NESTING: ::Integer
|
|
6
6
|
|
|
7
|
+
class Dumped < Data
|
|
8
|
+
attr_reader value(): untyped
|
|
9
|
+
|
|
10
|
+
attr_reader byte_size(): untyped
|
|
11
|
+
|
|
12
|
+
def self.new: (untyped value, untyped byte_size) -> instance
|
|
13
|
+
| (value: untyped, byte_size: untyped) -> instance
|
|
14
|
+
|
|
15
|
+
def self.members: () -> [ :value, :byte_size ]
|
|
16
|
+
|
|
17
|
+
def members: () -> [ :value, :byte_size ]
|
|
18
|
+
end
|
|
19
|
+
|
|
7
20
|
# @rbs (untyped, ?max_bytes: Integer?) -> untyped
|
|
8
21
|
def self.dump: (untyped, ?max_bytes: Integer?) -> untyped
|
|
9
22
|
|
|
23
|
+
# @rbs (untyped, ?max_bytes: Integer?) -> Dumped
|
|
24
|
+
def self.dump_with_byte_size: (untyped, ?max_bytes: Integer?) -> Dumped
|
|
25
|
+
|
|
10
26
|
# @rbs (untyped) -> untyped
|
|
11
27
|
def self.load: (untyped) -> untyped
|
|
12
28
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid_objects
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.14.
|
|
4
|
+
version: 0.14.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lucas Carlson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actioncable
|
|
@@ -323,6 +323,7 @@ files:
|
|
|
323
323
|
- benchmark/idle_polling.rb
|
|
324
324
|
- benchmark/processing.rb
|
|
325
325
|
- benchmark/query_count.rb
|
|
326
|
+
- benchmark/state_size.rb
|
|
326
327
|
- benchmark/support.rb
|
|
327
328
|
- benchmark/sync_latency.rb
|
|
328
329
|
- config/routes.rb
|