public LookupInfo(ISubscriptionMessage subscription, TimeSpan left)
 {
     Subscription = subscription ?? throw new ArgumentNullException(nameof(subscription));
     _initLeft    = left;
     _left        = left;
 }
예제 #2
0
        private bool ProcessInSubscriptionMessage(ISubscriptionMessage message, DataType dataType)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (dataType == null)
            {
                throw new ArgumentNullException(nameof(dataType));
            }

            var transId = message.TransactionId;

            var isSubscribe = message.IsSubscribe;

            ISubscriptionMessage sendInMsg = null;

            Message[] sendOutMsgs = null;

            lock (_sync)
            {
                if (isSubscribe)
                {
                    if (_replaceId.ContainsKey(transId))
                    {
                        sendInMsg = message;
                    }
                    else
                    {
                        var clone = message.TypedClone();

                        if (message.To != null)
                        {
                            _historicalRequests.Add(transId, clone);
                        }
                        else
                        {
                            _subscriptionsById.Add(transId, new SubscriptionInfo(clone));
                        }

                        sendInMsg = message;
                    }
                }
                else
                {
                    ISubscriptionMessage MakeUnsubscribe(ISubscriptionMessage m)
                    {
                        m = m.TypedClone();

                        m.IsSubscribe           = false;
                        m.OriginalTransactionId = m.TransactionId;
                        m.TransactionId         = transId;

                        return(m);
                    }

                    var originId = message.OriginalTransactionId;

                    if (_historicalRequests.TryGetAndRemove(originId, out var subscription))
                    {
                        sendInMsg = MakeUnsubscribe(subscription);
                    }
                    else if (_subscriptionsById.TryGetValue(originId, out var info))
                    {
                        if (info.State.IsActive())
                        {
                            // copy full subscription's details into unsubscribe request
                            sendInMsg = MakeUnsubscribe(info.Subscription);
                        }
                        else
                        {
                            this.AddWarningLog(LocalizedStrings.SubscriptionInState, originId, info.State);
                        }
                    }
                    else
                    {
                        sendOutMsgs = new[]
                        {
                            (Message)originId.CreateSubscriptionResponse(new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(originId)))
                        };
                    }
                }
            }

            var retVal = true;

            if (sendInMsg != null)
            {
                this.AddInfoLog("In: {0}", sendInMsg);
                retVal = base.OnSendInMessage((Message)sendInMsg);
            }

            if (sendOutMsgs != null)
            {
                foreach (var sendOutMsg in sendOutMsgs)
                {
                    this.AddInfoLog("Out: {0}", sendOutMsg);
                    RaiseNewOutMessage(sendOutMsg);
                }
            }

            return(retVal);
        }
예제 #3
0
 private bool ProcessInSubscriptionMessage(ISubscriptionMessage message)
 {
     return(ProcessInSubscriptionMessage(message, message.DataType));
 }
