private async Task PollCommandTaskMethodAsync(SubscriptionTask subscriptionTask) { var subscription = subscriptionTask.Subscription; var cancellationToken = subscriptionTask.CancellationTokenSource.Token; while (true) { try { var commands = await PollCommandsAsync(subscription.DeviceGuids, subscription.EventNames, subscription.Timestamp, subscriptionTask.IsLastPollFailed?(int?)0 : null, cancellationToken); NotifyPollResult(subscriptionTask, false); foreach (var command in commands) { command.SubscriptionId = subscription.Id; InvokeSubscriptionCallback(subscription.Id, command.Command.Timestamp.Value, command); } } catch (OperationCanceledException) { return; } catch (Exception) { NotifyPollResult(subscriptionTask, true); if (cancellationToken.WaitHandle.WaitOne(FAILED_POLL_RETRY_TIMEOUT)) // retry with small wait { return; } } } }
/// <summary> /// Subscribes to incoming messages. /// </summary> /// <param name="QueueName">Queue name.</param> /// <param name="Cancel">Cancel event. Set this event object, to cancel subscription.</param> /// <param name="Stopped">Optional Event that will be set when the subscription has ended.</param> /// <param name="Callback">Method to call when new message has been read.</param> /// <param name="State">State object to pass on to callback method.</param> public void SubscribeIncoming(string QueueName, ManualResetEvent Cancel, TaskCompletionSource <bool> Stopped, MqMessageEventHandler Callback, object State) { this.Information("Subscribing to messages from " + QueueName); SubscriptionTask Item = new SubscriptionTask(this, QueueName, Cancel, Stopped, Callback, State); MqTasks.ExecuteTask(Item); }
private void NotifyPollResult(SubscriptionTask subscriptionTask, bool isFailed) { lock (_subscriptionTasks) { subscriptionTask.IsLastPollFailed = isFailed; if (State == ChannelState.Connected && isFailed) { SetChannelState(ChannelState.Reconnecting); } else if (State == ChannelState.Reconnecting && !isFailed) { if (!_subscriptionTasks.Values.Any(t => t.IsLastPollFailed)) { SetChannelState(ChannelState.Connected); } } } }
/// <summary> /// Invoked after new subscription is added. /// The method starts a polling thread. /// </summary> /// <param name="subscription">A <see cref="ISubscription"/> object representing a subscription.</param> /// <returns></returns> protected override async Task SubscriptionAdded(ISubscription subscription) { var subscriptionTask = new SubscriptionTask(subscription); switch (subscription.Type) { case SubscriptionType.Notification: subscriptionTask.Run(async() => await PollNotificationTaskMethodAsync(subscriptionTask)); break; case SubscriptionType.Command: subscriptionTask.Run(async() => await PollCommandTaskMethodAsync(subscriptionTask)); break; } lock (_subscriptionTasks) { _subscriptionTasks[subscription.Id] = subscriptionTask; } await base.SubscriptionAdded(subscription); }
private void NotifyPollResult(SubscriptionTask subscriptionTask, bool isFailed) { lock (_subscriptionTasks) { subscriptionTask.IsLastPollFailed = isFailed; if (State == ChannelState.Connected && isFailed) { SetChannelState(ChannelState.Reconnecting); } else if (State == ChannelState.Reconnecting && !isFailed) { if (!_subscriptionTasks.Values.Any(t => t.IsLastPollFailed)) SetChannelState(ChannelState.Connected); } } }
private async Task PollCommandTaskMethodAsync(SubscriptionTask subscriptionTask) { var subscription = subscriptionTask.Subscription; var cancellationToken = subscriptionTask.CancellationTokenSource.Token; while (true) { try { var commands = await PollCommandsAsync(subscription.DeviceGuids, subscription.EventNames, subscription.Timestamp, subscriptionTask.IsLastPollFailed ? (int?)0 : null, cancellationToken); NotifyPollResult(subscriptionTask, false); foreach (var command in commands) { InvokeSubscriptionCallback(subscription.Id, command.Timestamp.Value, command); } } catch (OperationCanceledException) { return; } catch (Exception) { NotifyPollResult(subscriptionTask, true); if (cancellationToken.WaitHandle.WaitOne(FAILED_POLL_RETRY_TIMEOUT)) // retry with small wait return; } } }
/// <summary> /// Invoked after new subscription is added. /// The method starts a polling thread. /// </summary> /// <param name="subscription">A <see cref="ISubscription"/> object representing a subscription.</param> /// <returns></returns> protected override async Task SubscriptionAdded(ISubscription subscription) { var subscriptionTask = new SubscriptionTask(subscription); switch (subscription.Type) { case SubscriptionType.Notification: subscriptionTask.Run(async () => await PollNotificationTaskMethodAsync(subscriptionTask)); break; case SubscriptionType.Command: subscriptionTask.Run(async () => await PollCommandTaskMethodAsync(subscriptionTask)); break; } lock (_subscriptionTasks) { _subscriptionTasks[subscription.Id] = subscriptionTask; } await base.SubscriptionAdded(subscription); }