prosody 0.5.1 → 0.6.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.config/rail.toml +26 -0
  3. data/.release-please-manifest.json +1 -1
  4. data/.ruby-version +1 -1
  5. data/.taplo.toml +1 -1
  6. data/AGENTS.md +29 -15
  7. data/CHANGELOG.md +7 -0
  8. data/CONFIGURATION.md +19 -16
  9. data/Cargo.lock +254 -235
  10. data/Cargo.toml +11 -8
  11. data/README.md +100 -23
  12. data/examples/keyed_state.rb +10 -2
  13. data/examples/keyed_state.rbs +1 -0
  14. data/ext/prosody/Cargo.toml +1 -1
  15. data/ext/prosody/src/admin.rs +36 -36
  16. data/ext/prosody/src/bridge/mod.rs +5 -10
  17. data/ext/prosody/src/client/config/connections.rs +170 -0
  18. data/ext/prosody/src/client/config/middleware.rs +184 -0
  19. data/ext/prosody/src/client/config/mod.rs +396 -0
  20. data/ext/prosody/src/client/config/state.rs +323 -0
  21. data/ext/prosody/src/client/mod.rs +31 -117
  22. data/ext/prosody/src/client/readers.rs +106 -0
  23. data/ext/prosody/src/client/request.rs +2 -2
  24. data/ext/prosody/src/client/support.rs +13 -32
  25. data/ext/prosody/src/gvl.rs +8 -6
  26. data/ext/prosody/src/handler/{context.rs → context/mod.rs} +36 -150
  27. data/ext/prosody/src/handler/context/vending.rs +138 -0
  28. data/ext/prosody/src/handler/message.rs +36 -0
  29. data/ext/prosody/src/handler/mod.rs +18 -8
  30. data/ext/prosody/src/handler/state/deque.rs +144 -0
  31. data/ext/prosody/src/handler/state/mod.rs +163 -268
  32. data/ext/prosody/src/handler/state/query.rs +264 -0
  33. data/ext/prosody/src/handler/state/registration.rs +15 -86
  34. data/ext/prosody/src/handler/state/scan.rs +33 -141
  35. data/ext/prosody/src/handler/state/set.rs +98 -0
  36. data/ext/prosody/src/lib.rs +54 -36
  37. data/ext/prosody/src/logging.rs +6 -6
  38. data/ext/prosody/src/published.rs +171 -152
  39. data/ext/prosody/src/scheduler/result.rs +2 -1
  40. data/ext/prosody/src/util.rs +65 -3
  41. data/lib/prosody/client.rb +32 -0
  42. data/lib/prosody/configuration.rb +20 -12
  43. data/lib/prosody/demand.rb +27 -0
  44. data/lib/prosody/native_stubs/client.rb +157 -0
  45. data/lib/prosody/native_stubs/context.rb +178 -0
  46. data/lib/prosody/native_stubs/message.rb +133 -0
  47. data/lib/prosody/native_stubs.rb +11 -956
  48. data/lib/prosody/state/deque.rb +253 -0
  49. data/lib/prosody/state/map.rb +313 -0
  50. data/lib/prosody/state/set.rb +121 -0
  51. data/lib/prosody/state/value.rb +58 -0
  52. data/lib/prosody/state.rb +157 -677
  53. data/lib/prosody/version.rb +1 -1
  54. data/lib/prosody.rb +2 -1
  55. data/sig/configuration.rbs +19 -10
  56. data/sig/prosody.rbs +37 -4
  57. data/sig/published.rbs +102 -0
  58. data/sig/state.rbs +109 -122
  59. data/typecheck/payload_types.rb +12 -0
  60. data/typecheck/payload_types.rbs +1 -0
  61. metadata +30 -11
  62. data/ext/prosody/src/client/config.rs +0 -1300