예제 #4
0
 public SubscriptionInfo(ISubscriptionMessage subscription)
 {
     Subscription = subscription ?? throw new ArgumentNullException(nameof(subscription));
 }
        private bool ProcessInSubscriptionMessage(ISubscriptionMessage message,
                                                  DataType dataType, SecurityId securityId = default)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (dataType == null)
            {
                throw new ArgumentNullException(nameof(dataType));
            }

            var transId = message.TransactionId;

            var isSubscribe = message.IsSubscribe;

            ISubscriptionMessage sendInMsg = null;

            Message[] sendOutMsgs = null;

            lock (_sync)
            {
                if (isSubscribe)
                {
                    if (message.To == null)
                    {
                        var key = Tuple.Create(dataType, securityId);

                        if (!_subscriptionsByKey.TryGetValue(key, out var info))
                        {
                            sendInMsg = message;

                            info = new SubscriptionInfo(message.TypedClone());

                            _subscriptionsByKey.Add(key, info);
                        }
                        else
                        {
                            var resultMsg = message.CreateResult();

                            if (message.Type == MessageTypes.MarketData)
                            {
                                sendOutMsgs = new[]
                                {
                                    message.CreateResponse(),
                                        resultMsg,
                                };
                            }
                            else
                            {
                                sendOutMsgs = new[] { resultMsg };
                            }
                        }

                        _subscriptionsById.Add(transId, info);
                        info.Subscribers.Add(transId);
                    }
                    else
                    {
                        sendInMsg = message;
                    }
                }
                else
                {
                    ISubscriptionMessage MakeUnsubscribe(ISubscriptionMessage m, long subscriptionId)
                    {
                        m.IsSubscribe           = false;
                        m.TransactionId         = transId;
                        m.OriginalTransactionId = subscriptionId;

                        return(m);
                    }

                    var originId = message.OriginalTransactionId;

                    if (_subscriptionsById.TryGetValue(originId, out var info))
                    {
                        if (!info.Subscribers.Remove(originId))
                        {
                            sendOutMsgs = new[]
                            {
                                (Message)originId.CreateSubscriptionResponse(new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(originId)))
                            };
                        }
                        else
                        {
                            if (info.Subscribers.Count == 0)
                            {
                                _subscriptionsByKey.RemoveByValue(info);
                                _subscriptionsById.Remove(originId);

                                if (info.State.IsActive())
                                {
                                    // copy full subscription's details into unsubscribe request
                                    sendInMsg = MakeUnsubscribe(info.Subscription.TypedClone(), info.Subscription.TransactionId);
                                }
                                else
                                {
                                    this.AddWarningLog(LocalizedStrings.SubscriptionInState, originId, info.State);
                                }
                            }
                            else
                            {
                                sendOutMsgs = new[] { message.CreateResult() };
                            }
                        }
                    }
                    else
                    {
                        sendOutMsgs = new[]
                        {
                            (Message)originId.CreateSubscriptionResponse(new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(originId)))
                        };
                    }
                }
            }

            var retVal = true;

            if (sendInMsg != null)
            {
                this.AddInfoLog("In: {0}", sendInMsg);
                retVal = base.OnSendInMessage((Message)sendInMsg);
            }

            if (sendOutMsgs != null)
            {
                foreach (var sendOutMsg in sendOutMsgs)
                {
                    this.AddInfoLog("Out: {0}", sendOutMsg);
                    RaiseNewOutMessage(sendOutMsg);
                }
            }

            return(retVal);
        }
예제 #6
0
            public Subscription ProcessResponse(SubscriptionResponseMessage response, out ISubscriptionMessage originalMsg, out bool unexpectedCancelled)
            {
                originalMsg = null;

                try
                {
                    lock (_syncObject)
                    {
                        unexpectedCancelled = false;

                        if (!_requests.TryGetValue(response.OriginalTransactionId, out var tuple))
                        {
                            originalMsg = null;
                            return(null);
                        }

                        // do not remove cause subscription can be interrupted after successful response
                        //_requests.Remove(response.OriginalTransactionId);

                        originalMsg = tuple.Item1;

                        var info = originalMsg.IsSubscribe
                                                        ? TryGetInfo(originalMsg.TransactionId, false, addLog: false)
                                                        : TryGetInfo(originalMsg.OriginalTransactionId, true, addLog: false);

                        if (info == null)
                        {
                            originalMsg = null;
                            return(null);
                        }

                        var subscription = info.Subscription;

                        if (originalMsg.IsSubscribe)
                        {
                            if (response.IsOk())
                            {
                                ChangeState(subscription, SubscriptionStates.Active);
                            }
                            else
                            {
                                ChangeState(subscription, SubscriptionStates.Error);

                                _subscriptions.Remove(subscription.TransactionId);

                                unexpectedCancelled = subscription.State.IsActive();

                                _requests.Remove(response.OriginalTransactionId);
                            }
                        }
                        else
                        {
                            ChangeState(subscription, SubscriptionStates.Stopped);

                            _subscriptions.Remove(subscription.TransactionId);

                            // remove subscribe and unsubscribe requests
                            _requests.Remove(subscription.TransactionId);
                            _requests.Remove(response.OriginalTransactionId);
                        }

                        return(subscription);
                    }
                }
                finally
                {
                    if (originalMsg == null)
                    {
                        TryWriteLog(response.OriginalTransactionId);
                    }
                }
            }