#### [Abblix\.SharedSignals\.Redis](https://www.abblix.com/en/docs/api/abblix-sharedsignals-redis 'index')
### [Abblix\.SharedSignals\.Redis](https://www.abblix.com/en/docs/api/abblix-sharedsignals-redis/Abblix.SharedSignals.Redis 'Abblix\.SharedSignals\.Redis')

## RedisEventOutbox Class

The outbox on Redis's own structures: a list carries each stream's order, a hash carries the
items, and every mutation is a server\-side operation \- append, remove\-by\-value, field delete \- so
concurrent transmitter REPLICAS compose instead of overwriting each other, which is the hole a
whole\-queue\-as\-one\-value implementation cannot close\.

```csharp
public sealed class RedisEventOutbox : Abblix.SharedSignals.Transmitter.IEventOutbox
```

Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') → RedisEventOutbox

Implements [IEventOutbox](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.IEventOutbox 'Abblix\.SharedSignals\.Transmitter\.IEventOutbox')

### Remarks

The mutations run as server-side scripts rather than MULTI/EXEC, and the difference is what
            the caller is told. Redis has no rollback in either form: a command that fails at execution time
            does not undo its predecessors. But a transaction reports that failure only inside the EXEC reply,
            which a caller discarding the per-command tasks never reads - so a half-applied enqueue returned
            success, and the signed event sat in the hash unreachable forever. A script's error reaches the
            caller instead. What remains possible is a partial write, so the order is chosen to make the
            survivor harmless: the payload is stored first and listed second, because a payload nobody listed
            is invisible and expires, while a listing whose payload never arrived would be served forever and
            never acknowledged.

The queue and item keys of one stream share a cluster hash tag, so they land on one slot and
            the multi-key scripts here stay valid under Redis Cluster.

Losing Redis loses pending events, and the tier is deliberate. SSF 1.0 Section 8.1.2.1 lets a
            transmitter drop events it holds while a stream is PAUSED; for an enabled stream the same section
            requires transmission, so treating the whole queue as cache-tier is our decision rather than a
            permission the specification grants. It follows the delivery protocols' own tolerance for
            redelivery and loss over a broken transport, and it is why the queue belongs beside caches rather
            than beside data that earns backups.
### Constructors

## RedisEventOutbox\(IConnectionMultiplexer, RedisOutboxOptions\) Constructor {#Abblix.SharedSignals.Redis.RedisEventOutbox.RedisEventOutbox(StackExchange.Redis.IConnectionMultiplexer,Abblix.SharedSignals.Redis.RedisOutboxOptions)}

The outbox on Redis's own structures: a list carries each stream's order, a hash carries the
items, and every mutation is a server\-side operation \- append, remove\-by\-value, field delete \- so
concurrent transmitter REPLICAS compose instead of overwriting each other, which is the hole a
whole\-queue\-as\-one\-value implementation cannot close\.

```csharp
public RedisEventOutbox(StackExchange.Redis.IConnectionMultiplexer connection, Abblix.SharedSignals.Redis.RedisOutboxOptions options);
```
#### Parameters

###### `connection` [StackExchange\.Redis\.IConnectionMultiplexer](https://learn.microsoft.com/en-us/dotnet/api/stackexchange.redis.iconnectionmultiplexer 'StackExchange\.Redis\.IConnectionMultiplexer') {#Abblix.SharedSignals.Redis.RedisEventOutbox.RedisEventOutbox(StackExchange.Redis.IConnectionMultiplexer,Abblix.SharedSignals.Redis.RedisOutboxOptions).connection}

The Redis connection; opening and configuring it is the host's\.

###### `options` [RedisOutboxOptions](https://www.abblix.com/en/docs/api/abblix-sharedsignals-redis/Abblix.SharedSignals.Redis.RedisOutboxOptions 'Abblix\.SharedSignals\.Redis\.RedisOutboxOptions') {#Abblix.SharedSignals.Redis.RedisEventOutbox.RedisEventOutbox(StackExchange.Redis.IConnectionMultiplexer,Abblix.SharedSignals.Redis.RedisOutboxOptions).options}

What the queue may keep, and for how long\.

### Remarks

