Add bulk MXAccess subscription commands

This commit is contained in:
Joseph Doherty
2026-04-26 22:29:27 -04:00
parent daff16cfd2
commit 3d11ac3316
31 changed files with 14346 additions and 969 deletions
@@ -247,6 +247,120 @@ public sealed class GatewaySession
return await workerClient.InvokeAsync(command, CommandTimeout, cancellationToken).ConfigureAwait(false);
}
public Task<IReadOnlyList<SubscribeResult>> AddItemBulkAsync(
int serverHandle,
IReadOnlyList<string> tagAddresses,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(tagAddresses);
AddItemBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.TagAddresses.Add(tagAddresses);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.AddItemBulk,
AddItemBulk = bulkCommand,
},
reply => reply.AddItemBulk,
cancellationToken);
}
public Task<IReadOnlyList<SubscribeResult>> AdviseItemBulkAsync(
int serverHandle,
IReadOnlyList<int> itemHandles,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(itemHandles);
AdviseItemBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.ItemHandles.Add(itemHandles);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.AdviseItemBulk,
AdviseItemBulk = bulkCommand,
},
reply => reply.AdviseItemBulk,
cancellationToken);
}
public Task<IReadOnlyList<SubscribeResult>> RemoveItemBulkAsync(
int serverHandle,
IReadOnlyList<int> itemHandles,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(itemHandles);
RemoveItemBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.ItemHandles.Add(itemHandles);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.RemoveItemBulk,
RemoveItemBulk = bulkCommand,
},
reply => reply.RemoveItemBulk,
cancellationToken);
}
public Task<IReadOnlyList<SubscribeResult>> UnAdviseItemBulkAsync(
int serverHandle,
IReadOnlyList<int> itemHandles,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(itemHandles);
UnAdviseItemBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.ItemHandles.Add(itemHandles);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.UnAdviseItemBulk,
UnAdviseItemBulk = bulkCommand,
},
reply => reply.UnAdviseItemBulk,
cancellationToken);
}
public Task<IReadOnlyList<SubscribeResult>> SubscribeBulkAsync(
int serverHandle,
IReadOnlyList<string> tagAddresses,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(tagAddresses);
SubscribeBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.TagAddresses.Add(tagAddresses);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.SubscribeBulk,
SubscribeBulk = bulkCommand,
},
reply => reply.SubscribeBulk,
cancellationToken);
}
public Task<IReadOnlyList<SubscribeResult>> UnsubscribeBulkAsync(
int serverHandle,
IReadOnlyList<int> itemHandles,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(itemHandles);
UnsubscribeBulkCommand bulkCommand = new() { ServerHandle = serverHandle };
bulkCommand.ItemHandles.Add(itemHandles);
return InvokeBulkAsync(
new MxCommand
{
Kind = MxCommandKind.UnsubscribeBulk,
UnsubscribeBulk = bulkCommand,
},
reply => reply.UnsubscribeBulk,
cancellationToken);
}
public IAsyncEnumerable<WorkerEvent> ReadEventsAsync(CancellationToken cancellationToken)
{
IWorkerClient workerClient = GetReadyWorkerClient();
@@ -308,6 +422,35 @@ public sealed class GatewaySession
}
}
private async Task<IReadOnlyList<SubscribeResult>> InvokeBulkAsync(
MxCommand command,
Func<MxCommandReply, BulkSubscribeReply?> payloadAccessor,
CancellationToken cancellationToken)
{
WorkerCommandReply workerReply = await InvokeAsync(
new WorkerCommand { Command = command },
cancellationToken)
.ConfigureAwait(false);
MxCommandReply reply = workerReply.Reply ?? new MxCommandReply
{
ProtocolStatus = new ProtocolStatus
{
Code = ProtocolStatusCode.ProtocolViolation,
Message = "Worker command reply did not contain a public reply payload.",
},
};
if (reply.ProtocolStatus?.Code is not ProtocolStatusCode.Ok)
{
string message = reply.ProtocolStatus?.Message ?? reply.DiagnosticMessage;
throw new SessionManagerException(
SessionManagerErrorCode.SessionNotReady,
string.IsNullOrWhiteSpace(message) ? "Bulk MXAccess command failed." : message);
}
return payloadAccessor(reply)?.Results.ToArray() ?? [];
}
private IWorkerClient GetReadyWorkerClient()
{
lock (_syncRoot)