prosody 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.cargo/config.toml +3 -0
- data/.release-please-manifest.json +1 -1
- data/AGENTS.md +395 -0
- data/ARCHITECTURE.md +2 -2
- data/CHANGELOG.md +15 -0
- data/CLAUDE.md +1 -0
- data/CONFIGURATION.md +167 -0
- data/Cargo.lock +660 -326
- data/Cargo.toml +2 -1
- data/README.md +290 -191
- data/examples/keyed_state.rb +15 -3
- data/examples/keyed_state_windowing.rb +9 -1
- data/ext/prosody/Cargo.toml +2 -1
- data/ext/prosody/src/admin.rs +1 -5
- data/ext/prosody/src/bridge/mod.rs +17 -32
- data/ext/prosody/src/client/config.rs +194 -89
- data/ext/prosody/src/client/mod.rs +167 -74
- data/ext/prosody/src/client/request.rs +132 -0
- data/ext/prosody/src/client/support.rs +122 -0
- data/ext/prosody/src/handler/context.rs +24 -20
- data/ext/prosody/src/handler/message.rs +50 -0
- data/ext/prosody/src/handler/mod.rs +112 -84
- data/ext/prosody/src/handler/state/mod.rs +488 -0
- data/ext/prosody/src/handler/state/registration.rs +104 -0
- data/ext/prosody/src/handler/state/scan.rs +218 -0
- data/ext/prosody/src/lib.rs +15 -3
- data/ext/prosody/src/published.rs +273 -0
- data/ext/prosody/src/scheduler/mod.rs +2 -2
- data/ext/prosody/src/scheduler/processor.rs +2 -2
- data/ext/prosody/src/scheduler/result.rs +7 -4
- data/ext/prosody/src/util.rs +86 -5
- data/lib/prosody/configuration.rb +49 -15
- data/lib/prosody/handler.rb +63 -10
- data/lib/prosody/native_stubs.rb +197 -31
- data/lib/prosody/request.rb +45 -0
- data/lib/prosody/state.rb +164 -41
- data/lib/prosody/version.rb +1 -1
- data/lib/prosody.rb +1 -0
- data/sig/configuration.rbs +51 -15
- data/sig/handler.rbs +12 -4
- data/sig/prosody.rbs +43 -2
- data/sig/request.rbs +66 -0
- data/sig/state.rbs +165 -47
- data/steep_expectations.yml +10 -0
- data/typecheck/payload_types.rb +14 -3
- data/typecheck/payload_types.rbs +4 -2
- data/typecheck_negative/payload_types.rb +4 -0
- data/typecheck_negative/payload_types.rbs +1 -0
- metadata +12 -2
- data/ext/prosody/src/handler/state.rs +0 -1035
data/sig/state.rbs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module Prosody
|
|
2
|
+
type state_config_value = String | Integer | bool
|
|
3
|
+
|
|
2
4
|
# --- error taxonomy -----------------------------------------------------
|
|
3
5
|
# Raised for keyed-state failures a retry cannot resolve (unregistered
|
|
4
6
|
# collection, identity mismatch, duplicate registration, bad TTL). Never
|
|
@@ -17,6 +19,13 @@ module Prosody
|
|
|
17
19
|
class NullValueError < TransientStateError
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
class StateAccess < Data
|
|
23
|
+
attr_reader vend_method: Symbol
|
|
24
|
+
attr_reader wrapper: Symbol
|
|
25
|
+
attr_reader published_vend_method: Symbol?
|
|
26
|
+
attr_reader published_wrapper: Symbol?
|
|
27
|
+
end
|
|
28
|
+
|
|
20
29
|
# Concrete immutable definition object returned by the constructor helpers.
|
|
21
30
|
class StateDefinition < Data
|
|
22
31
|
attr_reader name: String
|
|
@@ -24,10 +33,13 @@ module Prosody
|
|
|
24
33
|
attr_reader payload: String
|
|
25
34
|
attr_reader ttl_seconds: Integer?
|
|
26
35
|
attr_reader read_uncommitted: bool?
|
|
36
|
+
attr_reader published: bool?
|
|
37
|
+
attr_reader read_cache: (Numeric | false)?
|
|
27
38
|
attr_reader keyset_limit: Integer?
|
|
28
39
|
attr_reader capacity: Integer?
|
|
40
|
+
attr_reader access: StateAccess
|
|
29
41
|
|
|
30
|
-
def to_state_config: () -> Hash[Symbol,
|
|
42
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
31
43
|
end
|
|
32
44
|
|
|
33
45
|
# --- definition interfaces (phantom-typed over the payload) --------------
|
|
@@ -37,51 +49,54 @@ module Prosody
|
|
|
37
49
|
def name: () -> String
|
|
38
50
|
def kind: () -> "value"
|
|
39
51
|
def payload: () -> "json"
|
|
40
|
-
def
|
|
52
|
+
def read_cache: () -> (Numeric | false)?
|
|
53
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
41
54
|
end
|
|
42
55
|
|
|
43
56
|
interface _MapDefinition[V = json_value]
|
|
44
57
|
def name: () -> String
|
|
45
58
|
def kind: () -> "map"
|
|
46
59
|
def payload: () -> "json"
|
|
47
|
-
def
|
|
60
|
+
def read_cache: () -> (Numeric | false)?
|
|
61
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
48
62
|
end
|
|
49
63
|
|
|
50
64
|
interface _DequeDefinition[T = json_value]
|
|
51
65
|
def name: () -> String
|
|
52
66
|
def kind: () -> "deque"
|
|
53
67
|
def payload: () -> "json"
|
|
54
|
-
def
|
|
68
|
+
def read_cache: () -> (Numeric | false)?
|
|
69
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
55
70
|
end
|
|
56
71
|
|
|
57
72
|
interface _MessageValueDefinition[P = json_value]
|
|
58
73
|
def name: () -> String
|
|
59
74
|
def kind: () -> "value"
|
|
60
75
|
def payload: () -> "message"
|
|
61
|
-
def to_state_config: () -> Hash[Symbol,
|
|
76
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
62
77
|
end
|
|
63
78
|
|
|
64
79
|
interface _MessageMapDefinition[P = json_value]
|
|
65
80
|
def name: () -> String
|
|
66
81
|
def kind: () -> "map"
|
|
67
82
|
def payload: () -> "message"
|
|
68
|
-
def to_state_config: () -> Hash[Symbol,
|
|
83
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
69
84
|
end
|
|
70
85
|
|
|
71
86
|
interface _MessageDequeDefinition[P = json_value]
|
|
72
87
|
def name: () -> String
|
|
73
88
|
def kind: () -> "deque"
|
|
74
89
|
def payload: () -> "message"
|
|
75
|
-
def to_state_config: () -> Hash[Symbol,
|
|
90
|
+
def to_state_config: () -> Hash[Symbol, state_config_value]
|
|
76
91
|
end
|
|
77
92
|
|
|
78
93
|
# --- definition constructors --------------------------------------------
|
|
79
94
|
# The `message_*` siblings return the same structural definition interfaces as
|
|
80
95
|
# their JSON counterparts (the runtime object is one StateDefinition); the
|
|
81
96
|
# `[P]` type parameter is annotation-only, naming the message payload type.
|
|
82
|
-
def self.value: [T] (_ToS name, ?ttl: Integer?, ?read_uncommitted: bool?) -> _ValueDefinition[T]
|
|
83
|
-
def self.map: [V] (_ToS name, ?ttl: Integer?, ?keyset_limit: Integer?, ?read_uncommitted: bool?) -> _MapDefinition[V]
|
|
84
|
-
def self.deque: [T] (_ToS name, ?ttl: Integer?, ?capacity: Integer?, ?read_uncommitted: bool?) -> _DequeDefinition[T]
|
|
97
|
+
def self.value: [T] (_ToS name, ?ttl: Integer?, ?read_uncommitted: bool?, ?published: bool?, ?read_cache: (Numeric | false)?) -> _ValueDefinition[T]
|
|
98
|
+
def self.map: [V] (_ToS name, ?ttl: Integer?, ?keyset_limit: Integer?, ?read_uncommitted: bool?, ?published: bool?, ?read_cache: (Numeric | false)?) -> _MapDefinition[V]
|
|
99
|
+
def self.deque: [T] (_ToS name, ?ttl: Integer?, ?capacity: Integer?, ?read_uncommitted: bool?, ?published: bool?, ?read_cache: (Numeric | false)?) -> _DequeDefinition[T]
|
|
85
100
|
def self.message_value: [P] (_ToS name, ?ttl: Integer?, ?read_uncommitted: bool?) -> _MessageValueDefinition[P]
|
|
86
101
|
def self.message_map: [P] (_ToS name, ?ttl: Integer?, ?keyset_limit: Integer?, ?read_uncommitted: bool?) -> _MessageMapDefinition[P]
|
|
87
102
|
def self.message_deque: [P] (_ToS name, ?ttl: Integer?, ?capacity: Integer?, ?read_uncommitted: bool?) -> _MessageDequeDefinition[P]
|
|
@@ -101,7 +116,7 @@ module Prosody
|
|
|
101
116
|
def value=: (T value) -> T # alias of #set (assignment yields value)
|
|
102
117
|
|
|
103
118
|
private
|
|
104
|
-
def initialize: (
|
|
119
|
+
def initialize: ((NativeJsonValueState | NativeMessageValueState) native) -> void
|
|
105
120
|
end
|
|
106
121
|
|
|
107
122
|
# A String-keyed ordered-map keyed-state handle.
|
|
@@ -123,6 +138,10 @@ module Prosody
|
|
|
123
138
|
| () -> Enumerator[String, void]
|
|
124
139
|
def reverse_each_key: () { (String) -> void } -> void
|
|
125
140
|
| () -> Enumerator[String, void]
|
|
141
|
+
def each_value: () { (V) -> void } -> void
|
|
142
|
+
| () -> Enumerator[V, void]
|
|
143
|
+
def reverse_each_value: () { (V) -> void } -> void
|
|
144
|
+
| () -> Enumerator[V, void]
|
|
126
145
|
|
|
127
146
|
# idiomatic Hash-style conveniences (bounded reads only)
|
|
128
147
|
def []: (String key) -> V? # alias of #get
|
|
@@ -144,7 +163,7 @@ module Prosody
|
|
|
144
163
|
| [R] (*String keys) { (String) -> R } -> Array[V | R]
|
|
145
164
|
|
|
146
165
|
private
|
|
147
|
-
def initialize: (
|
|
166
|
+
def initialize: ((NativeJsonMapState | NativeMessageMapState) native) -> void
|
|
148
167
|
def traverse: (Symbol direction) { (String, V) -> void } -> void
|
|
149
168
|
| (Symbol direction) -> Enumerator[[ String, V ], void]
|
|
150
169
|
def traverse_keys: (Symbol direction) { (String) -> void } -> void
|
|
@@ -185,62 +204,160 @@ module Prosody
|
|
|
185
204
|
| [R] (Integer index) { (Integer) -> R } -> (T | R)
|
|
186
205
|
|
|
187
206
|
private
|
|
188
|
-
def initialize: (
|
|
207
|
+
def initialize: ((NativeJsonDequeState | NativeMessageDequeState) native) -> void
|
|
189
208
|
def at_negative: (Integer index) -> T?
|
|
190
209
|
def traverse: (Symbol direction) { (T) -> void } -> void
|
|
191
210
|
| (Symbol direction) -> Enumerator[T, void]
|
|
192
211
|
end
|
|
193
212
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def
|
|
197
|
-
def set: (untyped value) -> void
|
|
213
|
+
interface _NativeValueHandle[T]
|
|
214
|
+
def get: () -> T?
|
|
215
|
+
def set: (T value) -> void
|
|
198
216
|
def clear: () -> void
|
|
199
217
|
def commit: () -> nil
|
|
200
218
|
def rollback: () -> nil
|
|
201
219
|
end
|
|
202
220
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
221
|
+
class NativeJsonValueState
|
|
222
|
+
include _NativeValueHandle[json_value]
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
class NativeMessageValueState
|
|
226
|
+
include _NativeValueHandle[Message[json_value]]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
interface _NativeMapHandle[V, S]
|
|
230
|
+
def get: (String key) -> V?
|
|
206
231
|
def contains_key: (String key) -> bool
|
|
207
|
-
def get_many: (Array[String] keys) -> Array[
|
|
208
|
-
def set: (String key,
|
|
232
|
+
def get_many: (Array[String] keys) -> Array[V?]
|
|
233
|
+
def set: (String key, V value) -> void
|
|
209
234
|
def remove: (String key) -> void
|
|
210
235
|
def clear: () -> void
|
|
211
|
-
def scan: (
|
|
212
|
-
def keys: (
|
|
236
|
+
def scan: (Symbol direction) -> S
|
|
237
|
+
def keys: (Symbol direction) -> NativeMapKeyScan
|
|
213
238
|
def commit: () -> nil
|
|
214
239
|
def rollback: () -> nil
|
|
215
240
|
end
|
|
216
241
|
|
|
217
|
-
|
|
218
|
-
|
|
242
|
+
class NativeJsonMapState
|
|
243
|
+
include _NativeMapHandle[json_value, NativeJsonMapScan]
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
class NativeMessageMapState
|
|
247
|
+
include _NativeMapHandle[Message[json_value], NativeMessageMapScan]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
interface _NativeDequeHandle[T, S]
|
|
219
251
|
def len: () -> Integer
|
|
220
252
|
def is_empty: () -> bool
|
|
221
|
-
def get: (Integer index) ->
|
|
222
|
-
def peek_front: () ->
|
|
223
|
-
def peek_back: () ->
|
|
224
|
-
def push_back: (
|
|
225
|
-
def push_front: (
|
|
226
|
-
def pop_front: () ->
|
|
227
|
-
def pop_back: () ->
|
|
253
|
+
def get: (Integer index) -> T?
|
|
254
|
+
def peek_front: () -> T?
|
|
255
|
+
def peek_back: () -> T?
|
|
256
|
+
def push_back: (T value) -> void
|
|
257
|
+
def push_front: (T value) -> void
|
|
258
|
+
def pop_front: () -> T?
|
|
259
|
+
def pop_back: () -> T?
|
|
228
260
|
def clear: () -> void
|
|
229
|
-
def scan: (
|
|
261
|
+
def scan: (Symbol direction) -> S
|
|
230
262
|
def commit: () -> nil
|
|
231
263
|
def rollback: () -> nil
|
|
232
264
|
end
|
|
233
265
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
266
|
+
class NativeJsonDequeState
|
|
267
|
+
include _NativeDequeHandle[json_value, NativeJsonDequeScan]
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
class NativeMessageDequeState
|
|
271
|
+
include _NativeDequeHandle[Message[json_value], NativeMessageDequeScan]
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
interface _NativeScan[T]
|
|
275
|
+
def next: () -> T?
|
|
237
276
|
def close: () -> void
|
|
238
277
|
end
|
|
239
278
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
279
|
+
class NativeJsonDequeScan
|
|
280
|
+
include _NativeScan[json_value]
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
class NativeJsonMapScan
|
|
284
|
+
include _NativeScan[[String, json_value]]
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
class NativeMessageDequeScan
|
|
288
|
+
include _NativeScan[Message[json_value]]
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
class NativeMessageMapScan
|
|
292
|
+
include _NativeScan[[String, Message[json_value]]]
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
class NativeMapKeyScan
|
|
296
|
+
include _NativeScan[String]
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
class NativePublishedValue
|
|
300
|
+
def get: (String key) -> json_value?
|
|
301
|
+
end
|
|
243
302
|
|
|
303
|
+
class NativePublishedMap
|
|
304
|
+
def get: (String key, String map_key) -> json_value?
|
|
305
|
+
def get_many: (String key, Array[String] map_keys) -> Array[json_value?]
|
|
306
|
+
def contains_key: (String key, String map_key) -> bool
|
|
307
|
+
def scan: (String key, Symbol direction) -> NativeJsonMapScan
|
|
308
|
+
def keys: (String key, Symbol direction) -> NativeMapKeyScan
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
class NativePublishedDeque
|
|
312
|
+
def get: (String key, Integer index) -> json_value?
|
|
313
|
+
def length: (String key) -> Integer
|
|
314
|
+
def is_empty: (String key) -> bool
|
|
315
|
+
def peek_front: (String key) -> json_value?
|
|
316
|
+
def peek_back: (String key) -> json_value?
|
|
317
|
+
def scan: (String key, Symbol direction) -> NativeJsonDequeScan
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
class PublishedValue[T = json_value]
|
|
321
|
+
def get: (_ToS key) -> T?
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
class PublishedMap[V = json_value]
|
|
325
|
+
def get: (_ToS key, _ToS map_key) -> V?
|
|
326
|
+
def get_many: (_ToS key, Array[_ToS] map_keys) -> Array[V?]
|
|
327
|
+
def key?: (_ToS key, _ToS map_key) -> bool
|
|
328
|
+
alias has_key? key?
|
|
329
|
+
alias include? key?
|
|
330
|
+
alias member? key?
|
|
331
|
+
def each_pair: (_ToS key) { (String, V) -> void } -> void
|
|
332
|
+
| (_ToS key) -> Enumerator[[String, V], void]
|
|
333
|
+
def reverse_each_pair: (_ToS key) { (String, V) -> void } -> void
|
|
334
|
+
| (_ToS key) -> Enumerator[[String, V], void]
|
|
335
|
+
def each_key: (_ToS key) { (String) -> void } -> void
|
|
336
|
+
| (_ToS key) -> Enumerator[String, void]
|
|
337
|
+
def reverse_each_key: (_ToS key) { (String) -> void } -> void
|
|
338
|
+
| (_ToS key) -> Enumerator[String, void]
|
|
339
|
+
def each_value: (_ToS key) { (V) -> void } -> void
|
|
340
|
+
| (_ToS key) -> Enumerator[V, void]
|
|
341
|
+
def reverse_each_value: (_ToS key) { (V) -> void } -> void
|
|
342
|
+
| (_ToS key) -> Enumerator[V, void]
|
|
343
|
+
alias each each_pair
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
class PublishedDeque[T = json_value]
|
|
347
|
+
def get: (_ToS key, Integer index) -> T?
|
|
348
|
+
def length: (_ToS key) -> Integer
|
|
349
|
+
alias size length
|
|
350
|
+
def empty?: (_ToS key) -> bool
|
|
351
|
+
def first: (_ToS key) -> T?
|
|
352
|
+
def last: (_ToS key) -> T?
|
|
353
|
+
def each: (_ToS key) { (T) -> void } -> void
|
|
354
|
+
| (_ToS key) -> Enumerator[T, void]
|
|
355
|
+
def reverse_each: (_ToS key) { (T) -> void } -> void
|
|
356
|
+
| (_ToS key) -> Enumerator[T, void]
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# --- shared state modules ------------------------------------------------
|
|
360
|
+
module State
|
|
244
361
|
# Adds keyed-state vending to the native context.
|
|
245
362
|
module Vending
|
|
246
363
|
def state: [T] (_ValueDefinition[T]) -> ValueState[T]
|
|
@@ -254,7 +371,8 @@ module Prosody
|
|
|
254
371
|
# Shared native-scan driving mixed into the traversal handles.
|
|
255
372
|
module Scanning
|
|
256
373
|
private
|
|
257
|
-
def scan_each: (Symbol direction, ?Symbol opener) { (
|
|
374
|
+
def scan_each: [T] (Symbol direction, ?Symbol opener) { (T) -> void } -> void
|
|
375
|
+
def scan_items: [T] (_NativeScan[T] scan) { (T) -> void } -> void
|
|
258
376
|
end
|
|
259
377
|
end
|
|
260
378
|
|
|
@@ -262,11 +380,11 @@ module Prosody
|
|
|
262
380
|
class Context
|
|
263
381
|
include State::Vending
|
|
264
382
|
|
|
265
|
-
def value_state: (String name) ->
|
|
266
|
-
def map_state: (String name) ->
|
|
267
|
-
def deque_state: (String name) ->
|
|
268
|
-
def message_value_state: (String name) ->
|
|
269
|
-
def message_map_state: (String name) ->
|
|
270
|
-
def message_deque_state: (String name) ->
|
|
383
|
+
def value_state: (String name) -> NativeJsonValueState
|
|
384
|
+
def map_state: (String name) -> NativeJsonMapState
|
|
385
|
+
def deque_state: (String name) -> NativeJsonDequeState
|
|
386
|
+
def message_value_state: (String name) -> NativeMessageValueState
|
|
387
|
+
def message_map_state: (String name) -> NativeMessageMapState
|
|
388
|
+
def message_deque_state: (String name) -> NativeMessageDequeState
|
|
271
389
|
end
|
|
272
390
|
end
|
data/steep_expectations.yml
CHANGED
|
@@ -45,3 +45,13 @@
|
|
|
45
45
|
::Object <: ::Prosody::Message[untyped]
|
|
46
46
|
::BasicObject <: ::Prosody::Message[untyped]
|
|
47
47
|
code: Ruby::ArgumentTypeMismatch
|
|
48
|
+
- range:
|
|
49
|
+
start:
|
|
50
|
+
line: 18
|
|
51
|
+
character: 12
|
|
52
|
+
end:
|
|
53
|
+
line: 18
|
|
54
|
+
character: 19
|
|
55
|
+
severity: ERROR
|
|
56
|
+
message: Type `::Prosody::ExciseMessage` does not have method `payload`
|
|
57
|
+
code: Ruby::NoMethod
|
data/typecheck/payload_types.rb
CHANGED
|
@@ -7,9 +7,15 @@ ORDER_BACKLOG = Prosody.message_deque("order-backlog")
|
|
|
7
7
|
ORDER_TOTALS = Prosody.map("order-totals")
|
|
8
8
|
|
|
9
9
|
class TypedOrderHandler < Prosody::EventHandler
|
|
10
|
+
def on_excise(_context, message)
|
|
11
|
+
message.key
|
|
12
|
+
{"accepted" => true}
|
|
13
|
+
end
|
|
14
|
+
|
|
10
15
|
def on_message(context, message)
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
payload = message.payload
|
|
17
|
+
order_id = payload["order_id"]
|
|
18
|
+
total = payload["total"]
|
|
13
19
|
|
|
14
20
|
# Message-backed state preserves the handler's payload type.
|
|
15
21
|
backlog = context.state(ORDER_BACKLOG)
|
|
@@ -21,7 +27,12 @@ class TypedOrderHandler < Prosody::EventHandler
|
|
|
21
27
|
consume_totals(context.state(ORDER_TOTALS))
|
|
22
28
|
|
|
23
29
|
consume_order(order_id, total)
|
|
24
|
-
|
|
30
|
+
oldest_payload = oldest&.payload
|
|
31
|
+
consume_order(oldest_payload["order_id"], oldest_payload["total"]) if oldest_payload
|
|
32
|
+
{"accepted" => true}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def on_timer(_context, _timer)
|
|
25
36
|
end
|
|
26
37
|
|
|
27
38
|
private
|
data/typecheck/payload_types.rbs
CHANGED
|
@@ -2,12 +2,14 @@ type order_event = {
|
|
|
2
2
|
"order_id" => String,
|
|
3
3
|
"total" => Integer
|
|
4
4
|
}
|
|
5
|
+
type handler_response = { "accepted" => bool }
|
|
5
6
|
|
|
6
7
|
ORDER_BACKLOG: Prosody::_MessageDequeDefinition[order_event]
|
|
7
8
|
ORDER_TOTALS: Prosody::_MapDefinition[Integer]
|
|
8
9
|
|
|
9
|
-
class TypedOrderHandler < Prosody::EventHandler[order_event]
|
|
10
|
-
def on_message: (Prosody::Context context, Prosody::Message[order_event] message) ->
|
|
10
|
+
class TypedOrderHandler < Prosody::EventHandler[order_event, handler_response]
|
|
11
|
+
def on_message: (Prosody::Context context, Prosody::Message[order_event] message) -> handler_response
|
|
12
|
+
def on_excise: (Prosody::Context context, Prosody::ExciseMessage message) -> handler_response
|
|
11
13
|
|
|
12
14
|
private
|
|
13
15
|
|
|
@@ -5,4 +5,5 @@ NEGATIVE_MESSAGES: Prosody::_MessageDequeDefinition[negative_event]
|
|
|
5
5
|
|
|
6
6
|
class NegativeTypeChecks
|
|
7
7
|
def check: (Prosody::Client client, Prosody::Context context, Prosody::Message[negative_event] message) -> void
|
|
8
|
+
def check_excise: (Prosody::ExciseMessage message) -> void
|
|
8
9
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prosody
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joshua Griffith
|
|
@@ -123,8 +123,11 @@ files:
|
|
|
123
123
|
- ".ruby-version"
|
|
124
124
|
- ".standard.yml"
|
|
125
125
|
- ".taplo.toml"
|
|
126
|
+
- AGENTS.md
|
|
126
127
|
- ARCHITECTURE.md
|
|
127
128
|
- CHANGELOG.md
|
|
129
|
+
- CLAUDE.md
|
|
130
|
+
- CONFIGURATION.md
|
|
128
131
|
- Cargo.lock
|
|
129
132
|
- Cargo.toml
|
|
130
133
|
- LICENSE
|
|
@@ -143,14 +146,19 @@ files:
|
|
|
143
146
|
- ext/prosody/src/bridge/mod.rs
|
|
144
147
|
- ext/prosody/src/client/config.rs
|
|
145
148
|
- ext/prosody/src/client/mod.rs
|
|
149
|
+
- ext/prosody/src/client/request.rs
|
|
150
|
+
- ext/prosody/src/client/support.rs
|
|
146
151
|
- ext/prosody/src/gvl.rs
|
|
147
152
|
- ext/prosody/src/handler/context.rs
|
|
148
153
|
- ext/prosody/src/handler/message.rs
|
|
149
154
|
- ext/prosody/src/handler/mod.rs
|
|
150
|
-
- ext/prosody/src/handler/state.rs
|
|
155
|
+
- ext/prosody/src/handler/state/mod.rs
|
|
156
|
+
- ext/prosody/src/handler/state/registration.rs
|
|
157
|
+
- ext/prosody/src/handler/state/scan.rs
|
|
151
158
|
- ext/prosody/src/handler/trigger.rs
|
|
152
159
|
- ext/prosody/src/lib.rs
|
|
153
160
|
- ext/prosody/src/logging.rs
|
|
161
|
+
- ext/prosody/src/published.rs
|
|
154
162
|
- ext/prosody/src/scheduler/cancellation.rs
|
|
155
163
|
- ext/prosody/src/scheduler/handle.rs
|
|
156
164
|
- ext/prosody/src/scheduler/mod.rs
|
|
@@ -163,6 +171,7 @@ files:
|
|
|
163
171
|
- lib/prosody/handler.rb
|
|
164
172
|
- lib/prosody/native_stubs.rb
|
|
165
173
|
- lib/prosody/processor.rb
|
|
174
|
+
- lib/prosody/request.rb
|
|
166
175
|
- lib/prosody/sentry.rb
|
|
167
176
|
- lib/prosody/state.rb
|
|
168
177
|
- lib/prosody/version.rb
|
|
@@ -171,6 +180,7 @@ files:
|
|
|
171
180
|
- sig/handler.rbs
|
|
172
181
|
- sig/processor.rbs
|
|
173
182
|
- sig/prosody.rbs
|
|
183
|
+
- sig/request.rbs
|
|
174
184
|
- sig/sentry.rbs
|
|
175
185
|
- sig/state.rbs
|
|
176
186
|
- sig/version.rbs
|