// TODO(mathip): add support for requestId parsing.
        public async Task <string> GetFilenameAsync(string request)
        {
            var client = await _lookupDispatcher.TakeAsync();

            var filename     = Path.GetRandomFileName();
            var binaryWriter = new BinaryWriter(File.Open(filename, FileMode.OpenOrCreate));

            var ct  = new CancellationTokenSource(_timeout);
            var res = new TaskCompletionSource <string>();

            ct.Token.Register(() => res.TrySetCanceled(), false);

            void SocketClientOnMessageReceived(object sender, SocketMessageEventArgs args)
            {
                // check for errors
                if (args.Message[0] == IQFeedDefault.PrototolErrorCharacter && args.Message[1] == IQFeedDefault.ProtocolDelimiterCharacter)
                {
                    // at this level, we might have true negative, further checks needed
                    var received     = Encoding.ASCII.GetString(args.Message, 0, args.Count);
                    var messages     = received.SplitFeedLine();
                    var errorMessage = ParseErrorMessage(messages);

                    if (!string.IsNullOrEmpty(errorMessage))
                    {
                        // error has been confirmed
                        res.TrySetException(_exceptionFactory.CreateNew(request, errorMessage, received));
                        return;
                    }
                }

                binaryWriter.Write(args.Message, 0, args.Count);

                // check if the message end
                if (args.Message.EndsWith(args.Count, _endOfMsgBytes))
                {
                    res.TrySetResult(filename);
                }
            }

            client.MessageReceived += SocketClientOnMessageReceived;
            await _lookupRateLimiter.WaitAsync().ConfigureAwait(false);

            client.Send(request);

            await res.Task.ContinueWith(x =>
            {
                binaryWriter.Close();
                client.MessageReceived -= SocketClientOnMessageReceived;
                _lookupDispatcher.Add(client);
                ct.Dispose();
                if (res.Task.IsFaulted)
                {
                    File.Delete(filename);
                }
            }, TaskContinuationOptions.None).ConfigureAwait(false);

            return(await res.Task.ConfigureAwait(false));
        }
예제 #2
0
        protected async Task <IEnumerable <T> > GetMessagesAsync <T>(string request, Func <byte[], int, MessageContainer <T> > messageHandler)
        {
            var client = await _lookupDispatcher.TakeAsync();

            var messages        = new List <T>();
            var invalidMessages = new List <InvalidMessage <T> >();
            var ct  = new CancellationTokenSource(_timeout);
            var res = new TaskCompletionSource <IEnumerable <T> >();

            ct.Token.Register(() => res.TrySetCanceled(), false);

            void SocketClientOnMessageReceived(object sender, SocketMessageEventArgs args)
            {
                var container = messageHandler(args.Message, args.Count);

                // exception must be throw at the very end when all messages have been received and parsed to avoid
                // continuation in the next request since we don't use request id
                if (container.ErrorMessage != null)
                {
                    res.TrySetException(_exceptionFactory.CreateNew(request, container.ErrorMessage, container.MessageTrace));
                    return;
                }

                messages.AddRange(container.Messages);
                invalidMessages.AddRange(container.InvalidMessages);

                if (!container.End)
                {
                    return;
                }

                if (invalidMessages.Count > 0)
                {
                    res.TrySetException(_exceptionFactory.CreateNew(request, invalidMessages, messages));
                    return;
                }

                res.TrySetResult(messages);
            }

            client.MessageReceived += SocketClientOnMessageReceived;
            await _lookupRateLimiter.WaitAsync().ConfigureAwait(false);

            client.Send(request);

            await res.Task.ContinueWith(x =>
            {
                client.MessageReceived -= SocketClientOnMessageReceived;
                _lookupDispatcher.Add(client);
                ct.Dispose();
            }, TaskContinuationOptions.None).ConfigureAwait(false);

            return(await res.Task.ConfigureAwait(false));
        }