@@ -1,958 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Prosody
4
- # = Native Interface Stubs
5
- #
6
- # This file contains stub definitions for native methods implemented in the
7
- # Prosody Rust extension. These stubs provide documentation and method
8
- # signatures for Ruby tooling like editors and documentation generators,
9
- # but the actual implementations are in the Rust extension.
10
- #
11
- # == Implementation Notes
12
- #
13
- # The actual implementations of these methods are in the Rust extension at:
14
- # ext/prosody/src/
15
-
16
- # Wrapper for dynamically-typed results returned from async operations.
17
- # This is an internal class used by the native code to transfer results
18
- # between Rust and Ruby.
19
- #
20
- # @private
21
- class DynamicResult
22
- # @private
23
- def initialize
24
- raise NotImplementedError, "This class is implemented natively in Rust"
25
- end
26
- end
27
-
28
- # Represents the context of a Kafka message, providing metadata and control
29
- # capabilities for message handling.
30
- #
31
- # Instances of this class are created by the native code and passed to your
32
- # EventHandler's #on_message method.
33
- #
34
- # @see ext/prosody/src/handler/context.rs for implementation
35
- class Context
36
- # @private
37
- def initialize
38
- raise NotImplementedError, "This class is implemented natively in Rust"
39
- end
40
-
41
- # Checks if cancellation has been requested.
42
- #
43
- # This method can be called within message handlers to detect when the
44
- # handler should exit. Cancellation includes message-level cancellation
45
- # (e.g., handler timeout) and partition shutdown. During shutdown,
46
- # cancellation is delayed until near the end of the shutdown timeout to
47
- # allow in-flight work to complete.
48
- #
49
- # @return [Boolean] true if cancellation has been requested, false otherwise
50
- #
51
- # @example Checking for cancellation in a loop
52
- # def on_message(context, message)
53
- # items = message.payload["items"]
54
- # items.each do |item|
55
- # return if context.should_cancel?
56
- # process_item(item)
57
- # end
58
- # end
59
- def should_cancel?
60
- raise NotImplementedError, "This method is implemented natively in Rust"
61
- end
62
-
63
- # Blocks until cancellation is signaled.
64
- #
65
- # Cancellation includes message-level cancellation (e.g., handler timeout)
66
- # and partition shutdown. During shutdown, cancellation is delayed until near
67
- # the end of the shutdown timeout to allow in-flight work to complete.
68
- # This method is useful for long-running handlers that need to wait for
69
- # external events while remaining responsive to cancellation.
70
- #
71
- # @return [void]
72
- #
73
- # @example Waiting for cancellation
74
- # def on_message(context, message)
75
- # # Do some work, then wait for cancellation
76
- # context.on_cancel
77
- # end
78
- def on_cancel
79
- raise NotImplementedError, "This method is implemented natively in Rust"
80
- end
81
-
82
- # Schedules a timer to fire at the specified time.
83
- #
84
- # Timers allow you to delay execution or implement timeout behavior within
85
- # your message handlers. When a timer fires, your handler's #on_timer method
86
- # will be called with the timer object.
87
- #
88
- # @param time [Time] When the timer should fire
89
- # @return [void]
90
- # @raise [ArgumentError] If the time is invalid or outside the supported range (1970-2106)
91
- # @raise [RuntimeError] If timer scheduling fails
92
- #
93
- # @example Scheduling a delayed action
94
- # def on_message(context, message)
95
- # # Schedule a timer to fire in 30 seconds
96
- # context.schedule(Time.now + 30)
97
- # end
98
- #
99
- # def on_timer(context, timer)
100
- # puts "Timer fired for key: #{timer.key}"
101
- # end
102
- def schedule(time)
103
- raise NotImplementedError, "This method is implemented natively in Rust"
104
- end
105
-
106
- # Clears all scheduled timers and schedules a new one at the specified time.
107
- #
108
- # This is equivalent to calling clear_scheduled followed by schedule, but
109
- # performed atomically.
110
- #
111
- # @param time [Time] When the new timer should fire
112
- # @return [void]
113
- # @raise [ArgumentError] If the time is invalid or outside the supported range
114
- # @raise [RuntimeError] If timer operations fail
115
- #
116
- # @example Replacing all timers with a new one
117
- # def on_message(context, message)
118
- # # Clear any existing timers and schedule a new one
119
- # context.clear_and_schedule(Time.now + 60)
120
- # end
121
- def clear_and_schedule(time)
122
- raise NotImplementedError, "This method is implemented natively in Rust"
123
- end
124
-
125
- # Unschedules a timer that was scheduled for the specified time.
126
- #
127
- # If multiple timers were scheduled for the same time, this will remove one
128
- # of them. If no timer exists for the specified time, this method does nothing.
129
- #
130
- # @param time [Time] The time for which to unschedule the timer
131
- # @return [void]
132
- # @raise [ArgumentError] If the time is invalid
133
- # @raise [RuntimeError] If timer unscheduling fails
134
- #
135
- # @example Canceling a specific timer
136
- # def on_message(context, message)
137
- # timer_time = Time.now + 30
138
- # context.schedule(timer_time)
139
- #
140
- # # Later, cancel that specific timer
141
- # context.unschedule(timer_time)
142
- # end
143
- def unschedule(time)
144
- raise NotImplementedError, "This method is implemented natively in Rust"
145
- end
146
-
147
- # Clears all scheduled timers.
148
- #
149
- # After calling this method, no timers will be scheduled to fire for this
150
- # message context.
151
- #
152
- # @return [void]
153
- # @raise [RuntimeError] If clearing timers fails
154
- #
155
- # @example Canceling all timers
156
- # def on_message(context, message)
157
- # context.clear_scheduled
158
- # end
159
- def clear_scheduled
160
- raise NotImplementedError, "This method is implemented natively in Rust"
161
- end
162
-
163
- # Returns all currently scheduled timer times.
164
- #
165
- # The returned array contains Time objects representing when each scheduled
166
- # timer will fire. The array may be empty if no timers are scheduled.
167
- #
168
- # @return [Array<Time>] Array of scheduled timer times
169
- # @raise [RuntimeError] If retrieving scheduled times fails
170
- #
171
- # @example Checking scheduled timers
172
- # def on_message(context, message)
173
- # scheduled_times = context.scheduled
174
- # puts "#{scheduled_times.length} timers scheduled"
175
- # scheduled_times.each do |time|
176
- # puts "Timer will fire at: #{time}"
177
- # end
178
- # end
179
- def scheduled
180
- raise NotImplementedError, "This method is implemented natively in Rust"
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
262
- end
263
-
264
- # Represents a Kafka message with its metadata and payload.
265
- #
266
- # Instances of this class are created by the native code and passed to your
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.
270
- #
271
- # @see ext/prosody/src/handler/message.rs for implementation
272
- class Message
273
- # Returns the Kafka topic this message was published to.
274
- #
275
- # @return [String] The topic name
276
- def topic
277
- raise NotImplementedError, "This method is implemented natively in Rust"
278
- end
279
-
280
- # Returns the Kafka partition number for this message.
281
- #
282
- # @return [Integer] The partition number
283
- def partition
284
- raise NotImplementedError, "This method is implemented natively in Rust"
285
- end
286
-
287
- # Returns the Kafka offset of this message within its partition.
288
- #
289
- # @return [Integer] The message offset
290
- def offset
291
- raise NotImplementedError, "This method is implemented natively in Rust"
292
- end
293
-
294
- # Returns the message key used for partitioning.
295
- #
296
- # @return [String] The message key
297
- def key
298
- raise NotImplementedError, "This method is implemented natively in Rust"
299
- end
300
-
301
- # Returns the timestamp when the message was created.
302
- #
303
- # @return [Time] The message timestamp
304
- def timestamp
305
- raise NotImplementedError, "This method is implemented natively in Rust"
306
- end
307
-
308
- # Returns the deserialized message payload.
309
- #
310
- # The payload is automatically deserialized from JSON to Ruby objects.
311
- #
312
- # @return [Payload] The message content
313
- def payload
314
- raise NotImplementedError, "This method is implemented natively in Rust"
315
- end
316
- end
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
-
336
- # Represents a timer that was scheduled to fire at a specific time.
337
- #
338
- # Timer instances are created by the native code and passed to your
339
- # EventHandler's #on_timer method when a scheduled timer fires.
340
- #
341
- # @see ext/prosody/src/handler/trigger.rs for implementation
342
- class Timer
343
- # @private
344
- def initialize
345
- raise NotImplementedError, "This class is implemented natively in Rust"
346
- end
347
-
348
- # Returns the entity key identifying what this timer belongs to.
349
- #
350
- # The key is typically the same as the message key that was being processed
351
- # when the timer was scheduled.
352
- #
353
- # @return [String] The entity key
354
- def key
355
- raise NotImplementedError, "This method is implemented natively in Rust"
356
- end
357
-
358
- # Returns the time when this timer was scheduled to fire.
359
- #
360
- # Note: Due to CompactDateTime's second-level precision, the returned time
361
- # will have zero nanoseconds even if the original scheduled time had
362
- # sub-second precision.
363
- #
364
- # @return [Time] The scheduled execution time
365
- def time
366
- raise NotImplementedError, "This method is implemented natively in Rust"
367
- end
368
- end
369
-
370
- # Main client for interacting with the Prosody messaging system.
371
- # Provides methods for sending messages and subscribing to Kafka topics.
372
- #
373
- # @see ext/prosody/src/client/mod.rs for implementation
374
- class Client
375
- # Creates a new Prosody client with the given configuration.
376
- #
377
- # @param config [Hash, Configuration] Client configuration
378
- # @return [Client] A new client instance
379
- # @raise [ArgumentError] If the configuration is invalid
380
- # @raise [RuntimeError] If client initialization fails
381
- #
382
- # @example Creating a client with a Configuration object
383
- # config = Prosody::Configuration.new do |c|
384
- # c.bootstrap_servers = "localhost:9092"
385
- # c.group_id = "my-consumer-group"
386
- # end
387
- # client = Prosody::Client.new(config)
388
- #
389
- # @example Creating a client with a hash
390
- # client = Prosody::Client.new(
391
- # bootstrap_servers: "localhost:9092",
392
- # group_id: "my-consumer-group"
393
- # )
394
- def self.new(config)
395
- raise NotImplementedError, "This method is implemented natively in Rust"
396
- end
397
-
398
- # Returns the current state of the consumer.
399
- #
400
- # The consumer can be in one of four states:
401
- # - `:shut_down` - The client is shut down
402
- # - `:unconfigured` - The consumer has not been configured yet
403
- # - `:configured` - The consumer is configured but not running
404
- # - `:running` - The consumer is actively consuming messages
405
- #
406
- # @return [Symbol] The current consumer state
407
- def consumer_state
408
- raise NotImplementedError, "This method is implemented natively in Rust"
409
- end
410
-
411
- def native_request(_request)
412
- raise NotImplementedError, "This method is implemented natively in Rust"
413
- end
414
-
415
- # Returns the number of Kafka partitions currently assigned to this consumer.
416
- #
417
- # This method can be used to monitor the consumer's workload and ensure
418
- # proper load balancing across multiple consumer instances.
419
- #
420
- # @return [Integer] The number of assigned partitions
421
- def assigned_partitions
422
- raise NotImplementedError, "This method is implemented natively in Rust"
423
- end
424
-
425
- # Checks if the consumer is stalled.
426
- #
427
- # A stalled consumer is one that has stopped processing messages due to
428
- # errors or reaching processing limits. This can be used to detect unhealthy
429
- # consumers that need attention.
430
- #
431
- # @return [Boolean] true if the consumer is stalled, false otherwise
432
- def is_stalled?
433
- raise NotImplementedError, "This method is implemented natively in Rust"
434
- end
435
-
436
- # Sends a message to the specified Kafka topic.
437
- #
438
- # @param topic [String] The destination topic name
439
- # @param key [String] The message key for partitioning
440
- # @param payload [Prosody::json_value] The JSON-compatible message payload
441
- # @return [void]
442
- # @raise [RuntimeError] If the message cannot be sent
443
- #
444
- # @example Sending a simple message
445
- # client.send_message("my-topic", "user-123", {
446
- # "event" => "login", "timestamp" => Time.now.to_i
447
- # })
448
- def send_message(topic, key, payload)
449
- raise NotImplementedError, "This method is implemented natively in Rust"
450
- end
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
-
462
- # Subscribes to Kafka topics using the provided handler.
463
- # The handler must implement `on_message`, `on_excise`, and `on_timer`.
464
- #
465
- # @param handler [EventHandler] A handler object that processes messages
466
- # @return [void]
467
- # @raise [ArgumentError] If a required handler method is missing
468
- # @raise [RuntimeError] If subscription fails
469
- #
470
- # @example Subscribing with a handler
471
- # class MyHandler < Prosody::EventHandler
472
- # def on_message(context, message)
473
- # puts "Received message: #{message.payload}"
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
482
- # end
483
- #
484
- # client.subscribe(MyHandler.new)
485
- def subscribe(handler)
486
- raise NotImplementedError, "This method is implemented natively in Rust"
487
- end
488
-
489
- # Unsubscribes from all topics, stopping message processing.
490
- #
491
- # This method gracefully shuts down the consumer, completing any in-flight
492
- # messages before stopping.
493
- #
494
- # @return [void]
495
- # @raise [RuntimeError] If unsubscription fails
496
- #
497
- def unsubscribe
498
- raise NotImplementedError, "This method is implemented natively in Rust"
499
- end
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
-
512
- # Returns the configured source system identifier.
513
- #
514
- # The source system is used to identify the originating service or
515
- # component in produced messages, enabling loop detection.
516
- #
517
- # @return [String] The source system identifier
518
- #
519
- # @example Getting the source system
520
- # puts client.source_system # => "my-service"
521
- def source_system
522
- raise NotImplementedError, "This method is implemented natively in Rust"
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
931
- end
932
-
933
- # Internal processor for executing tasks asynchronously.
934
- # This class is used internally by the native code.
935
- #
936
- # @private
937
- class AsyncTaskProcessor
938
- # @private
939
- def initialize(logger = Prosody.logger)
940
- # Actual implementation is in lib/prosody/processor.rb
941
- end
942
-
943
- # @private
944
- def start
945
- # Actual implementation is in lib/prosody/processor.rb
946
- end
947
-
948
- # @private
949
- def stop
950
- # Actual implementation is in lib/prosody/processor.rb
951
- end
952
-
953
- # @private
954
- def submit(task_id, carrier, event_context, callback, &block)
955
- # Actual implementation is in lib/prosody/processor.rb
956
- end
957
- end
958
- end
3
+ # = Native Interface Stubs
4
+ #
5
+ # The files in native_stubs/ document the public classes that the Prosody Rust
6
+ # extension implements. Editors and documentation tools read them. The runtime
7
+ # does not load them, because the native extension defines these classes.
8
+ #
9
+ # The implementations are in the Rust extension at ext/prosody/src/.
10
+
11
+ require_relative "native_stubs/context"
12
+ require_relative "native_stubs/message"
13
+ require_relative "native_stubs/client"