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
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
//! Conversion of [`NativeConfiguration`] into the Kafka producer, Kafka
|
|
2
|
+
//! consumer, Cassandra, and telemetry emitter builders.
|
|
3
|
+
|
|
4
|
+
use super::{NativeConfiguration, ProbePort};
|
|
5
|
+
use crate::util::seconds;
|
|
6
|
+
use prosody::cassandra::config::CassandraConfigurationBuilder;
|
|
7
|
+
use prosody::consumer::ConsumerConfigurationBuilder;
|
|
8
|
+
use prosody::producer::ProducerConfigurationBuilder;
|
|
9
|
+
use prosody::telemetry::emitter::TelemetryEmitterConfiguration;
|
|
10
|
+
|
|
11
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for ProducerConfigurationBuilder {
|
|
12
|
+
type Error = String;
|
|
13
|
+
|
|
14
|
+
/// Reads the Kafka producer settings.
|
|
15
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
16
|
+
let mut builder = Self::default();
|
|
17
|
+
|
|
18
|
+
if let Some(bootstrap_servers) = &config.bootstrap_servers {
|
|
19
|
+
builder.bootstrap_servers(bootstrap_servers.clone());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if let Some(send_timeout) = &config.send_timeout {
|
|
23
|
+
builder.send_timeout(seconds("send_timeout", *send_timeout)?);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if let Some(idempotence_cache_size) = &config.idempotence_cache_size {
|
|
27
|
+
builder.idempotence_cache_size(*idempotence_cache_size as usize);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if let Some(source_system) = &config.source_system {
|
|
31
|
+
builder.source_system(source_system.clone());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if let Some(mock) = &config.mock {
|
|
35
|
+
builder.mock(*mock);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Ok(builder)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for ConsumerConfigurationBuilder {
|
|
43
|
+
type Error = String;
|
|
44
|
+
|
|
45
|
+
/// Reads the Kafka consumer settings.
|
|
46
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
47
|
+
let mut builder = Self::default();
|
|
48
|
+
|
|
49
|
+
if let Some(bootstrap_servers) = &config.bootstrap_servers {
|
|
50
|
+
builder.bootstrap_servers(bootstrap_servers.clone());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if let Some(group_id) = &config.group_id {
|
|
54
|
+
builder.group_id(group_id.clone());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if let Some(subscribed_topics) = &config.subscribed_topics {
|
|
58
|
+
builder.subscribed_topics(subscribed_topics.clone());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if let Some(allowed_events) = &config.allowed_events {
|
|
62
|
+
builder.allowed_events(allowed_events.clone());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if let Some(max_uncommitted) = &config.max_uncommitted {
|
|
66
|
+
builder.max_uncommitted(*max_uncommitted as usize);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if let Some(stall_threshold) = &config.stall_threshold {
|
|
70
|
+
builder.stall_threshold(seconds("stall_threshold", *stall_threshold)?);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if let Some(shutdown_timeout) = &config.shutdown_timeout {
|
|
74
|
+
builder.shutdown_timeout(seconds("shutdown_timeout", *shutdown_timeout)?);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if let Some(poll_interval) = &config.poll_interval {
|
|
78
|
+
builder.poll_interval(seconds("poll_interval", *poll_interval)?);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if let Some(commit_interval) = &config.commit_interval {
|
|
82
|
+
builder.commit_interval(seconds("commit_interval", *commit_interval)?);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if let Some(statistics_interval) = &config.statistics_interval {
|
|
86
|
+
builder.statistics_interval(seconds("statistics_interval", *statistics_interval)?);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if let Some(mock) = &config.mock {
|
|
90
|
+
builder.mock(*mock);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if let Some(probe_port) = &config.probe_port {
|
|
94
|
+
match probe_port {
|
|
95
|
+
ProbePort::Unconfigured => {}
|
|
96
|
+
ProbePort::Disabled => {
|
|
97
|
+
builder.probe_port(None);
|
|
98
|
+
}
|
|
99
|
+
ProbePort::Configured(port) => {
|
|
100
|
+
builder.probe_port(*port);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if let Some(slab_size) = &config.slab_size {
|
|
106
|
+
builder.slab_size(seconds("slab_size", *slab_size)?);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Ok(builder)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for CassandraConfigurationBuilder {
|
|
114
|
+
type Error = String;
|
|
115
|
+
|
|
116
|
+
/// Reads the Cassandra settings.
|
|
117
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
118
|
+
let mut builder = Self::default();
|
|
119
|
+
|
|
120
|
+
if let Some(nodes) = &config.cassandra_nodes {
|
|
121
|
+
builder.nodes(nodes.clone());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if let Some(keyspace) = &config.cassandra_keyspace {
|
|
125
|
+
builder.keyspace(keyspace.clone());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if let Some(datacenter) = &config.cassandra_datacenter {
|
|
129
|
+
builder.datacenter(Some(datacenter.clone()));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if let Some(rack) = &config.cassandra_rack {
|
|
133
|
+
builder.rack(Some(rack.clone()));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if let Some(user) = &config.cassandra_user {
|
|
137
|
+
builder.user(Some(user.clone()));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if let Some(password) = &config.cassandra_password {
|
|
141
|
+
builder.password(Some(password.clone()));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if let Some(retention) = &config.cassandra_retention {
|
|
145
|
+
builder.retention(seconds("cassandra_retention", *retention)?);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Ok(builder)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for TelemetryEmitterConfiguration {
|
|
153
|
+
type Error = String;
|
|
154
|
+
|
|
155
|
+
/// Reads the telemetry emitter settings. Environment variables fill unset
|
|
156
|
+
/// fields.
|
|
157
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
158
|
+
let mut builder = Self::builder();
|
|
159
|
+
|
|
160
|
+
if let Some(topic) = &config.telemetry_topic {
|
|
161
|
+
builder.topic(topic.clone());
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if let Some(enabled) = &config.telemetry_enabled {
|
|
165
|
+
builder.enabled(*enabled);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
builder.build().map_err(|e| e.to_string())
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
//! Conversion of [`NativeConfiguration`] into the retry, failure topic,
|
|
2
|
+
//! scheduler, monopolization, defer, timeout, and deduplication middleware
|
|
3
|
+
//! builders.
|
|
4
|
+
|
|
5
|
+
use super::NativeConfiguration;
|
|
6
|
+
use crate::util::seconds;
|
|
7
|
+
use prosody::consumer::middleware::deduplication::DeduplicationConfigurationBuilder;
|
|
8
|
+
use prosody::consumer::middleware::defer::DeferConfigurationBuilder;
|
|
9
|
+
use prosody::consumer::middleware::monopolization::MonopolizationConfigurationBuilder;
|
|
10
|
+
use prosody::consumer::middleware::retry::RetryConfigurationBuilder;
|
|
11
|
+
use prosody::consumer::middleware::scheduler::SchedulerConfigurationBuilder;
|
|
12
|
+
use prosody::consumer::middleware::timeout::TimeoutConfigurationBuilder;
|
|
13
|
+
use prosody::consumer::middleware::topic::FailureTopicConfigurationBuilder;
|
|
14
|
+
use std::num::NonZeroUsize;
|
|
15
|
+
|
|
16
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for RetryConfigurationBuilder {
|
|
17
|
+
type Error = String;
|
|
18
|
+
|
|
19
|
+
/// Reads the retry settings.
|
|
20
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
21
|
+
let mut builder = Self::default();
|
|
22
|
+
|
|
23
|
+
if let Some(retry_base) = &config.retry_base {
|
|
24
|
+
builder.base(seconds("retry_base", *retry_base)?);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if let Some(max_retries) = &config.max_retries {
|
|
28
|
+
builder.max_retries(*max_retries);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if let Some(max_retry_delay) = &config.max_retry_delay {
|
|
32
|
+
builder.max_delay(seconds("max_retry_delay", *max_retry_delay)?);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Ok(builder)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
impl<'a> From<&'a NativeConfiguration> for FailureTopicConfigurationBuilder {
|
|
40
|
+
/// Reads the failure topic setting.
|
|
41
|
+
fn from(config: &'a NativeConfiguration) -> Self {
|
|
42
|
+
let mut builder = Self::default();
|
|
43
|
+
|
|
44
|
+
if let Some(failure_topic) = &config.failure_topic {
|
|
45
|
+
builder.failure_topic(failure_topic.clone());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
builder
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for SchedulerConfigurationBuilder {
|
|
53
|
+
type Error = String;
|
|
54
|
+
|
|
55
|
+
/// Reads the scheduler settings.
|
|
56
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
57
|
+
let mut builder = Self::default();
|
|
58
|
+
|
|
59
|
+
if let Some(max_concurrency) = &config.max_concurrency {
|
|
60
|
+
builder.max_concurrency(*max_concurrency as usize);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if let Some(failure_weight) = &config.scheduler_failure_weight {
|
|
64
|
+
builder.failure_weight(*failure_weight);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if let Some(max_wait) = &config.scheduler_max_wait {
|
|
68
|
+
builder.max_wait(seconds("scheduler_max_wait", *max_wait)?);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if let Some(wait_weight) = &config.scheduler_wait_weight {
|
|
72
|
+
builder.wait_weight(*wait_weight);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if let Some(cache_size) = &config.scheduler_cache_size {
|
|
76
|
+
builder.cache_size(*cache_size as usize);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Ok(builder)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for MonopolizationConfigurationBuilder {
|
|
84
|
+
type Error = String;
|
|
85
|
+
|
|
86
|
+
/// Reads the monopolization settings.
|
|
87
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
88
|
+
let mut builder = Self::default();
|
|
89
|
+
|
|
90
|
+
if let Some(enabled) = &config.monopolization_enabled {
|
|
91
|
+
builder.enabled(*enabled);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if let Some(threshold) = &config.monopolization_threshold {
|
|
95
|
+
builder.monopolization_threshold(*threshold);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if let Some(window) = &config.monopolization_window {
|
|
99
|
+
builder.window_duration(seconds("monopolization_window", *window)?);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if let Some(cache_size) = &config.monopolization_cache_size {
|
|
103
|
+
builder.cache_size(*cache_size as usize);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Ok(builder)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for DeferConfigurationBuilder {
|
|
111
|
+
type Error = String;
|
|
112
|
+
|
|
113
|
+
/// Reads the defer settings.
|
|
114
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
115
|
+
let mut builder = Self::default();
|
|
116
|
+
|
|
117
|
+
if let Some(enabled) = &config.defer_enabled {
|
|
118
|
+
builder.enabled(*enabled);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if let Some(base) = &config.defer_base {
|
|
122
|
+
builder.base(seconds("defer_base", *base)?);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if let Some(max_delay) = &config.defer_max_delay {
|
|
126
|
+
builder.max_delay(seconds("defer_max_delay", *max_delay)?);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if let Some(failure_threshold) = &config.defer_failure_threshold {
|
|
130
|
+
builder.failure_threshold(*failure_threshold);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if let Some(failure_window) = &config.defer_failure_window {
|
|
134
|
+
builder.failure_window(seconds("defer_failure_window", *failure_window)?);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if let Some(store_cache_size) = &config.defer_store_cache_size {
|
|
138
|
+
builder.store_cache_size(*store_cache_size as usize);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Ok(builder)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for TimeoutConfigurationBuilder {
|
|
146
|
+
type Error = String;
|
|
147
|
+
|
|
148
|
+
/// Reads the handler timeout setting.
|
|
149
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
150
|
+
let mut builder = Self::default();
|
|
151
|
+
|
|
152
|
+
if let Some(timeout) = &config.timeout {
|
|
153
|
+
builder.timeout(Some(seconds("timeout", *timeout)?));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Ok(builder)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
impl<'a> TryFrom<&'a NativeConfiguration> for DeduplicationConfigurationBuilder {
|
|
161
|
+
type Error = String;
|
|
162
|
+
|
|
163
|
+
/// Reads the deduplication settings. Core deduplication is mandatory, so an
|
|
164
|
+
/// `idempotence_cache_size` of `0` fails.
|
|
165
|
+
fn try_from(config: &'a NativeConfiguration) -> Result<Self, Self::Error> {
|
|
166
|
+
let mut builder = Self::default();
|
|
167
|
+
|
|
168
|
+
if let Some(cache_capacity) = &config.idempotence_cache_size {
|
|
169
|
+
let cache_capacity = NonZeroUsize::new(*cache_capacity as usize)
|
|
170
|
+
.ok_or_else(|| "idempotence_cache_size must be greater than 0".to_owned())?;
|
|
171
|
+
builder.cache_capacity(cache_capacity);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if let Some(version) = &config.idempotence_version {
|
|
175
|
+
builder.version(version.clone());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if let Some(ttl) = &config.idempotence_ttl {
|
|
179
|
+
builder.ttl(seconds("idempotence_ttl", *ttl)?);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
Ok(builder)
|
|
183
|
+
}
|
|
184
|
+
}
|