public bool CompletePublish(
OperationContext context,
AsyncPublishOperation operation)
{
// get publish queue for session.
SessionPublishQueue queue = null;
lock (m_lock)
{
if (!m_publishQueues.TryGetValue(context.Session.Id, out queue))
{
throw new ServiceResultException(StatusCodes.BadSessionClosed);
}
}
uint subscriptionId = 0;
UInt32Collection availableSequenceNumbers = null;
bool moreNotifications = false;
NotificationMessage message = null;
// Utils.Trace("Publish #{0} ReceivedFromClient", context.ClientHandle);
bool requeue = false;
do
{
// wait for a subscription to publish.
Subscription subscription = queue.CompletePublish(requeue, operation, operation.Calldata);
if (subscription == null)
{
return false;
}
subscriptionId = subscription.Id;
moreNotifications = false;
// publish notifications.
try
{
requeue = false;
message = subscription.Publish(
context,
out availableSequenceNumbers,
out moreNotifications);
// a null message indicates a false alarm and that there were no notifications
// to publish and that the request needs to be requeued.
if (message != null)
{
break;
}
Utils.Trace("Publish False Alarm - Request #{0} Requeued.", context.ClientHandle);
requeue = true;
}
finally
{
queue.PublishCompleted(subscription, moreNotifications);
}
}
while (requeue);
// fill in response if operation completed.
if (message != null)
{
operation.Response.SubscriptionId = subscriptionId;
operation.Response.AvailableSequenceNumbers = availableSequenceNumbers;
operation.Response.MoreNotifications = moreNotifications;
operation.Response.NotificationMessage = message;
// update diagnostics.
if (context.Session != null)
{
lock (context.Session.DiagnosticsLock)
{
SessionDiagnosticsDataType diagnostics = context.Session.SessionDiagnostics;
diagnostics.CurrentPublishRequestsInQueue--;
}
}
}
return true;
}