-
Notifications
You must be signed in to change notification settings - Fork 16
03 PLAN
phase: 03-transports plan: "3" wave: 2 dependencies: ["1"] must_haves:
- RedisTransport.md consumer code replaces Log.Log(DotNetWorkQueue.Logging.LogLevel...) with ILogger pattern
- RedisTransport.md links to ConsumerMethod (not ConsumerLinq)
- RedisTransport.md includes one-liner link to MessageHistory
- RedisTransport.md links to samples repo
- RedisOptions.md uses correct property path DelayedProcessingConfiguration.MonitorTime
- RedisOptions.md documents ClearErrorMessagesBatchLimit and all other properties
- RedisOptions.md documents SntpTimeConfiguration nested properties
- RedisPoisonMessages.md consumer code uses QueueConnection and ConsumerQueueNotifications files_touched:
- RedisTransport.md
- RedisOptions.md
- RedisPoisonMessages.md tdd: false
Wave 2 -- Transport pages. Depends on Plan 1 (Transports overview). Can run in parallel with Plans 2, 4-7.
Update `RedisTransport.md` with these changes:
-
Consumer HandleMessages method (line 62-64): Replace the broken logging API call. Change:
private void HandleMessages(IReceivedMessage<SimpleMessage> m, IWorkerNotification n) { n.Log.Log(DotNetWorkQueue.Logging.LogLevel.Debug, () => $"Processing Message {m.Body.Message}"); }
to:
private void HandleMessages(IReceivedMessage<SimpleMessage> message, IWorkerNotification notifications) { notifications.Log.LogDebug($"Processing Message {message.Body.Message}"); }
-
Feature list (lines 8-15): The list is correct but add "History tracking" to match source capabilities. All Redis features are always-on except History (opt-in). Updated list:
- Priority
- Status
- HeartBeat
- Delayed Processing
- Status Table
- Route
- Message Expiration
- History tracking (opt-in)
-
Cross-references: Add after the consumer code sample:
For more consumer patterns, see [ConsumerMethod](https://github.com/blehnen/DotNetWorkQueue/wiki/ConsumerMethod) and [ConsumerAsync](https://github.com/blehnen/DotNetWorkQueue/wiki/ConsumerAsync). If history tracking is enabled, see [MessageHistory](https://github.com/blehnen/DotNetWorkQueue/wiki/MessageHistory) for retention and query options.
-
Samples link: Add at the bottom:
###### Full samples See the [Redis samples](https://github.com/blehnen/DotNetWorkQueue.Samples/tree/main/Source/Samples/Redis) in the DotNetWorkQueue.Samples repository.
Do NOT change: Producer code, queue name/connection string examples.
grep -i "DotNetWorkQueue.Logging.LogLevel|Log.Log(|ConsumerLinq" /mnt/f/git/dotnetworkqueue.wiki/RedisTransport.md; echo "exit: $?" grep returns no matches (exit code 1). RedisTransport.md usesnotifications.Log.LogDebug(...) pattern. Links to ConsumerMethod, MessageHistory, and samples repo are present.
Replace the content of `RedisOptions.md` with complete documentation of `RedisQueueTransportOptions` and `RedisBaseTransportOptions`. The current page is mostly correct but needs the nested property path fixed and missing properties documented.
New content for RedisOptions.md:
#### Redis Options
**NuGet package:** `DotNetWorkQueue.Transport.Redis`
**Options class:** `RedisQueueTransportOptions`
**Namespace:** `DotNetWorkQueue.Transport.Redis.Basic`
##### Always-on features
Unlike the relational transports, Redis features are always enabled. There is no queue creation step required -- queues are created on demand.
| Feature | Value | Notes |
|---------|-------|-------|
| `EnablePriority` | always `true` | |
| `EnableStatus` | always `true` | |
| `EnableHeartBeat` | always `true` | |
| `EnableDelayedProcessing` | always `true` | |
| `EnableStatusTable` | always `true` | |
| `EnableRoute` | always `true` | |
| `EnableMessageExpiration` | always `true` | |
| `EnableHistory` | `false` (settable) | Opt-in history tracking |
When `EnableHistory` is set to `true`, the `HistoryOptions` property (type `HistoryTransportOptions`) controls retention. See [MessageHistory](https://github.com/blehnen/DotNetWorkQueue/wiki/MessageHistory) for the full list of history options.
##### Batch processing limits
These control how many items are processed per LUA script execution on the Redis server.
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `ClearExpiredMessagesBatchLimit` | `int` | `50` | Expired messages removed per batch |
| `ClearErrorMessagesBatchLimit` | `int` | `50` | Error messages removed per batch |
| `MoveDelayedMessagesBatchLimit` | `int` | `50` | Delayed messages promoted per batch |
| `ResetHeartBeatBatchLimit` | `int` | `50` | Dead messages recovered per batch |
```csharp
queue.Configuration.Options().ClearExpiredMessagesBatchLimit = 10;
queue.Configuration.Options().ClearErrorMessagesBatchLimit = 10;
queue.Configuration.Options().MoveDelayedMessagesBatchLimit = 10;
queue.Configuration.Options().ResetHeartBeatBatchLimit = 10;Controls how frequently the transport checks for delayed messages that are ready to process. Lower values reduce latency; higher values reduce Redis load.
queue.Configuration.Options().DelayedProcessingConfiguration.MonitorTime = TimeSpan.FromSeconds(1);The default is TimeSpan.FromSeconds(1).
The Redis transport supports multiple ways to obtain the current time. All time-dependent operations (delayed processing, expiration, heartbeat) use the configured time source.
TimeServer value |
Description |
|---|---|
TimeLocations.LocalMachine (default) |
Uses the local system clock. Only safe if all machines have synchronized clocks. |
TimeLocations.RedisServer |
Uses the Redis server clock. In a cluster, all nodes should be time-synced. |
TimeLocations.SntpServer |
Uses an NTP server. Slowest but safest when clock sync is not guaranteed. |
TimeLocations.Custom |
User-supplied time provider. |
queue.Configuration.Options().TimeServer = TimeLocations.SntpServer;When TimeServer is set to SntpServer, these properties configure the NTP client:
| Property | Type | Default |
|---|---|---|
Server |
string |
"pool.ntp.org" |
Port |
int |
123 |
TimeOut |
TimeSpan |
8 seconds |
queue.Configuration.Options().SntpTimeConfiguration.Server = "time.google.com";
queue.Configuration.Options().SntpTimeConfiguration.Port = 123;Controls how message IDs are generated.
MessageIdLocation value |
Description |
|---|---|
MessageIdLocations.RedisIncr (default) |
Uses Redis INCR for sequential IDs |
MessageIdLocations.Uuid |
Uses client-generated UUIDs |
MessageIdLocations.Custom |
User-supplied ID generator |
queue.Configuration.Options().MessageIdLocation = MessageIdLocations.Uuid;See also: RedisPoisonMessages for custom poison message handling.
Key changes from current:
- `DelayedProcessingMonitorTime` reference corrected to `DelayedProcessingConfiguration.MonitorTime`
- `ClearErrorMessagesBatchLimit` now documented
- `SntpTimeConfiguration` nested properties documented
- `MessageIdLocation` property added
- Always-on features table added
- `EnableHistory` and `HistoryOptions` documented
- Structured with clear sections and property tables
</action>
<verify>grep -c "DelayedProcessingConfiguration\.MonitorTime\|ClearErrorMessagesBatchLimit\|SntpTimeConfiguration\|MessageIdLocation\|EnableHistory" /mnt/f/git/dotnetworkqueue.wiki/RedisOptions.md</verify>
<done>grep returns 5 or more matches. RedisOptions.md documents the correct property path, all batch limits, SNTP config, MessageIdLocation, and EnableHistory.</done>
</task>
---
## Task 3: Update `RedisPoisonMessages.md` consumer code to use current API
<task id="3" files="RedisPoisonMessages.md" tdd="false">
<action>
Update `RedisPoisonMessages.md` with these changes:
1. **IoC injection code sample (lines 88-100):** The consumer creation call on line 93 uses the old 2-argument `CreateConsumer(queueName, connectionString)` pattern. Update to use `QueueConnection`:
Change:
```csharp
var queueName = "example";
var connectionString = "127.0.0.1";
using (var queueContainer = new QueueContainer<RedisQueueInit>(registerService =>
registerService.Register<IReceivePoisonMessage, MoveMessageToFileSystem>(LifeStyles.Singleton)))
{
using (var queue = queueContainer.CreateConsumer(queueName, connectionString))
{
queue.Start<SimpleMessage>(HandleMessages);
```
to:
```csharp
var queueName = "example";
var connectionString = "127.0.0.1";
var queueConnection = new QueueConnection(queueName, connectionString);
using (var queueContainer = new QueueContainer<RedisQueueInit>(registerService =>
registerService.Register<IReceivePoisonMessage, MoveMessageToFileSystem>(LifeStyles.Singleton)))
{
using (var queue = queueContainer.CreateConsumer(queueConnection))
{
var notifications = new ConsumerQueueNotifications(
(n) => Console.WriteLine($"Error: {n.Error}"),
(n) => Console.WriteLine($"Receive error: {n.Error}"),
(n) => Console.WriteLine($"Moved to error queue: {n.MessageId}"),
(n) => Console.WriteLine($"Poison message: {n.MessageId}"),
(n) => Console.WriteLine($"Rollback: {n.MessageId}"),
(n) => Console.WriteLine($"Completed: {n.MessageId}"));
queue.Start<SimpleMessage>(HandleMessages, notifications);
```
2. **Typos:** Fix "messges" to "messages", "implemenations" to "implementations", "belive" to "believe", "posion" to "poison" in the prose text.
**Do NOT change:** The `MoveMessageToFileSystem` class implementation, the `IReceivePoisonMessage` interface, or the file system handling code. These remain valid.
</action>
<verify>grep -c "QueueConnection\|ConsumerQueueNotifications" /mnt/f/git/dotnetworkqueue.wiki/RedisPoisonMessages.md</verify>
<done>grep returns 2 or more matches. RedisPoisonMessages.md uses QueueConnection constructor and includes ConsumerQueueNotifications. Typos are fixed.</done>
</task>
For any issues please use the GitHub issues