The mutations run as server-side scripts rather than MULTI/EXEC, and the difference is what
            the caller is told. Redis has no rollback in either form: a command that fails at execution time
            does not undo its predecessors. But a transaction reports that failure only inside the EXEC reply,
            which a caller discarding the per-command tasks never reads - so a half-applied enqueue returned
            success, and the signed event sat in the hash unreachable forever. A script's error reaches the
            caller instead. What remains possible is a partial write, so the order is chosen to make the
            survivor harmless: the payload is stored first and listed second, because a payload nobody listed
            is invisible and expires, while a listing whose payload never arrived would be served forever and
            never acknowledged.

The queue and item keys of one stream share a cluster hash tag, so they land on one slot and
            the multi-key scripts here stay valid under Redis Cluster.

Losing Redis loses pending events, and the tier is deliberate. SSF 1.0 Section 8.1.2.1 lets a
            transmitter drop events it holds while a stream is PAUSED; for an enabled stream the same section
            requires transmission, so treating the whole queue as cache-tier is our decision rather than a
            permission the specification grants. It follows the delivery protocols' own tolerance for
            redelivery and loss over a broken transport, and it is why the queue belongs beside caches rather
            than beside data that earns backups.
### Methods

## RedisEventOutbox\.AcknowledgeAsync\(string, string, IReadOnlyCollection\<string\>, CancellationToken\) Method {#Abblix.SharedSignals.Redis.RedisEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken)}

Removes acknowledged SETs from a stream's queue, releasing the transmitter from
retaining them \(RFC 8936 Section 2\.2\)\. Identifiers with nothing to match are ignored \-
an acknowledgement can only arrive for something that was once here\.

```csharp
public System.Threading.Tasks.Task AcknowledgeAsync(string receiverId, string streamId, System.Collections.Generic.IReadOnlyCollection<string> jwtIds, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
```
#### Parameters

###### `receiverId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken).receiverId}

The receiver the stream belongs to\.

###### `streamId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken).streamId}

The stream whose queue is acknowledged\.

###### `jwtIds` [System\.Collections\.Generic\.IReadOnlyCollection&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlycollection-1 'System\.Collections\.Generic\.IReadOnlyCollection\`1')[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlycollection-1 'System\.Collections\.Generic\.IReadOnlyCollection\`1') {#Abblix.SharedSignals.Redis.RedisEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken).jwtIds}

The "jti" values being acknowledged\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.SharedSignals.Redis.RedisEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken).cancellationToken}

Cancels I/O a durable implementation performs\.

Implements [AcknowledgeAsync\(string, string, IReadOnlyCollection&lt;string&gt;, CancellationToken\)](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.IEventOutbox#Abblix.SharedSignals.Transmitter.IEventOutbox.AcknowledgeAsync(string,string,System.Collections.Generic.IReadOnlyCollection_string_,System.Threading.CancellationToken) 'Abblix\.SharedSignals\.Transmitter\.IEventOutbox\.AcknowledgeAsync\(System\.String,System\.String,System\.Collections\.Generic\.IReadOnlyCollection\{System\.String\},System\.Threading\.CancellationToken\)')

#### Returns
[System\.Threading\.Tasks\.Task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 'System\.Threading\.Tasks\.Task')

## RedisEventOutbox\.ClearAsync\(string, string, CancellationToken\) Method {#Abblix.SharedSignals.Redis.RedisEventOutbox.ClearAsync(string,string,System.Threading.CancellationToken)}

Drops a stream's whole queue \- the companion of deleting or disabling the stream, whose
events are not held for later \(SSF 1\.0 Sections 8\.1\.1\.5, 8\.1\.2\.1\)\.

```csharp
public System.Threading.Tasks.Task ClearAsync(string receiverId, string streamId, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
```
#### Parameters

###### `receiverId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.ClearAsync(string,string,System.Threading.CancellationToken).receiverId}

The receiver the stream belongs to\.

###### `streamId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.ClearAsync(string,string,System.Threading.CancellationToken).streamId}

The stream whose queue is dropped\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.SharedSignals.Redis.RedisEventOutbox.ClearAsync(string,string,System.Threading.CancellationToken).cancellationToken}

Cancels I/O a durable implementation performs\.

