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.
- checksums.yaml +4 -4
- data/.config/rail.toml +26 -0
- data/.release-please-manifest.json +1 -1
- data/.ruby-version +1 -1
- data/.taplo.toml +1 -1
- data/AGENTS.md +29 -15
- data/CHANGELOG.md +7 -0
- data/CONFIGURATION.md +19 -16
- data/Cargo.lock +254 -235
- data/Cargo.toml +11 -8
- data/README.md +100 -23
- data/examples/keyed_state.rb +10 -2
- data/examples/keyed_state.rbs +1 -0
- data/ext/prosody/Cargo.toml +1 -1
- data/ext/prosody/src/admin.rs +36 -36
- data/ext/prosody/src/bridge/mod.rs +5 -10
- data/ext/prosody/src/client/config/connections.rs +170 -0
- data/ext/prosody/src/client/config/middleware.rs +184 -0
- data/ext/prosody/src/client/config/mod.rs +396 -0
- data/ext/prosody/src/client/config/state.rs +323 -0
- data/ext/prosody/src/client/mod.rs +31 -117
- data/ext/prosody/src/client/readers.rs +106 -0
- data/ext/prosody/src/client/request.rs +2 -2
- data/ext/prosody/src/client/support.rs +13 -32
- data/ext/prosody/src/gvl.rs +8 -6
- data/ext/prosody/src/handler/{context.rs → context/mod.rs} +36 -150
- data/ext/prosody/src/handler/context/vending.rs +138 -0
- data/ext/prosody/src/handler/message.rs +36 -0
- data/ext/prosody/src/handler/mod.rs +18 -8
- data/ext/prosody/src/handler/state/deque.rs +144 -0
- data/ext/prosody/src/handler/state/mod.rs +163 -268
- data/ext/prosody/src/handler/state/query.rs +264 -0
- data/ext/prosody/src/handler/state/registration.rs +15 -86
- data/ext/prosody/src/handler/state/scan.rs +33 -141
- data/ext/prosody/src/handler/state/set.rs +98 -0
- data/ext/prosody/src/lib.rs +54 -36
- data/ext/prosody/src/logging.rs +6 -6
- data/ext/prosody/src/published.rs +171 -152
- data/ext/prosody/src/scheduler/result.rs +2 -1
- data/ext/prosody/src/util.rs +65 -3
- data/lib/prosody/client.rb +32 -0
- data/lib/prosody/configuration.rb +20 -12
- data/lib/prosody/demand.rb +27 -0
- data/lib/prosody/native_stubs/client.rb +157 -0
- data/lib/prosody/native_stubs/context.rb +178 -0
- data/lib/prosody/native_stubs/message.rb +133 -0
- data/lib/prosody/native_stubs.rb +11 -956
- data/lib/prosody/state/deque.rb +253 -0
- data/lib/prosody/state/map.rb +313 -0
- data/lib/prosody/state/set.rb +121 -0
- data/lib/prosody/state/value.rb +58 -0
- data/lib/prosody/state.rb +157 -677
- data/lib/prosody/version.rb +1 -1
- data/lib/prosody.rb +2 -1
- data/sig/configuration.rbs +19 -10
- data/sig/prosody.rbs +37 -4
- data/sig/published.rbs +102 -0
- data/sig/state.rbs +109 -122
- data/typecheck/payload_types.rb +12 -0
- data/typecheck/payload_types.rbs +1 -0
- metadata +30 -11
- data/ext/prosody/src/client/config.rs +0 -1300
|
@@ -43,8 +43,8 @@ mod state;
|
|
|
43
43
|
mod trigger;
|
|
44
44
|
|
|
45
45
|
pub(crate) use state::{
|
|
46
|
-
NativeJsonDequeScan, NativeJsonMapScan, NativeMapKeyScan,
|
|
47
|
-
|
|
46
|
+
NativeJsonDequeScan, NativeJsonMapScan, NativeMapKeyScan, key_query, position_query, run_state,
|
|
47
|
+
state_error,
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
/// A handler that bridges between Kafka messages and Ruby message processing
|
|
@@ -95,6 +95,7 @@ impl RubyHandler {
|
|
|
95
95
|
&self,
|
|
96
96
|
context: C,
|
|
97
97
|
message: ConsumerMessage<P>,
|
|
98
|
+
demand: DemandType,
|
|
98
99
|
method: &'static str,
|
|
99
100
|
event_type: &'static str,
|
|
100
101
|
span: Span,
|
|
@@ -123,6 +124,7 @@ impl RubyHandler {
|
|
|
123
124
|
context.boxed(),
|
|
124
125
|
self.bridge.clone(),
|
|
125
126
|
self.propagator.clone(),
|
|
127
|
+
demand,
|
|
126
128
|
);
|
|
127
129
|
let response_requested = message.response_requested();
|
|
128
130
|
let message = M::from(message);
|
|
@@ -188,7 +190,7 @@ impl FallibleHandler for RubyHandler {
|
|
|
188
190
|
&self,
|
|
189
191
|
context: C,
|
|
190
192
|
message: ConsumerMessage<Self::Payload>,
|
|
191
|
-
|
|
193
|
+
demand: DemandType,
|
|
192
194
|
) -> Result<Self::Output, Self::Error>
|
|
193
195
|
where
|
|
194
196
|
C: EventContext<Payload = Self::Payload>,
|
|
@@ -201,7 +203,7 @@ impl FallibleHandler for RubyHandler {
|
|
|
201
203
|
offset = message.offset(),
|
|
202
204
|
key = %message.key()
|
|
203
205
|
);
|
|
204
|
-
self.handle_record::<_, _, Message>(context, message, "on_message", "message", span)
|
|
206
|
+
self.handle_record::<_, _, Message>(context, message, demand, "on_message", "message", span)
|
|
205
207
|
.await
|
|
206
208
|
}
|
|
207
209
|
|
|
@@ -209,7 +211,7 @@ impl FallibleHandler for RubyHandler {
|
|
|
209
211
|
&self,
|
|
210
212
|
context: C,
|
|
211
213
|
message: ConsumerMessage<()>,
|
|
212
|
-
|
|
214
|
+
demand: DemandType,
|
|
213
215
|
) -> Result<Self::Output, Self::Error>
|
|
214
216
|
where
|
|
215
217
|
C: EventContext<Payload = Self::Payload>,
|
|
@@ -222,15 +224,22 @@ impl FallibleHandler for RubyHandler {
|
|
|
222
224
|
offset = message.offset(),
|
|
223
225
|
key = %message.key()
|
|
224
226
|
);
|
|
225
|
-
self.handle_record::<_, _, ExciseMessage>(
|
|
226
|
-
|
|
227
|
+
self.handle_record::<_, _, ExciseMessage>(
|
|
228
|
+
context,
|
|
229
|
+
message,
|
|
230
|
+
demand,
|
|
231
|
+
"on_excise",
|
|
232
|
+
"excise",
|
|
233
|
+
span,
|
|
234
|
+
)
|
|
235
|
+
.await
|
|
227
236
|
}
|
|
228
237
|
|
|
229
238
|
async fn on_timer<C>(
|
|
230
239
|
&self,
|
|
231
240
|
context: C,
|
|
232
241
|
trigger: ProsodyTrigger,
|
|
233
|
-
|
|
242
|
+
demand: DemandType,
|
|
234
243
|
) -> Result<Self::Output, Self::Error>
|
|
235
244
|
where
|
|
236
245
|
C: EventContext<Payload = Self::Payload>,
|
|
@@ -269,6 +278,7 @@ impl FallibleHandler for RubyHandler {
|
|
|
269
278
|
context.boxed(),
|
|
270
279
|
self.bridge.clone(),
|
|
271
280
|
self.propagator.clone(),
|
|
281
|
+
demand,
|
|
272
282
|
);
|
|
273
283
|
let timer: Timer = trigger.into();
|
|
274
284
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
//! Native deque handles for JSON and message payloads.
|
|
2
|
+
|
|
3
|
+
use super::{
|
|
4
|
+
NativeJsonDequeScan, NativeMessageDequeScan, json_write_item, message_or_nil,
|
|
5
|
+
message_write_item, outcome_symbol, position_query, run_state, wrapped_class,
|
|
6
|
+
};
|
|
7
|
+
use crate::bridge::Bridge;
|
|
8
|
+
use magnus::{Error, Module, RHash, RModule, Ruby, StaticSymbol, Value, method};
|
|
9
|
+
use opentelemetry::propagation::TextMapCompositePropagator;
|
|
10
|
+
use prosody::consumer::event_context::DynDequeState;
|
|
11
|
+
use prosody::consumer::message::ConsumerMessage;
|
|
12
|
+
use serde_json::Value as JsonValue;
|
|
13
|
+
use serde_magnus::serialize;
|
|
14
|
+
use std::sync::Arc;
|
|
15
|
+
|
|
16
|
+
macro_rules! deque_state {
|
|
17
|
+
($name:ident, $class:literal, $item:ty, $scan:ident, $prepare:expr, $restore:expr) => {
|
|
18
|
+
/// Native deque handle with one payload type.
|
|
19
|
+
#[magnus::wrap(class = $class)]
|
|
20
|
+
pub struct $name {
|
|
21
|
+
state: Arc<dyn DynDequeState<$item>>,
|
|
22
|
+
bridge: Bridge,
|
|
23
|
+
propagator: Arc<TextMapCompositePropagator>,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
impl $name {
|
|
27
|
+
pub(crate) fn new(
|
|
28
|
+
state: Arc<dyn DynDequeState<$item>>,
|
|
29
|
+
bridge: Bridge,
|
|
30
|
+
propagator: Arc<TextMapCompositePropagator>,
|
|
31
|
+
) -> Self {
|
|
32
|
+
Self {
|
|
33
|
+
state,
|
|
34
|
+
bridge,
|
|
35
|
+
propagator,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn len(ruby: &Ruby, this: &Self) -> Result<usize, Error> {
|
|
40
|
+
run_op!(ruby, this, &this.state, len())
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fn is_empty(ruby: &Ruby, this: &Self) -> Result<bool, Error> {
|
|
44
|
+
run_op!(ruby, this, &this.state, is_empty())
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn get(ruby: &Ruby, this: &Self, index: usize) -> Result<Value, Error> {
|
|
48
|
+
($restore)(ruby, run_op!(ruby, this, &this.state, get(index))?)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fn peek_front(ruby: &Ruby, this: &Self) -> Result<Value, Error> {
|
|
52
|
+
($restore)(ruby, run_op!(ruby, this, &this.state, peek_front())?)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
fn peek_back(ruby: &Ruby, this: &Self) -> Result<Value, Error> {
|
|
56
|
+
($restore)(ruby, run_op!(ruby, this, &this.state, peek_back())?)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fn push_back(ruby: &Ruby, this: &Self, value: Value) -> Result<(), Error> {
|
|
60
|
+
let item = ($prepare)(ruby, value)?;
|
|
61
|
+
run_op!(ruby, this, &this.state, push_back(item))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fn push_front(ruby: &Ruby, this: &Self, value: Value) -> Result<(), Error> {
|
|
65
|
+
let item = ($prepare)(ruby, value)?;
|
|
66
|
+
run_op!(ruby, this, &this.state, push_front(item))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fn pop_front(ruby: &Ruby, this: &Self) -> Result<Value, Error> {
|
|
70
|
+
($restore)(ruby, run_op!(ruby, this, &this.state, pop_front())?)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn pop_back(ruby: &Ruby, this: &Self) -> Result<Value, Error> {
|
|
74
|
+
($restore)(ruby, run_op!(ruby, this, &this.state, pop_back())?)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fn clear(ruby: &Ruby, this: &Self) -> Result<(), Error> {
|
|
78
|
+
run_op!(ruby, this, &this.state, clear())
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fn scan(
|
|
82
|
+
ruby: &Ruby,
|
|
83
|
+
this: &Self,
|
|
84
|
+
direction: StaticSymbol,
|
|
85
|
+
options: RHash,
|
|
86
|
+
) -> Result<$scan, Error> {
|
|
87
|
+
let query = position_query(ruby, direction, options)?;
|
|
88
|
+
Ok($scan::new(
|
|
89
|
+
this.state.values().with_query(query).stream(),
|
|
90
|
+
this.bridge.clone(),
|
|
91
|
+
Arc::clone(&this.propagator),
|
|
92
|
+
))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fn commit(ruby: &Ruby, this: &Self) -> Result<StaticSymbol, Error> {
|
|
96
|
+
let outcome = run_op!(ruby, this, &this.state, commit())?;
|
|
97
|
+
Ok(outcome_symbol(ruby, outcome))
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn rollback(ruby: &Ruby, this: &Self) -> Result<StaticSymbol, Error> {
|
|
101
|
+
let state = Arc::clone(&this.state);
|
|
102
|
+
let outcome = run_state(ruby, &this.bridge, &this.propagator, async move {
|
|
103
|
+
Ok(state.rollback().await)
|
|
104
|
+
})?;
|
|
105
|
+
Ok(outcome_symbol(ruby, outcome))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
pub(super) fn register(ruby: &Ruby, module: RModule) -> Result<(), Error> {
|
|
109
|
+
let class = wrapped_class(ruby, module, $class)?;
|
|
110
|
+
class.define_method("len", method!($name::len, 0))?;
|
|
111
|
+
class.define_method("is_empty", method!($name::is_empty, 0))?;
|
|
112
|
+
class.define_method("get", method!($name::get, 1))?;
|
|
113
|
+
class.define_method("peek_front", method!($name::peek_front, 0))?;
|
|
114
|
+
class.define_method("peek_back", method!($name::peek_back, 0))?;
|
|
115
|
+
class.define_method("push_back", method!($name::push_back, 1))?;
|
|
116
|
+
class.define_method("push_front", method!($name::push_front, 1))?;
|
|
117
|
+
class.define_method("pop_front", method!($name::pop_front, 0))?;
|
|
118
|
+
class.define_method("pop_back", method!($name::pop_back, 0))?;
|
|
119
|
+
class.define_method("clear", method!($name::clear, 0))?;
|
|
120
|
+
class.define_method("scan", method!($name::scan, 2))?;
|
|
121
|
+
class.define_method("commit", method!($name::commit, 0))?;
|
|
122
|
+
class.define_method("rollback", method!($name::rollback, 0))?;
|
|
123
|
+
Ok(())
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
deque_state!(
|
|
130
|
+
NativeJsonDequeState,
|
|
131
|
+
"Prosody::NativeJsonDequeState",
|
|
132
|
+
JsonValue,
|
|
133
|
+
NativeJsonDequeScan,
|
|
134
|
+
json_write_item,
|
|
135
|
+
|ruby, item| serialize::<_, Value>(ruby, &item)
|
|
136
|
+
);
|
|
137
|
+
deque_state!(
|
|
138
|
+
NativeMessageDequeState,
|
|
139
|
+
"Prosody::NativeMessageDequeState",
|
|
140
|
+
ConsumerMessage<JsonValue>,
|
|
141
|
+
NativeMessageDequeScan,
|
|
142
|
+
|ruby, value| message_write_item(ruby, value, " to push into a message deque"),
|
|
143
|
+
|ruby, item| Ok::<_, Error>(message_or_nil(ruby, item))
|
|
144
|
+
);
|