public Task DispatchFlowEventAsync(FlowStateContext flowStateCtx)
            {
                // Quick check to see if we have a buffer to forward events to
                if (FlowEventQueue == null)
                {
                    return(Task.FromResult(0));
                }

                return(DispatchFlowEventAsyncInternal(flowStateCtx));
            }
 private async Task DispatchFlowEventAsyncInternal(FlowStateContext flowStateCtx)
 {
     await FlowEventQueue.SendAsync(flowStateCtx).ConfigureAwait(false);
 }
        private async Task <bool> SubscribeQueueAsyncInternal(Queue queue, BufferBlock <Message> messageQueue = null,
                                                              BufferBlock <FlowStateContext> flowEvtQueue     = null, bool flowStartState = false)
        {
            FlowBindings.FlowBindingElement binding = null;
            if (messageQueue == null)
            {
                // Use default message block
                messageQueue = defaultAppMsgQueue;
            }
            bool newSubscription = flowBindings.AddBinding(queue, messageQueue, flowEvtQueue, out binding);

            if (newSubscription && binding != null)
            {
                try
                {
                    // Configure flow properties
                    var fp = new FlowProperties
                    {
                        AckMode        = solaceOptions.ClientAck ? MessageAckMode.ClientAck : MessageAckMode.AutoAck,
                        BindBlocking   = false, // ensure we bind in non-blocking mode
                        FlowStartState = flowStartState
                    };

                    // Destination
                    IEndpoint solQueue = null;
                    if (queue.IsTemporary)
                    {
                        solQueue = session.CreateTemporaryQueue(queue.Name);
                    }
                    else
                    {
                        solQueue = ContextFactory.Instance.CreateQueue(queue.Name);
                    }

                    // Create the flow
                    TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>();
                    IFlow flow = session.CreateFlow(
                        fp,
                        solQueue,
                        null,
                        async(sender, msgEv) => { await AcceptMessageEventAsync(msgEv, binding).ConfigureAwait(false); },
                        async(sender, flowEv) =>
                    {
                        logger.LogDebug("FlowEvent: {0}, Info: {1}", flowEv.Event, flowEv.Info);
                        var flowStateCtx = new FlowStateContext()
                        {
                            Info = flowEv.Info, ResponseCode = flowEv.ResponseCode
                        };
                        switch (flowEv.Event)
                        {
                        case FlowEvent.UpNotice:
                            flowStateCtx.State = FlowState.Up;
                            tcs.TrySetResult(true);
                            break;

                        case FlowEvent.BindFailedError:
                            flowStateCtx.State = FlowState.BindFailedError;
                            logger.LogWarning(string.Format("Queue connection failure: {0}", flowEv.Event.ToString()));
                            tcs.TrySetResult(false);
                            break;

                        case FlowEvent.DownError:
                            flowStateCtx.State = FlowState.Down;
                            break;

                        case FlowEvent.FlowActive:
                            flowStateCtx.State = FlowState.FlowActive;
                            break;

                        case FlowEvent.FlowInactive:
                            flowStateCtx.State = FlowState.FlowInactive;
                            break;

                        default:
                            break;
                        }

                        // Notify caller of the flow event
                        await binding.DispatchFlowEventAsync(flowStateCtx).ConfigureAwait(false);
                    });
                    binding.Flow = flow;
                    return(await tcs.Task.ConfigureAwait(false));
                }
                catch (Exception e)
                {
                    binding.Flow = null;
                    flowBindings.RemoveBinding(queue, out binding);
                    throw new MessagingException(e.Message, e);
                }
            }

            if (!newSubscription && binding != null)
            {
                // If existing subscription then ignore and return success
                return(true);
            }
            return(false);
        }