Implements [ClearAsync\(string, string, CancellationToken\)](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.IEventOutbox#Abblix.SharedSignals.Transmitter.IEventOutbox.ClearAsync(string,string,System.Threading.CancellationToken) 'Abblix\.SharedSignals\.Transmitter\.IEventOutbox\.ClearAsync\(System\.String,System\.String,System\.Threading\.CancellationToken\)')

#### Returns
[System\.Threading\.Tasks\.Task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 'System\.Threading\.Tasks\.Task')

## RedisEventOutbox\.EnqueueAsync\(string, string, OutboxItem, CancellationToken\) Method {#Abblix.SharedSignals.Redis.RedisEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken)}

Appends a SET to a stream's queue\.

```csharp
public System.Threading.Tasks.Task EnqueueAsync(string receiverId, string streamId, Abblix.SharedSignals.Transmitter.OutboxItem item, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
```
#### Parameters

###### `receiverId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken).receiverId}

The receiver the stream belongs to\.

###### `streamId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken).streamId}

The stream the SET was minted for\.

###### `item` [OutboxItem](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.OutboxItem 'Abblix\.SharedSignals\.Transmitter\.OutboxItem') {#Abblix.SharedSignals.Redis.RedisEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken).item}

The minted SET\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.SharedSignals.Redis.RedisEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken).cancellationToken}

Cancels I/O a durable implementation performs\.

Implements [EnqueueAsync\(string, string, OutboxItem, CancellationToken\)](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.IEventOutbox#Abblix.SharedSignals.Transmitter.IEventOutbox.EnqueueAsync(string,string,Abblix.SharedSignals.Transmitter.OutboxItem,System.Threading.CancellationToken) 'Abblix\.SharedSignals\.Transmitter\.IEventOutbox\.EnqueueAsync\(System\.String,System\.String,Abblix\.SharedSignals\.Transmitter\.OutboxItem,System\.Threading\.CancellationToken\)')

#### Returns
[System\.Threading\.Tasks\.Task](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task 'System\.Threading\.Tasks\.Task')

## RedisEventOutbox\.PendingAsync\(string, string, Nullable\<int\>, CancellationToken\) Method {#Abblix.SharedSignals.Redis.RedisEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken)}

Reads the unacknowledged head of a stream's queue, oldest first, without removing
anything \- redelivery of the unacknowledged is the delivery protocols' own semantics\.

```csharp
public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Abblix.SharedSignals.Transmitter.OutboxItem>> PendingAsync(string receiverId, string streamId, System.Nullable<int> maxCount=null, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
```
#### Parameters

###### `receiverId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken).receiverId}

The receiver the stream belongs to\.

###### `streamId` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.SharedSignals.Redis.RedisEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken).streamId}

The stream whose queue is read\.

###### `maxCount` [System\.Nullable&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1')[System\.Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32 'System\.Int32')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.nullable-1 'System\.Nullable\`1') {#Abblix.SharedSignals.Redis.RedisEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken).maxCount}

The most items to return; null returns everything pending, mirroring an absent
"maxEvents" \(RFC 8936 Section 2\.2\)\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.SharedSignals.Redis.RedisEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken).cancellationToken}

Cancels I/O a durable implementation performs\.

Implements [PendingAsync\(string, string, Nullable&lt;int&gt;, CancellationToken\)](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.IEventOutbox#Abblix.SharedSignals.Transmitter.IEventOutbox.PendingAsync(string,string,System.Nullable_int_,System.Threading.CancellationToken) 'Abblix\.SharedSignals\.Transmitter\.IEventOutbox\.PendingAsync\(System\.String,System\.String,System\.Nullable\{System\.Int32\},System\.Threading\.CancellationToken\)')

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[System\.Collections\.Generic\.IReadOnlyList&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlylist-1 'System\.Collections\.Generic\.IReadOnlyList\`1')[OutboxItem](https://www.abblix.com/en/docs/api/abblix-sharedsignals/Abblix.SharedSignals.Transmitter.OutboxItem 'Abblix\.SharedSignals\.Transmitter\.OutboxItem')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.ireadonlylist-1 'System\.Collections\.Generic\.IReadOnlyList\`1')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')
