// 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)); }
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)); }
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)); }
// 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)); }
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)); }