예제 #3
0
        public async Task <string> GetFilenameAsync(string request)
        {
            var client = await _lookupDispatcher.TakeAsync();

            var filename     = Path.GetRandomFileName();
            var binaryWriter = new BinaryWriter(File.Open(filename, FileMode.OpenOrCreate));

            var ct  = new CancellationTokenSource(_timeoutMs);
            var res = new TaskCompletionSource <string>();

            ct.Token.Register(() => res.TrySetCanceled(), false);

            void SocketClientOnMessageReceived(object sender, SocketMessageEventArgs args)
            {
                // check for errors
                if (args.Message[0] == IQFeedDefault.PrototolErrorCharacter && args.Message[1] == IQFeedDefault.ProtocolDelimiterCharacter)
                {
                    var errorMessage = Encoding.ASCII.GetString(args.Message, 0, args.Count);
                    res.TrySetException(_errorMessageHandler.GetException(errorMessage));
                    return;
                }

                binaryWriter.Write(args.Message, 0, args.Count);

                // check if the message end
                if (args.Message.EndsWith(args.Count, _endOfMsgBytes))
                {
                    res.TrySetResult(filename);
                }
            }

            client.MessageReceived += SocketClientOnMessageReceived;
            client.Send(request);

            await res.Task.ContinueWith(x =>
            {
                binaryWriter.Close();
                client.MessageReceived -= SocketClientOnMessageReceived;
                _lookupDispatcher.Add(client);
                ct.Dispose();
                if (res.Task.IsFaulted)
                {
                    File.Delete(filename);
                }
            }, TaskContinuationOptions.None).ConfigureAwait(false);

            return(await res.Task.ConfigureAwait(false));
        }
예제 #4
0
        // TODO: combine this method with Historical
        private async Task <IEnumerable <T> > GetMessagesAsync <T>(string request, Func <byte[], int, ChainsMessageContainer <T> > chainsMessageHandler)
        {
            var client = await _lookupDispatcher.TakeAsync();

            var messages = new List <T>();
            var ct       = new CancellationTokenSource(_timeoutMs);
            var res      = new TaskCompletionSource <IEnumerable <T> >();

            ct.Token.Register(() => res.TrySetCanceled(), false);

            void SocketClientOnMessageReceived(object sender, SocketMessageEventArgs args)
            {
                var container = chainsMessageHandler(args.Message, args.Count);

                if (messages.Count == 0 && container.Error != null)
                {
                    // TODO: should throw specific exception here
                    res.TrySetException(new Exception(container.Error));
                    return;
                }

                messages.AddRange(container.Messages);

                if (container.End)
                {
                    res.TrySetResult(messages);
                }
            }

            client.MessageReceived += SocketClientOnMessageReceived;
            client.Send(request);

            await res.Task.ContinueWith(x =>
            {
                client.MessageReceived -= SocketClientOnMessageReceived;
                _lookupDispatcher.Add(client);
            }, TaskContinuationOptions.None).ConfigureAwait(false);

            return(await res.Task.ConfigureAwait(false));
        }
예제 #5
0
        protected async Task <IEnumerable <T> > GetMessagesAsync <T>(string request, Func <byte[], int, MessageContainer <T> > messageHandler)
        {
            var client = await _lookupDispatcher.TakeAsync();

            var messages = new List <T>();
            var ct       = new CancellationTokenSource(_timeout);
            var res      = new TaskCompletionSource <IEnumerable <T> >();

            ct.Token.Register(() => res.TrySetCanceled(), false);

            void SocketClientOnMessageReceived(object sender, SocketMessageEventArgs args)
            {
                var container = messageHandler(args.Message, args.Count);

                if (container.ErrorMessage != null)
                {
                    res.TrySetException(_exceptionFactory.CreateNew(request, container.ErrorMessage, container.MessageTrace));
                    return;
                }

                messages.AddRange(container.Messages);

                if (container.End)
                {
                    res.TrySetResult(messages);
                }
            }

            client.MessageReceived += SocketClientOnMessageReceived;
            client.Send(request);

            await res.Task.ContinueWith(x =>
            {
                client.MessageReceived -= SocketClientOnMessageReceived;
                _lookupDispatcher.Add(client);
                ct.Dispose();
            }, TaskContinuationOptions.None).ConfigureAwait(false);

            return(await res.Task.ConfigureAwait(false));
        }