prosody 0.3.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 +14 -4
- data/CHANGELOG.md +28 -0
- data/CLAUDE.md +1 -0
- data/CONFIGURATION.md +167 -0
- data/Cargo.lock +1115 -645
- data/Cargo.toml +7 -6
- data/README.md +436 -146
- data/Rakefile +11 -1
- data/examples/keyed_state.rb +70 -0
- data/examples/keyed_state.rbs +18 -0
- data/examples/keyed_state_windowing.rb +55 -0
- data/examples/keyed_state_windowing.rbs +16 -0
- data/ext/prosody/Cargo.toml +1 -0
- data/ext/prosody/src/admin.rs +1 -5
- data/ext/prosody/src/bridge/mod.rs +17 -32
- data/ext/prosody/src/client/config.rs +501 -28
- 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 +150 -5
- data/ext/prosody/src/handler/message.rs +67 -0
- data/ext/prosody/src/handler/mod.rs +115 -85
- 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 +71 -11
- data/lib/prosody/handler.rb +65 -8
- data/lib/prosody/native_stubs.rb +550 -9
- data/lib/prosody/request.rb +45 -0
- data/lib/prosody/state.rb +816 -0
- data/lib/prosody/version.rb +1 -1
- data/lib/prosody.rb +6 -0
- data/release-please-config.json +4 -0
- data/sig/configuration.rbs +70 -11
- data/sig/handler.rbs +17 -5
- data/sig/processor.rbs +28 -12
- data/sig/prosody.rbs +53 -7
- data/sig/request.rbs +66 -0
- data/sig/sentry.rbs +6 -0
- data/sig/state.rbs +390 -0
- data/steep_expectations.yml +57 -0
- data/typecheck/payload_types.rb +54 -0
- data/typecheck/payload_types.rbs +22 -0
- data/typecheck_negative/payload_types.rb +20 -0
- data/typecheck_negative/payload_types.rbs +9 -0
- metadata +32 -9
data/lib/prosody/native_stubs.rb
CHANGED
|
@@ -179,12 +179,94 @@ module Prosody
|
|
|
179
179
|
def scheduled
|
|
180
180
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
181
181
|
end
|
|
182
|
+
|
|
183
|
+
# Vends the native single-value JSON state handle for the named collection.
|
|
184
|
+
#
|
|
185
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
186
|
+
# +context.state(definition)+.
|
|
187
|
+
#
|
|
188
|
+
# @param name [String] the registered collection name
|
|
189
|
+
# @return [NativeJsonValueState] the native handle
|
|
190
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
191
|
+
# @private
|
|
192
|
+
def value_state(name)
|
|
193
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Vends the native ordered-map JSON state handle for the named collection.
|
|
197
|
+
#
|
|
198
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
199
|
+
# +context.state(definition)+.
|
|
200
|
+
#
|
|
201
|
+
# @param name [String] the registered collection name
|
|
202
|
+
# @return [NativeJsonMapState] the native handle
|
|
203
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
204
|
+
# @private
|
|
205
|
+
def map_state(name)
|
|
206
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Vends the native deque JSON state handle for the named collection.
|
|
210
|
+
#
|
|
211
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
212
|
+
# +context.state(definition)+.
|
|
213
|
+
#
|
|
214
|
+
# @param name [String] the registered collection name
|
|
215
|
+
# @return [NativeJsonDequeState] the native handle
|
|
216
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
217
|
+
# @private
|
|
218
|
+
def deque_state(name)
|
|
219
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Vends the native single-value message state handle for the named
|
|
223
|
+
# collection.
|
|
224
|
+
#
|
|
225
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
226
|
+
# +context.state(definition)+.
|
|
227
|
+
#
|
|
228
|
+
# @param name [String] the registered collection name
|
|
229
|
+
# @return [NativeMessageValueState] the native handle
|
|
230
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
231
|
+
# @private
|
|
232
|
+
def message_value_state(name)
|
|
233
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Vends the native ordered-map message state handle for the named
|
|
237
|
+
# collection.
|
|
238
|
+
#
|
|
239
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
240
|
+
# +context.state(definition)+.
|
|
241
|
+
#
|
|
242
|
+
# @param name [String] the registered collection name
|
|
243
|
+
# @return [NativeMessageMapState] the native handle
|
|
244
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
245
|
+
# @private
|
|
246
|
+
def message_map_state(name)
|
|
247
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Vends the native deque message state handle for the named collection.
|
|
251
|
+
#
|
|
252
|
+
# Internal routing target for {Prosody::State::Vending#state}; prefer
|
|
253
|
+
# +context.state(definition)+.
|
|
254
|
+
#
|
|
255
|
+
# @param name [String] the registered collection name
|
|
256
|
+
# @return [NativeMessageDequeState] the native handle
|
|
257
|
+
# @raise [PermanentStateError] if the name is unregistered or mismatched
|
|
258
|
+
# @private
|
|
259
|
+
def message_deque_state(name)
|
|
260
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
261
|
+
end
|
|
182
262
|
end
|
|
183
263
|
|
|
184
264
|
# Represents a Kafka message with its metadata and payload.
|
|
185
265
|
#
|
|
186
266
|
# Instances of this class are created by the native code and passed to your
|
|
187
|
-
# EventHandler's #on_message method.
|
|
267
|
+
# EventHandler's #on_message method. In RBS, +Message[Payload]+ carries the
|
|
268
|
+
# statically declared payload shape; bare +Message+ defaults to
|
|
269
|
+
# +Prosody::json_value+. This annotation does not add runtime validation.
|
|
188
270
|
#
|
|
189
271
|
# @see ext/prosody/src/handler/message.rs for implementation
|
|
190
272
|
class Message
|
|
@@ -227,12 +309,30 @@ module Prosody
|
|
|
227
309
|
#
|
|
228
310
|
# The payload is automatically deserialized from JSON to Ruby objects.
|
|
229
311
|
#
|
|
230
|
-
# @return [
|
|
312
|
+
# @return [Payload] The message content
|
|
231
313
|
def payload
|
|
232
314
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
233
315
|
end
|
|
234
316
|
end
|
|
235
317
|
|
|
318
|
+
# An excise record with Kafka metadata and no payload.
|
|
319
|
+
class ExciseMessage
|
|
320
|
+
# @return [String] The topic name
|
|
321
|
+
def topic = raise NotImplementedError, "This method is implemented natively in Rust"
|
|
322
|
+
|
|
323
|
+
# @return [Integer] The partition number
|
|
324
|
+
def partition = raise NotImplementedError, "This method is implemented natively in Rust"
|
|
325
|
+
|
|
326
|
+
# @return [Integer] The message offset
|
|
327
|
+
def offset = raise NotImplementedError, "This method is implemented natively in Rust"
|
|
328
|
+
|
|
329
|
+
# @return [String] The message key
|
|
330
|
+
def key = raise NotImplementedError, "This method is implemented natively in Rust"
|
|
331
|
+
|
|
332
|
+
# @return [Time] The record timestamp
|
|
333
|
+
def timestamp = raise NotImplementedError, "This method is implemented natively in Rust"
|
|
334
|
+
end
|
|
335
|
+
|
|
236
336
|
# Represents a timer that was scheduled to fire at a specific time.
|
|
237
337
|
#
|
|
238
338
|
# Timer instances are created by the native code and passed to your
|
|
@@ -297,7 +397,8 @@ module Prosody
|
|
|
297
397
|
|
|
298
398
|
# Returns the current state of the consumer.
|
|
299
399
|
#
|
|
300
|
-
# The consumer can be in one of
|
|
400
|
+
# The consumer can be in one of four states:
|
|
401
|
+
# - `:shut_down` - The client is shut down
|
|
301
402
|
# - `:unconfigured` - The consumer has not been configured yet
|
|
302
403
|
# - `:configured` - The consumer is configured but not running
|
|
303
404
|
# - `:running` - The consumer is actively consuming messages
|
|
@@ -307,6 +408,10 @@ module Prosody
|
|
|
307
408
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
308
409
|
end
|
|
309
410
|
|
|
411
|
+
def native_request(_request)
|
|
412
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
413
|
+
end
|
|
414
|
+
|
|
310
415
|
# Returns the number of Kafka partitions currently assigned to this consumer.
|
|
311
416
|
#
|
|
312
417
|
# This method can be used to monitor the consumer's workload and ensure
|
|
@@ -332,21 +437,34 @@ module Prosody
|
|
|
332
437
|
#
|
|
333
438
|
# @param topic [String] The destination topic name
|
|
334
439
|
# @param key [String] The message key for partitioning
|
|
335
|
-
# @param payload [
|
|
440
|
+
# @param payload [Prosody::json_value] The JSON-compatible message payload
|
|
336
441
|
# @return [void]
|
|
337
442
|
# @raise [RuntimeError] If the message cannot be sent
|
|
338
443
|
#
|
|
339
444
|
# @example Sending a simple message
|
|
340
|
-
# client.send_message("my-topic", "user-123", {
|
|
445
|
+
# client.send_message("my-topic", "user-123", {
|
|
446
|
+
# "event" => "login", "timestamp" => Time.now.to_i
|
|
447
|
+
# })
|
|
341
448
|
def send_message(topic, key, payload)
|
|
342
449
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
343
450
|
end
|
|
344
451
|
|
|
452
|
+
# Sends an excise record to the specified Kafka topic.
|
|
453
|
+
#
|
|
454
|
+
# @param topic [String] The destination topic name
|
|
455
|
+
# @param key [String] The message key for partitioning
|
|
456
|
+
# @return [void]
|
|
457
|
+
# @raise [RuntimeError] If the excise record cannot be sent
|
|
458
|
+
def excise(topic, key)
|
|
459
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
460
|
+
end
|
|
461
|
+
|
|
345
462
|
# Subscribes to Kafka topics using the provided handler.
|
|
346
|
-
# The handler must implement
|
|
463
|
+
# The handler must implement `on_message`, `on_excise`, and `on_timer`.
|
|
347
464
|
#
|
|
348
465
|
# @param handler [EventHandler] A handler object that processes messages
|
|
349
466
|
# @return [void]
|
|
467
|
+
# @raise [ArgumentError] If a required handler method is missing
|
|
350
468
|
# @raise [RuntimeError] If subscription fails
|
|
351
469
|
#
|
|
352
470
|
# @example Subscribing with a handler
|
|
@@ -354,6 +472,13 @@ module Prosody
|
|
|
354
472
|
# def on_message(context, message)
|
|
355
473
|
# puts "Received message: #{message.payload}"
|
|
356
474
|
# end
|
|
475
|
+
#
|
|
476
|
+
# def on_excise(_context, message)
|
|
477
|
+
# puts "Excised key: #{message.key}"
|
|
478
|
+
# end
|
|
479
|
+
#
|
|
480
|
+
# def on_timer(_context, _timer)
|
|
481
|
+
# end
|
|
357
482
|
# end
|
|
358
483
|
#
|
|
359
484
|
# client.subscribe(MyHandler.new)
|
|
@@ -369,12 +494,21 @@ module Prosody
|
|
|
369
494
|
# @return [void]
|
|
370
495
|
# @raise [RuntimeError] If unsubscription fails
|
|
371
496
|
#
|
|
372
|
-
# @example Shutting down a consumer
|
|
373
|
-
# client.unsubscribe
|
|
374
497
|
def unsubscribe
|
|
375
498
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
376
499
|
end
|
|
377
500
|
|
|
501
|
+
# Shuts down the consumer and all client services.
|
|
502
|
+
#
|
|
503
|
+
# @return [void]
|
|
504
|
+
# @raise [RuntimeError] If shutdown fails
|
|
505
|
+
#
|
|
506
|
+
# @example Shutting down a client
|
|
507
|
+
# client.shutdown
|
|
508
|
+
def shutdown
|
|
509
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
510
|
+
end
|
|
511
|
+
|
|
378
512
|
# Returns the configured source system identifier.
|
|
379
513
|
#
|
|
380
514
|
# The source system is used to identify the originating service or
|
|
@@ -387,6 +521,413 @@ module Prosody
|
|
|
387
521
|
def source_system
|
|
388
522
|
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
389
523
|
end
|
|
524
|
+
|
|
525
|
+
# @private
|
|
526
|
+
def published_value(subsystem, name, read_cache, read_cache_disabled)
|
|
527
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
# @private
|
|
531
|
+
def published_map(subsystem, name, read_cache, read_cache_disabled)
|
|
532
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
# @private
|
|
536
|
+
def published_deque(subsystem, name, read_cache, read_cache_disabled)
|
|
537
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
# Native single-value keyed-state handle, vended by the context and wrapped by
|
|
542
|
+
# {Prosody::ValueState}. Every operation is fiber-yield async: it crosses the
|
|
543
|
+
# bridge and yields the fiber while the Rust core drives the operation.
|
|
544
|
+
#
|
|
545
|
+
# @see ext/prosody/src/handler/state/mod.rs for implementation
|
|
546
|
+
module NativeValueOperations
|
|
547
|
+
# @private
|
|
548
|
+
def initialize
|
|
549
|
+
raise NotImplementedError, "This class is implemented natively in Rust"
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
# Reads the current value.
|
|
553
|
+
#
|
|
554
|
+
# @return [Object, nil] the stored value, or nil when absent
|
|
555
|
+
def get
|
|
556
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
# Buffers a write of the value.
|
|
560
|
+
#
|
|
561
|
+
# @param value [Object] the value to store
|
|
562
|
+
# @return [void]
|
|
563
|
+
# @raise [NullValueError] if value is nil
|
|
564
|
+
# @raise [TransientStateError] if value cannot be represented
|
|
565
|
+
def set(value)
|
|
566
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
# Buffers a clear of the value.
|
|
570
|
+
#
|
|
571
|
+
# @return [void]
|
|
572
|
+
def clear
|
|
573
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# Durably commits the buffered operations mid-handler.
|
|
577
|
+
#
|
|
578
|
+
# @return [nil]
|
|
579
|
+
def commit
|
|
580
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# Discards the buffered uncommitted operations.
|
|
584
|
+
#
|
|
585
|
+
# @return [nil]
|
|
586
|
+
def rollback
|
|
587
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
class NativeJsonValueState
|
|
592
|
+
include NativeValueOperations
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
class NativeMessageValueState
|
|
596
|
+
include NativeValueOperations
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
# Native String-keyed ordered-map keyed-state handle, vended by the context and
|
|
600
|
+
# wrapped by {Prosody::MapState}. Every operation is fiber-yield async, except
|
|
601
|
+
# +#scan+, which opens the cursor synchronously; each native cursor pull
|
|
602
|
+
# yields the fiber.
|
|
603
|
+
#
|
|
604
|
+
# @see ext/prosody/src/handler/state/mod.rs for implementation
|
|
605
|
+
module NativeMapOperations
|
|
606
|
+
# @private
|
|
607
|
+
def initialize
|
|
608
|
+
raise NotImplementedError, "This class is implemented natively in Rust"
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
# Reads the value for a key.
|
|
612
|
+
#
|
|
613
|
+
# @param key [String] the map key
|
|
614
|
+
# @return [Object, nil] the value, or nil when the key is absent
|
|
615
|
+
def get(key)
|
|
616
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
# Answers whether a stored cell exists for a key. No value decode and no
|
|
620
|
+
# resolver run (a message-backed map answers with zero Kafka fetches), but
|
|
621
|
+
# not no-I/O: a cache miss still reads the store.
|
|
622
|
+
#
|
|
623
|
+
# @param key [String] the map key
|
|
624
|
+
# @return [Boolean] whether a live cell exists for the key
|
|
625
|
+
def contains_key(key)
|
|
626
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
# Reads several keys in a single isolated batch.
|
|
630
|
+
#
|
|
631
|
+
# @param keys [Array<String>] the keys to read, in order
|
|
632
|
+
# @return [Array<Object, nil>] one result per input key
|
|
633
|
+
def get_many(keys)
|
|
634
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
# Inserts or overwrites a key.
|
|
638
|
+
#
|
|
639
|
+
# @param key [String] the map key
|
|
640
|
+
# @param value [Object] the value to store
|
|
641
|
+
# @return [void]
|
|
642
|
+
# @raise [NullValueError] if value is nil
|
|
643
|
+
# @raise [TransientStateError] if value cannot be represented
|
|
644
|
+
def set(key, value)
|
|
645
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
# Removes a key.
|
|
649
|
+
#
|
|
650
|
+
# @param key [String] the map key
|
|
651
|
+
# @return [void]
|
|
652
|
+
def remove(key)
|
|
653
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
# Removes every entry.
|
|
657
|
+
#
|
|
658
|
+
# @return [void]
|
|
659
|
+
def clear
|
|
660
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
# Opens a native ordered scan over the live entries.
|
|
664
|
+
#
|
|
665
|
+
# @param direction [Symbol] +:forward+ or +:backward+
|
|
666
|
+
# @return [Object] the native cursor
|
|
667
|
+
# @raise [TransientStateError] if direction is not +:forward+ or +:backward+
|
|
668
|
+
def scan(direction)
|
|
669
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
# Opens a native ordered scan over the live keys only, yielding bare keys.
|
|
673
|
+
# Skips value decode and the resolver (a message-backed map enumerates keys
|
|
674
|
+
# with zero Kafka fetches), though not no-I/O.
|
|
675
|
+
#
|
|
676
|
+
# @param direction [Symbol] +:forward+ or +:backward+
|
|
677
|
+
# @return [NativeMapKeyScan] the native key cursor
|
|
678
|
+
# @raise [TransientStateError] if direction is not +:forward+ or +:backward+
|
|
679
|
+
def keys(direction)
|
|
680
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
# Durably commits the buffered operations mid-handler.
|
|
684
|
+
#
|
|
685
|
+
# @return [nil]
|
|
686
|
+
def commit
|
|
687
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
# Discards the buffered uncommitted operations.
|
|
691
|
+
#
|
|
692
|
+
# @return [nil]
|
|
693
|
+
def rollback
|
|
694
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
class NativeJsonMapState
|
|
699
|
+
include NativeMapOperations
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
class NativeMessageMapState
|
|
703
|
+
include NativeMapOperations
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
# Native deque keyed-state handle, vended by the context and wrapped by
|
|
707
|
+
# {Prosody::DequeState}. Every operation is fiber-yield async, except +#scan+,
|
|
708
|
+
# which opens the cursor synchronously; each native cursor pull yields the
|
|
709
|
+
# fiber.
|
|
710
|
+
#
|
|
711
|
+
# @see ext/prosody/src/handler/state/mod.rs for implementation
|
|
712
|
+
module NativeDequeOperations
|
|
713
|
+
# @private
|
|
714
|
+
def initialize
|
|
715
|
+
raise NotImplementedError, "This class is implemented natively in Rust"
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
# The number of live elements.
|
|
719
|
+
#
|
|
720
|
+
# @return [Integer]
|
|
721
|
+
def len
|
|
722
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
# Whether the deque holds no live elements.
|
|
726
|
+
#
|
|
727
|
+
# @return [Boolean]
|
|
728
|
+
def is_empty
|
|
729
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
# Reads the element at front-relative position.
|
|
733
|
+
#
|
|
734
|
+
# @param index [Integer] the zero-based position from the front
|
|
735
|
+
# @return [Object, nil] the element, or nil past the end
|
|
736
|
+
def get(index)
|
|
737
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
# Reads the front endpoint slot, or nil when empty. One round trip, no
|
|
741
|
+
# length read; an expired endpoint slot under a TTL yields nil even when
|
|
742
|
+
# live interior elements remain (a peek never searches inward).
|
|
743
|
+
#
|
|
744
|
+
# @return [Object, nil] the front element, or nil when empty
|
|
745
|
+
def peek_front
|
|
746
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
# Reads the back endpoint slot, or nil when empty. Same endpoint-slot
|
|
750
|
+
# semantics as #peek_front.
|
|
751
|
+
#
|
|
752
|
+
# @return [Object, nil] the back element, or nil when empty
|
|
753
|
+
def peek_back
|
|
754
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
# Appends an element at the back.
|
|
758
|
+
#
|
|
759
|
+
# @param value [Object] the element
|
|
760
|
+
# @return [void]
|
|
761
|
+
# @raise [NullValueError] if value is nil
|
|
762
|
+
# @raise [TransientStateError] if value cannot be represented
|
|
763
|
+
def push_back(value)
|
|
764
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
# Prepends an element at the front.
|
|
768
|
+
#
|
|
769
|
+
# @param value [Object] the element
|
|
770
|
+
# @return [void]
|
|
771
|
+
# @raise [NullValueError] if value is nil
|
|
772
|
+
# @raise [TransientStateError] if value cannot be represented
|
|
773
|
+
def push_front(value)
|
|
774
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
# Removes and returns the front element.
|
|
778
|
+
#
|
|
779
|
+
# @return [Object, nil] the removed element, or nil when empty
|
|
780
|
+
def pop_front
|
|
781
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
# Removes and returns the back element.
|
|
785
|
+
#
|
|
786
|
+
# @return [Object, nil] the removed element, or nil when empty
|
|
787
|
+
def pop_back
|
|
788
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
# Removes every element.
|
|
792
|
+
#
|
|
793
|
+
# @return [void]
|
|
794
|
+
def clear
|
|
795
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
# Opens a native scan over the live elements.
|
|
799
|
+
#
|
|
800
|
+
# @param direction [Symbol] +:forward+ or +:backward+
|
|
801
|
+
# @return [Object] the native cursor
|
|
802
|
+
# @raise [TransientStateError] if direction is not +:forward+ or +:backward+
|
|
803
|
+
def scan(direction)
|
|
804
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
# Durably commits the buffered operations mid-handler.
|
|
808
|
+
#
|
|
809
|
+
# @return [nil]
|
|
810
|
+
def commit
|
|
811
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
# Discards the buffered uncommitted operations.
|
|
815
|
+
#
|
|
816
|
+
# @return [nil]
|
|
817
|
+
def rollback
|
|
818
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
819
|
+
end
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
class NativeJsonDequeState
|
|
823
|
+
include NativeDequeOperations
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
class NativeMessageDequeState
|
|
827
|
+
include NativeDequeOperations
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
# Native cursor over a keyed-state collection, driven one chunk at a time
|
|
831
|
+
# by the {Prosody::MapState} / {Prosody::DequeState} traversal methods. Each
|
|
832
|
+
# pull crosses the bridge and yields the fiber; +close+ is idempotent.
|
|
833
|
+
#
|
|
834
|
+
# @see ext/prosody/src/handler/state/scan.rs for implementation
|
|
835
|
+
module NativeScanOperations
|
|
836
|
+
# @private
|
|
837
|
+
def initialize
|
|
838
|
+
raise NotImplementedError, "This class is implemented natively in Rust"
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
# Pulls the next item from the cursor.
|
|
842
|
+
#
|
|
843
|
+
# @return [Object, nil] the next item, or nil when the cursor is exhausted
|
|
844
|
+
def next
|
|
845
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
# Closes the native cursor. Idempotent.
|
|
849
|
+
#
|
|
850
|
+
# @return [void]
|
|
851
|
+
def close
|
|
852
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
853
|
+
end
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
class NativeJsonDequeScan
|
|
857
|
+
include NativeScanOperations
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
class NativeJsonMapScan
|
|
861
|
+
include NativeScanOperations
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
class NativeMessageDequeScan
|
|
865
|
+
include NativeScanOperations
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
class NativeMessageMapScan
|
|
869
|
+
include NativeScanOperations
|
|
870
|
+
end
|
|
871
|
+
|
|
872
|
+
class NativeMapKeyScan
|
|
873
|
+
include NativeScanOperations
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
# @private
|
|
877
|
+
class NativePublishedValue
|
|
878
|
+
def get(key)
|
|
879
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
880
|
+
end
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
# @private
|
|
884
|
+
class NativePublishedMap
|
|
885
|
+
def get(key, map_key)
|
|
886
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
def get_many(key, map_keys)
|
|
890
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
def contains_key(key, map_key)
|
|
894
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
def scan(key, direction)
|
|
898
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
def keys(key, direction)
|
|
902
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
903
|
+
end
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
# @private
|
|
907
|
+
class NativePublishedDeque
|
|
908
|
+
def get(key, index)
|
|
909
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
910
|
+
end
|
|
911
|
+
|
|
912
|
+
def length(key)
|
|
913
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
def is_empty(key)
|
|
917
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
def peek_front(key)
|
|
921
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
def peek_back(key)
|
|
925
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
def scan(key, direction)
|
|
929
|
+
raise NotImplementedError, "This method is implemented natively in Rust"
|
|
930
|
+
end
|
|
390
931
|
end
|
|
391
932
|
|
|
392
933
|
# Internal processor for executing tasks asynchronously.
|
|
@@ -410,7 +951,7 @@ module Prosody
|
|
|
410
951
|
end
|
|
411
952
|
|
|
412
953
|
# @private
|
|
413
|
-
def submit(task_id, carrier, callback, &block)
|
|
954
|
+
def submit(task_id, carrier, event_context, callback, &block)
|
|
414
955
|
# Actual implementation is in lib/prosody/processor.rb
|
|
415
956
|
end
|
|
416
957
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Prosody
|
|
4
|
+
Success = Data.define(:value)
|
|
5
|
+
Failure = Data.define(:error)
|
|
6
|
+
HandlerError = Data.define(:message)
|
|
7
|
+
|
|
8
|
+
Timeout = Data.define do
|
|
9
|
+
def message = "no response arrived before the deadline"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
FormatMismatch = Data.define do
|
|
13
|
+
def message = "the responder answered in another format"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
MalformedResponse = Data.define do
|
|
17
|
+
def message = "the response did not decode"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Client
|
|
21
|
+
# Returns one outcome for each subsystem.
|
|
22
|
+
# @param timeout [Numeric] The response deadline in seconds.
|
|
23
|
+
# @raise [ArgumentError] if a subsystem name or timeout is invalid
|
|
24
|
+
# @raise [RuntimeError] if the request cannot start or the Kafka send fails
|
|
25
|
+
def request(topic:, key:, payload:, subsystems:, timeout:)
|
|
26
|
+
native_request(
|
|
27
|
+
topic: topic,
|
|
28
|
+
key: key,
|
|
29
|
+
payload: payload,
|
|
30
|
+
subsystems: subsystems,
|
|
31
|
+
timeout: timeout
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns one excise outcome for each subsystem.
|
|
36
|
+
def request_excise(topic:, key:, subsystems:, timeout:)
|
|
37
|
+
native_request_excise(
|
|
38
|
+
topic: topic,
|
|
39
|
+
key: key,
|
|
40
|
+
subsystems: subsystems,
|
|
41
|
+
timeout: timeout
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|