diff --git a/build.gradle b/build.gradle
index deb11a773d..8152aec1a9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -66,7 +66,8 @@ dependencies {
implementation 'io.seqera:lib-crypto:1.0.0'
implementation 'io.seqera:jedis-lock:1.0.0'
implementation 'io.seqera:lib-data-queue-redis:1.1.2'
- implementation 'io.seqera:lib-data-stream-redis:1.2.0'
+ implementation 'io.seqera:lib-data-workqueue:2.0.0'
+ implementation 'io.seqera:lib-data-workqueue-redis:2.0.0'
implementation 'io.seqera:lib-data-range-redis:1.1.0'
implementation 'io.seqera:lib-jedis-pool:1.0.0'
implementation 'io.micronaut:micronaut-http-client'
diff --git a/docs/configuration.md b/docs/configuration.md
index 118c6702f9..279fa819b9 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -587,14 +587,17 @@ Configure polling and scheduling intervals for Wave's asynchronous job processin
`wave.job-manager.scheduler-interval` *(optional)*
: Interval for the job scheduler to process queued jobs (default: `1s`).
-## Message stream
+## Work queue
-Configure how Wave consumes messages from the Redis stream used for internal event processing.
+Configure how Wave consumes messages from the Redis backed work queue used for internal job processing.
-`wave.message-stream.claim-timeout` *(optional)*
-: Timeout for claiming messages from the Redis stream (default: `5s`).
+`wave.work-queue.consumer-group-name` *(optional)*
+: Name of the Redis consumer group used to read the work queues (default: `wave-message-stream`).
-`wave.message-stream.consume-warn-timeout` *(optional)*
+`wave.work-queue.visibility-timeout` *(optional)*
+: How long a claimed message stays invisible to other consumers before it is redelivered (default: `5s`).
+
+`wave.work-queue.consumer-warn-timeout` *(optional)*
: Threshold duration after which a slow message consumer triggers a warning (default: `4s`).
## Thread monitor
diff --git a/src/main/groovy/io/seqera/wave/service/data/stream/RedisStreamConfigBean.groovy b/src/main/groovy/io/seqera/wave/service/data/stream/RedisStreamConfigBean.groovy
deleted file mode 100644
index 785574cbd3..0000000000
--- a/src/main/groovy/io/seqera/wave/service/data/stream/RedisStreamConfigBean.groovy
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Wave, containers provisioning service
- * Copyright (c) 2023-2025, Seqera Labs
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see
This configuration provides centralized settings for Redis Stream-based - * messaging components, including consumer group management and timeout - * configurations. The configuration values are injected from application - * properties with sensible defaults. - * - *
Configuration properties: - *
Example application configuration: - *
- * # application.yml - * wave: - * message-stream: - * consumer-group-name: "wave-prod-stream" - * claim-timeout: "10s" - * consume-warn-timeout: "8s" - *- * - *
This bean implements {@link RedisStreamConfig} to provide configuration
- * values to Redis Stream components throughout the application.
- *
- * @author Paolo Di Tommaso This class extends {@link AbstractMessageStream} and provides a foundation for
- * creating type-safe message streams with automatic JSON serialization/deserialization
+ * Base abstract class for implementing work queues in the Wave application.
+ *
+ * This class extends {@link AbstractWorkQueue} and provides a foundation for
+ * creating type-safe work queues with automatic JSON serialization/deserialization
* using the Moshi library. It handles the encoding strategy configuration and
- * provides a consistent interface for message stream implementations. Message streams are used for real-time message processing and event handling,
- * allowing for continuous data flow and stream-based operations. Concrete implementations
- * should extend this class to define specific streaming behavior and message processing logic.
Work queues deliver each message to exactly one consumer at a time under a + * message lease: a message is removed from the queue only when the consumer settles + * it as acknowledged, and is otherwise redelivered once the lease expires. Concrete + * implementations should extend this class to define specific queueing behaviour and + * message processing logic.
+ * + * @paramThis method uses reflection to determine the generic type parameter {@code M} * and creates a Moshi-based encoding strategy that can handle the automatic * conversion between the strongly-typed message objects and their JSON string - * representations for streaming operations.
- * + * representations for queueing operations. + * * @return a new instance of {@link StringEncodingStrategy} configured for type {@code M} */ @Override diff --git a/src/main/groovy/io/seqera/wave/service/data/workqueue/RedisWorkQueueConfigBean.groovy b/src/main/groovy/io/seqera/wave/service/data/workqueue/RedisWorkQueueConfigBean.groovy new file mode 100644 index 0000000000..19c8193e7a --- /dev/null +++ b/src/main/groovy/io/seqera/wave/service/data/workqueue/RedisWorkQueueConfigBean.groovy @@ -0,0 +1,77 @@ +/* + * Wave, containers provisioning service + * Copyright (c) 2023-2025, Seqera Labs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, seeThis configuration provides centralized settings for Redis work queue + * components, including consumer group management and lease timings. The + * configuration values are injected from application properties with sensible + * defaults. + * + *
Configuration properties: + *
Note the consumer group name default is intentionally {@code wave-message-stream}: + * the work queue reuses the Redis streams and consumer group created by the message + * stream implementation it replaces, so messages queued before an upgrade are still + * delivered afterwards. + * + *
Example application configuration: + *
+ * # application.yml + * wave: + * work-queue: + * consumer-group-name: "wave-prod-queue" + * visibility-timeout: "10s" + * consumer-warn-timeout: "8s" + *+ * + *
This bean implements {@link RedisWorkQueueConfig} to provide configuration
+ * values to Redis work queue components throughout the application.
+ *
+ * @author Paolo Di Tommaso