LogWarning() public method

public LogWarning ( ) : void
return void
Ejemplo n.º 1
0
        private string GenerateSelectSql(TableInfo tableInfo)
        {
            if (tableInfo.Primary.Count == 0)
            {
                Logger?.LogWarning("Can't generate select sql, primary key is missing.");
                return(null);
            }

            var tableName = GetTableName(tableInfo);
            var database  = GetDatabaseName(tableInfo);

            string where = "";
            foreach (var column in tableInfo.Primary)
            {
                where += $" [{GetColumnName(column)}] = @{column.Name} AND";
            }
            where = where.Substring(0, where.Length - 3);

            var sql = string.IsNullOrWhiteSpace(database) ? $"SELECT * FROM [{tableName}] WHERE {where};" :
                      $"USE [{database}]; SELECT * FROM [{tableName}] WHERE {where};";

            return(sql);
        }
        /// <summary>
        /// 生成更新数据的 SQL 语句
        /// </summary>
        /// <param name="tableMetadata">表元数据</param>
        /// <returns>SQL 语句</returns>
        protected virtual string GenerateUpdateSql(TableMetadata tableMetadata)
        {
            if (tableMetadata.Updates == null || tableMetadata.Updates.Count == 0)
            {
                Logger?.LogWarning("实体没有设置主键, 无法生成 Update 语句");
                return(null);
            }

            var where = "";
            foreach (var column in tableMetadata.Primary)
            {
                where += $" {Escape}{GetNameSql(column)}{Escape} = @{column} AND";
            }

            where = where.Substring(0, where.Length - 3);

            var setCols = string.Join(", ",
                                      tableMetadata.Updates.Select(c => $"{Escape}{GetNameSql(c)}{Escape}= @{c}"));
            var tableSql = GenerateTableSql(tableMetadata);
            var sql      = $"UPDATE {tableSql} SET {setCols} WHERE {where};";

            return(sql);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Completes a message by doing the actual READ from the queue.
        /// </summary>
        /// <param name="messages">The message we want to complete.</param>
        /// <returns>Task.</returns>
        internal async Task Complete(IEnumerable <T> messages)
        {
            try
            {
                var messageLockTokens = new List <string>();
                foreach (var message in messages)
                {
                    if (Messages.TryGetValue(message, out var msg))
                    {
                        Release(message);
                        if (msg.SystemProperties.LockedUntilUtc < DateTime.Now)
                        {
                            Receiver.RenewLockAsync(msg.SystemProperties.LockToken).GetAwaiter().GetResult();
                        }
                    }

                    if (msg?.SystemProperties.LockToken != null)
                    {
                        messageLockTokens.Add(msg.SystemProperties.LockToken);
                    }
                }
                if (messageLockTokens.Count > 0)
                {
                    await Receiver.CompleteAsync(messageLockTokens).ConfigureAwait(false);
                }
            }
            catch (Exception ex) when(ex is MessageLockLostException || ex is MessageNotFoundException)
            {
                Logger?.LogWarning(ex, "Error during message Complete, lock was lost [THIS CAN BE IGNORED - already in use or already processed]");
            }
            catch (Exception e)
            {
                Logger?.LogError(e, "Error during message Complete");

                MessageIn?.OnError(e);
            }
        }
Ejemplo n.º 4
0
        [ExcludeFromCodeCoverage] // Skipped - too many edge cases that cant be tested.
        internal async Task SendMessage(T messageBody, KeyValuePair <string, object>[] messageProperties = null)
        {
            if (Disposed)
            {
                return;
            }

            try
            {
                // Converts the message to a broker message and verifies its size is within the allowed size.
                var message = ConvertMessage(messageBody, messageProperties);
                await Sender.SendAsync(message).ConfigureAwait(false);
            }
            catch (MessagingEntityDisabledException mex)
            {
                Logger?.LogWarning(mex, "Error occurred sending message - entity is disabled");
                throw new EntityDisabledException(Config.SenderInfo.EntityName, mex.Message, mex);
            }
            catch (QuotaExceededException qex)
            {
                long maxSize = 0, currentSize = 0;

                // Build a meaningful entity full message.
                try
                {
                    long.TryParse(qex.Message.Substring("Size of entity in bytes:", ",").Trim(), out currentSize);
                    long.TryParse(qex.Message.Substring("Max entity size in bytes:", ".").Trim(), out maxSize);
                }
                catch (Exception)
                {
                    // Do nothing on error if there are any problems grabbing the size in bytes.
                }

                Logger?.LogWarning(qex, $"Error occurred sending messages - sender entity is full (max allowed: {maxSize}, current: {currentSize})");
                throw new EntityFullException(Config.SenderInfo.EntityName, qex.Message, currentSize, maxSize, qex);
            }
        }
Ejemplo n.º 5
0
            public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, RC.IBasicProperties properties, byte[] body)
            {
                Logger?.LogDebug("Storing delivery for consumer tag: {tag} with deliveryTag: {deliveryTag} for consumer: {consumer}", ConsumerTag, deliveryTag, ToString());
                try
                {
                    var delivery = new Delivery(consumerTag, new Envelope(deliveryTag, redelivered, exchange, routingKey), properties, body, QueueName);
                    if (Consumer.AbortStarted > 0)
                    {
                        if (!Consumer.Queue.TryAdd(delivery, Consumer.ShutdownTimeout))
                        {
                            RabbitUtils.SetPhysicalCloseRequired(Model, true);
                            _ = Consumer.Queue.TakeWhile((d) => Consumer.Queue.Count > 0);
                            if (!Canceled)
                            {
                                RabbitUtils.Cancel(Model, consumerTag);
                            }

                            try
                            {
                                Model.Close();
                            }
                            catch (Exception)
                            {
                                // Noop
                            }
                        }
                    }
                    else
                    {
                        Consumer.Queue.TryAdd(delivery);
                    }
                }
                catch (Exception e)
                {
                    Logger?.LogWarning(e, "Unexpected exception during delivery");
                }
            }
Ejemplo n.º 6
0
        internal static void ValidateListBox(ListBox element)
        {
            // Skip validation if a debugger isn't attached
            if (!Debugger.IsAttached)
            {
                return;
            }

            if (element is ListBox lb)
            {
                if (lb.ItemsSource == null)
                {
                    Logger?.LogWarning($"Cannot animate ListBox items because {nameof(lb.ItemsSource)} is null.");
                    return;
                }

                var itemSettings = GetItems(lb);

                // ItemsProperty can only be set on a AnimatedListBox or AnimatedListView.
                if (itemSettings != null && !(lb is AnimatedListBox) && !(lb is AnimatedListView))
                {
                    throw new ArgumentException($"{nameof(ItemsProperty)} can only be set on a {nameof(AnimatedListBox)} or {nameof(AnimatedListView)}.");
                }

                // ListBox item animations will only work if the inner ScrollViewer has CanContentScroll = true
                if (lb?.FindDescendant <ScrollViewer>() is ScrollViewer scroller && !scroller.CanContentScroll)
                {
                    throw new ArgumentException($"{nameof(ListBox)} item animations will only work if the inner {nameof(ScrollViewer)} has {nameof(scroller.CanContentScroll)} = true");
                }

                // Don't set a value for the Event property, is it disregarded for ListBox item animations.
                if (itemSettings != null && itemSettings.Event != DefaultSettings.Event)
                {
                    throw new ArgumentException($"Don't set a value for the {nameof(itemSettings.Event)} property, is it disregarded for {nameof(ListBox)} item animations.");
                }
            }
        }
Ejemplo n.º 7
0
        public async Task <IImageSourceServiceResult <WImageSource>?> GetImageSourceAsync(IUriImageSource imageSource, float scale = 1, CancellationToken cancellationToken = default)
        {
            if (imageSource.IsEmpty)
            {
                return(null);
            }

            // TODO: use a real caching library with the URI
            if (imageSource is not IStreamImageSource streamImageSource)
            {
                throw new InvalidOperationException("Unable to load URI as a stream.");
            }

            try
            {
                using var stream = await streamImageSource.GetStreamAsync(cancellationToken);

                if (stream == null)
                {
                    throw new InvalidOperationException("Unable to load image stream.");
                }

                var image = new BitmapImage();

                using var ras = stream.AsRandomAccessStream();
                await image.SetSourceAsync(ras);

                var result = new ImageSourceServiceResult(image);

                return(result);
            }
            catch (Exception ex)
            {
                Logger?.LogWarning(ex, "Unable to load image URI '{Uri}'.", imageSource.Uri);
                throw;
            }
        }
Ejemplo n.º 8
0
        public override async Task <IImageSourceServiceResult?> LoadDrawableAsync(IImageSource imageSource, Android.Widget.ImageView imageView, CancellationToken cancellationToken = default)
        {
            var streamImageSource = (IStreamImageSource)imageSource;

            if (!streamImageSource.IsEmpty)
            {
                Stream?stream = null;
                try
                {
                    stream = await streamImageSource.GetStreamAsync(cancellationToken).ConfigureAwait(false);

                    var callback = new ImageLoaderCallback();

                    PlatformInterop.LoadImageFromStream(imageView, stream, callback);

                    var result = await callback.Result;

                    stream?.Dispose();

                    return(result);
                }
                catch (Exception ex)
                {
                    Logger?.LogWarning(ex, "Unable to load image stream.");
                    throw;
                }
                finally
                {
                    if (stream != null)
                    {
                        GC.KeepAlive(stream);
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 9
0
        public async Task <IImageSourceServiceResult <Drawable>?> GetDrawableAsync(IStreamImageSource imageSource, Context context, CancellationToken cancellationToken = default)
        {
            if (imageSource.IsEmpty)
            {
                return(null);
            }

            try
            {
                var stream = await imageSource.GetStreamAsync(cancellationToken).ConfigureAwait(false);

                // We can use the .NET stream directly because we register the InputStreamModelLoader.
                // There are 2 alternatives:
                //  - Load the bitmap manually and pass that along, but then we do not get the decoding features.
                //  - Copy the stream into a byte array and that is double memory usage - especially for large streams.
                var inputStream = new InputStreamAdapter(stream);

                var result = await Glide
                             .With(context)
                             .Load(inputStream)
                             .SetDiskCacheStrategy(DiskCacheStrategy.None)
                             .SubmitAsync(context, cancellationToken)
                             .ConfigureAwait(false);

                if (result == null)
                {
                    throw new InvalidOperationException("Unable to load image stream.");
                }

                return(result);
            }
            catch (Exception ex)
            {
                Logger?.LogWarning(ex, "Unable to load image stream.");
                throw;
            }
        }
Ejemplo n.º 10
0
 protected override void EndNestedType(string value)
 {
     try
     {
         PropertyValue.Init(_processStack.Pop().Entity);
         CurrentInstance = _processStack.Peek();
         if (CurrentInstance.Entity != null)
         {
             CurrentInstance.Entity.Parse(CurrentInstance.CurrentParamIndex, PropertyValue, NestedIndex);
         }
     }
     catch (Exception)
     {
         if (ErrorCount > MaxErrorCount)
         {
             throw new XbimParserException("Too many errors in file, parser execution terminated");
         }
         ErrorCount++;
         var mainEntity = _processStack.Last();
         if (mainEntity != null)
         {
             Logger?.LogWarning("Entity #{0,-5} {1}, error at parameter {2} value = {4}",
                                mainEntity.EntityLabel, mainEntity.Entity.GetType().Name.ToUpper(),
                                mainEntity.CurrentParamIndex + 1,
                                value);
         }
         else
         {
             Logger?.LogWarning("Unhandled Parser error, in Parser.cs EndNestedType");
         }
     }
     if (ListNestLevel == 0)
     {
         CurrentInstance.CurrentParamIndex++;
         _deferListItems = false;
     }
 }
Ejemplo n.º 11
0
        private void HandleDeclarationException(int passiveDeclareRetries, DeclarationException e)
        {
            if (passiveDeclareRetries > 0 && Channel.IsOpen)
            {
                Logger?.LogWarning(e, "Queue declaration failed; retries left={retries}", passiveDeclareRetries);
                try
                {
                    Thread.Sleep(FailedDeclarationRetryInterval);
                }
                catch (Exception e1)
                {
                    Declaring = false;
                    ActiveObjectCounter.Release(this);
                    throw RabbitExceptionTranslator.ConvertRabbitAccessException(e1);
                }
            }
            else if (e.FailedQueues.Count < Queues.Count)
            {
                Logger?.LogWarning("Not all queues are available; only listening on those that are - configured: {queues}; not available: {notavail}", string.Join(',', Queues), string.Join(',', e.FailedQueues));
                lock (MissingQueues)
                {
                    foreach (var q in e.FailedQueues)
                    {
                        MissingQueues.Add(q);
                    }
                }

                LastRetryDeclaration = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            }
            else
            {
                Declaring = false;
                ActiveObjectCounter.Release(this);
                throw new QueuesNotAvailableException("Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.", e);
            }
        }
Ejemplo n.º 12
0
        protected override void Dispose(bool disposing)
        {
            Logger?.LogDebug("[FtpDataStream] Disposing");
            base.Dispose(disposing);

            try
            {
                encapsulatedStream.Dispose();

                if (client.Configuration.DisconnectTimeoutMilliseconds.HasValue)
                {
                    client.ControlStream.SetTimeouts(client.Configuration.DisconnectTimeoutMilliseconds.Value);
                }
                client.CloseFileDataStreamAsync().Wait();
            }
            catch (Exception e)
            {
                Logger?.LogWarning(0, e, "Closing the data stream took longer than expected");
            }
            finally
            {
                client.ControlStream.ResetTimeouts();
            }
        }
Ejemplo n.º 13
0
        public async Task <int> ExecuteAsync(string standardQuery, object paramValues, CommandType?dbCommandType = null,
                                             int commandTimeout = 0)
        {
            try
            {
                Logger?.LogInformation($"Executing DB query: \n {standardQuery} ");
                Logger?.LogInformation($"DB query parameters: \n {paramValues?.JsonSerialize()}");
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                var result =
                    await
                        (await GetOpenConnectionAsync()).ExecuteAsync(standardQuery, paramValues, _currentTransaction,
                                                                      commandType: dbCommandType, commandTimeout: commandTimeout);

                Logger?.LogInformation($"DB query results: \n {result}");
                if (stopwatch.ElapsedMilliseconds >= ExecutionPerformanceThresholdInMs)
                {
                    Logger?.LogWarning(
                        $"DB query execution time: \n {stopwatch.ElapsedMilliseconds} ms \n {standardQuery}",
                        dbCommandType,
                        standardQuery, paramValues);
                }
                else
                {
                    Logger?.LogInformation(
                        $"DB query execution time: \n {stopwatch.ElapsedMilliseconds} ms \n {standardQuery}");
                }

                return(result);
            }
            catch (Exception ex)
            {
                Logger?.LogError($"Executing DB query failed: \n {ex.Message}", ex, standardQuery, paramValues);
                throw ex;
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// 生成插入新数据或者更新旧数据的 SQL 语句
        /// </summary>
        /// <param name="tableMetadata">表元数据</param>
        /// <returns>SQL 语句</returns>
        protected virtual string GenerateInsertAndUpdateSql(TableMetadata tableMetadata)
        {
            if (!tableMetadata.HasPrimary)
            {
                Logger?.LogWarning("实体没有设置主键, 无法生成 InsertAndUpdate 语句");
                return(null);
            }

            // UPDATE MyTable SET FieldA=@FieldA WHERE Key=@Key IF @@ROWCOUNT = 0 INSERT INTO MyTable (FieldA) VALUES (@FieldA)
            var columns = tableMetadata.Columns;
            var isAutoIncrementPrimary = tableMetadata.IsAutoIncrementPrimary;
            // 去掉自增主键
            var insertColumns =
                (isAutoIncrementPrimary ? columns.Where(c1 => c1.Key != tableMetadata.Primary.First()) : columns)
                .ToArray();

            var columnsSql = string.Join(", ", insertColumns.Select(c => $"[{GetNameSql(c.Key)}]"));

            var columnsParamsSql = string.Join(", ", insertColumns.Select(p => $"@{p.Key}"));

            var where = "";
            foreach (var column in tableMetadata.Primary)
            {
                where += $" [{GetNameSql(column)}] = @{column} AND";
            }

            where = where.Substring(0, where.Length - 3);

            var tableSql = GenerateTableSql(tableMetadata);

            var setCols = string.Join(", ", insertColumns.Select(c => $"[{GetNameSql(c.Key)}] = @{c.Key}"));
            var sql     =
                $"UPDATE {tableSql} SET {setCols} WHERE {where} IF @@ROWCOUNT = 0 INSERT INTO {tableSql} ({columnsSql}) VALUES ({columnsParamsSql});";

            return(sql);
        }
Ejemplo n.º 15
0
        public async Task <IImageSourceServiceResult <Image>?> GetImageAsync(IFileImageSource imageSource, Image image, CancellationToken cancellationToken = default)
        {
            if (imageSource.IsEmpty)
            {
                return(null);
            }

            var filename = imageSource.File;

            try
            {
                if (!string.IsNullOrEmpty(filename))
                {
                    var isLoadComplated = await image.LoadAsync(GetPath(filename), cancellationToken);

                    if (!isLoadComplated)
                    {
                        //If it fails, call the Load function to remove the previous image.
                        image.Load(string.Empty);
                        throw new InvalidOperationException("Unable to load image file.");
                    }

                    var result = new ImageSourceServiceResult(image);
                    return(result);
                }
                else
                {
                    throw new InvalidOperationException("Unable to load image file.");
                }
            }
            catch (Exception ex)
            {
                Logger?.LogWarning(ex, "Unable to load image file '{File}'.", filename);
                throw;
            }
        }
Ejemplo n.º 16
0
        protected override void HandleMessage(IEnumerable <Action <CandlestickEventArgs> > callbacks, string stream, string json)
        {
            try
            {
                var jObject = JObject.Parse(json);

                var eventType = jObject["e"].Value <string>();

                if (eventType == "kline")
                {
                    //var symbol = jObject["s"].Value<string>();
                    var eventTime = jObject["E"].Value <long>().ToDateTime();

                    var kLine = jObject["k"];

                    var firstTradeId = kLine["f"].Value <long>();
                    var lastTradeId  = kLine["L"].Value <long>();

                    var isFinal = kLine["x"].Value <bool>();

                    var candlestick = new Candlestick(
                        kLine["s"].Value <string>(),  // symbol
                        kLine["i"].Value <string>()   // interval
                        .ToCandlestickInterval(),
                        kLine["t"].Value <long>()     // open time
                        .ToDateTime(),
                        kLine["o"].Value <decimal>(), // open
                        kLine["h"].Value <decimal>(), // high
                        kLine["l"].Value <decimal>(), // low
                        kLine["c"].Value <decimal>(), // close
                        kLine["v"].Value <decimal>(), // volume
                        kLine["T"].Value <long>()     // close time
                        .ToDateTime(),
                        kLine["q"].Value <decimal>(), // quote asset volume
                        kLine["n"].Value <long>(),    // number of trades
                        kLine["V"].Value <decimal>(), // taker buy base asset volume (volume of active buy)
                        kLine["Q"].Value <decimal>()  // taker buy quote asset volume (quote volume of active buy)
                        );

                    var eventArgs = new CandlestickEventArgs(eventTime, candlestick, firstTradeId, lastTradeId, isFinal);

                    try
                    {
                        if (callbacks != null)
                        {
                            foreach (var callback in callbacks)
                            {
                                callback(eventArgs);
                            }
                        }
                        Candlestick?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException) { /* ignore */ }
                    catch (Exception e)
                    {
                        Logger?.LogWarning(e, $"{nameof(CandlestickClient)}.{nameof(HandleMessage)}: Unhandled candlestick event handler exception.");
                    }
                }
                else
                {
                    Logger?.LogWarning($"{nameof(CandlestickClient)}.{nameof(HandleMessage)}: Unexpected event type ({eventType}).");
                }
            }
            catch (OperationCanceledException) { /* ignore */ }
            catch (Exception e)
            {
                Logger?.LogError(e, $"{nameof(CandlestickClient)}.{nameof(HandleMessage)}");
            }
        }
Ejemplo n.º 17
0
        protected override Task <DataFlowResult> Parse(DataFlowContext context)
        {
            if (!context.Contains(_model.TypeName))
            {
                context.Add(_model.TypeName, _tableMetadata);
            }

            var selectable = context.GetSelectable();
            var results    = new ParseResult <T>();

            if (selectable.Properties == null)
            {
                selectable.Properties = new Dictionary <string, object>();
            }

            var environments = new Dictionary <string, string>();

            foreach (var property in context.Response.Request.Properties)
            {
                environments.Add(property.Key, property.Value);
            }

            if (_model.ShareValueSelectors != null)
            {
                foreach (var selector in _model.ShareValueSelectors)
                {
                    string name  = selector.Name;
                    var    value = selectable.Select(selector.ToSelector()).GetValue();
                    if (!environments.ContainsKey(name))
                    {
                        environments.Add(name, value);
                    }
                    else
                    {
                        environments[name] = value;
                    }
                }
            }

            bool singleExtractor = _model.Selector == null;

            if (!singleExtractor)
            {
                var selector = _model.Selector.ToSelector();

                var list = selectable.SelectList(selector).Nodes()?.ToList();
                if (list != null)
                {
                    if (_model.Take > 0 && list.Count > _model.Take)
                    {
                        list = _model.TakeFromHead
                                                        ? list.Take(_model.Take).ToList()
                                                        : list.Skip(list.Count - _model.Take).ToList();
                    }

                    for (var i = 0; i < list.Count; ++i)
                    {
                        var item = list.ElementAt(i);
                        var obj  = ParseObject(environments, item, i);
                        if (obj != null)
                        {
                            results.Add(obj);
                        }
                        else
                        {
                            Logger?.LogWarning($"解析到空数据,类型: {_model.TypeName}");
                        }
                    }
                }
            }
            else
            {
                var obj = ParseObject(environments, selectable, 0);
                if (obj != null)
                {
                    results.Add(obj);
                }
                else
                {
                    Logger?.LogWarning($"解析到空数据,类型: {_model.TypeName}");
                }
            }

            if (results.Count > 0)
            {
                var items = context.GetParseItem(_model.TypeName);
                if (items == null)
                {
                    context.AddParseItem(_model.TypeName, results);
                }
                else
                {
                    ((ParseResult <T>)items).AddRange(results);
                }
            }

            return(Task.FromResult(DataFlowResult.Success));
        }
Ejemplo n.º 18
0
        protected override void OnWebSocketEvent(WebSocketStreamEventArgs args, IEnumerable <Action <SymbolStatisticsEventArgs> > callbacks)
        {
            Logger?.LogDebug($"{nameof(SymbolStatisticsWebSocketClient)}: \"{args.Json}\"");

            try
            {
                SymbolStatisticsEventArgs eventArgs;

                if (args.Json.IsJsonArray())
                {
                    // Simulate a single event time.
                    var eventTime = DateTime.UtcNow.ToTimestamp().ToDateTime();

                    var statistics = JArray.Parse(args.Json).Select(DeserializeSymbolStatistics).ToArray();

                    eventArgs = new SymbolStatisticsEventArgs(eventTime, args.Token, statistics);
                }
                else
                {
                    var jObject = JObject.Parse(args.Json);

                    var eventType = jObject["e"].Value <string>();

                    if (eventType == "24hrTicker")
                    {
                        var eventTime = jObject["E"].Value <long>().ToDateTime();

                        var statistics = DeserializeSymbolStatistics(jObject);

                        eventArgs = new SymbolStatisticsEventArgs(eventTime, args.Token, statistics);
                    }
                    else
                    {
                        Logger?.LogWarning($"{nameof(SymbolStatisticsWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unexpected event type ({eventType}).");
                        return;
                    }
                }

                try
                {
                    if (callbacks != null)
                    {
                        foreach (var callback in callbacks)
                        {
                            callback(eventArgs);
                        }
                    }
                    StatisticsUpdate?.Invoke(this, eventArgs);
                }
                catch (OperationCanceledException) { }
                catch (Exception e)
                {
                    if (!args.Token.IsCancellationRequested)
                    {
                        Logger?.LogError(e, $"{nameof(SymbolStatisticsWebSocketClient)}: Unhandled aggregate trade event handler exception.");
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!args.Token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(SymbolStatisticsWebSocketClient)}.{nameof(OnWebSocketEvent)}");
                }
            }
        }
Ejemplo n.º 19
0
        protected override async Task <Response> ImplDownloadAsync(Request request)
        {
            var response = new Response {
                Request = request
            };

            for (var i = 0; i < RetryTime; ++i)
            {
                HttpResponseMessage httpResponseMessage = null;
                WebProxy            proxy = null;
                try
                {
                    var httpRequestMessage = GenerateHttpRequestMessage(request);

                    if (UseProxy)
                    {
                        if (HttpProxyPool == null)
                        {
                            response.Exception = "HttpProxyPool is null";
                            response.Success   = false;
                            Logger?.LogError(
                                $"{request.OwnerId} download {request.Url} failed [{i}]: {response.Exception}");
                            return(response);
                        }
                        else
                        {
                            proxy = HttpProxyPool.GetProxy();
                            if (proxy == null)
                            {
                                response.Exception = "There is no available proxy";
                                response.Success   = false;
                                Logger?.LogError(
                                    $"{request.OwnerId} download {request.Url} failed [{i}]: {response.Exception}");
                                return(response);
                            }
                        }
                    }

                    var httpClientEntry = GetHttpClientEntry(proxy == null ? "DEFAULT" : $"{proxy.Address}", proxy);


                    httpResponseMessage = Framework.NetworkCenter == null
                                                ? await httpClientEntry.HttpClient.SendAsync(httpRequestMessage)
                                                : await Framework.NetworkCenter.Execute(async() =>
                                                                                        await httpClientEntry.HttpClient.SendAsync(httpRequestMessage));

                    httpResponseMessage.EnsureSuccessStatusCode();
                    response.TargetUrl = httpResponseMessage.RequestMessage.RequestUri.AbsoluteUri;
                    response.MediaType = httpResponseMessage.Content.Headers.ContentType.MediaType;
                    response.CharSet   = httpResponseMessage.Content.Headers.ContentType.CharSet;
                    response.Content   = await httpResponseMessage.Content.ReadAsByteArrayAsync();

//					if (!ExcludeMediaTypes.Any(t =>
//						httpResponseMessage.Content.Headers.ContentType.MediaType.Contains(t)))
//					{
//						if (!DownloadFile)
//						{
//							StorageFile(request, bytes);
//						}
//					}
//					else
//					{
//						var content = ReadContent(request, bytes,
//							httpResponseMessage.Content.Headers.ContentType.CharSet);
//
//						if (DecodeHtml)
//						{
//#if NETFRAMEWORK
//                            content = System.Web.HttpUtility.UrlDecode(
//                                System.Web.HttpUtility.HtmlDecode(content),
//                                string.IsNullOrEmpty(request.Encoding)
//                                    ? Encoding.UTF8
//                                    : Encoding.GetEncoding(request.Encoding));
//#else
//							content = WebUtility.UrlDecode(WebUtility.HtmlDecode(content));
//#endif
//						}
//
//						response.RawText = content;
//					}

                    if (!string.IsNullOrWhiteSpace(request.ChangeIpPattern))
                    {
                        var rawtext = ResponseExtensions.ReadContent(request, response.Content, response.CharSet);

                        if (Regex.IsMatch(rawtext, request.ChangeIpPattern))
                        {
                            if (UseProxy)
                            {
                                response.TargetUrl = null;
                                response.Content   = null;
                                response.Success   = false;
                                // 把代理设置为空,影响 final 代码块里不作归还操作,等于删除此代理
                                proxy = null;
                            }
                            else
                            {
                                // 不支持切换 IP
                                if (Framework.NetworkCenter == null ||
                                    !Framework.NetworkCenter.SupportAdsl)
                                {
                                    response.Success   = false;
                                    response.Exception = "IP Banded";
                                    Logger?.LogError(
                                        $"{request.OwnerId} download {request.Url} failed [{i}]: {response.Exception}");
                                    return(response);
                                }
                                else
                                {
                                    Framework.NetworkCenter.Redial();
                                }
                            }
                        }
                    }
                    else
                    {
                        response.Success = true;
                        Logger?.LogInformation(
                            $"{request.OwnerId} download {request.Url} success");
                        return(response);
                    }
                }
                catch (Exception e)
                {
                    response.Exception = e.Message;
                    response.Success   = false;
                    Logger?.LogError($"{request.OwnerId} download {request.Url} failed [{i}]: {e}");
                }
                finally
                {
                    if (HttpProxyPool != null && proxy != null)
                    {
                        HttpProxyPool.ReturnProxy(proxy,
                                                  httpResponseMessage?.StatusCode ?? HttpStatusCode.ServiceUnavailable);
                    }

                    try
                    {
                        httpResponseMessage?.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger?.LogWarning($"{request.OwnerId} dispose response {request.Url} failed [{i}]: {e}");
                    }
                }

                // 下载失败需要等待一秒,防止频率过高。
                // TODO: 改成可配置
                Thread.Sleep(1000);
            }

            return(response);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Deserialize JSON and raise <see cref="UserDataEventArgs"/> event.
        /// </summary>
        /// <param name="json"></param>
        /// <param name="token"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        protected override void DeserializeJsonAndRaiseEvent(string json, CancellationToken token, Action <UserDataEventArgs> callback = null)
        {
            Throw.IfNullOrWhiteSpace(json, nameof(json));

            Logger?.LogDebug($"{nameof(UserDataWebSocketClient)}: \"{json}\"");

            try
            {
                var jObject = JObject.Parse(json);

                var eventType = jObject["e"].Value <string>();
                var eventTime = jObject["E"].Value <long>();

                // ReSharper disable once ConvertIfStatementToSwitchStatement
                if (eventType == "outboundAccountInfo")
                {
                    var commissions = new AccountCommissions(
                        jObject["m"].Value <int>(),  // maker
                        jObject["t"].Value <int>(),  // taker
                        jObject["b"].Value <int>(),  // buyer
                        jObject["s"].Value <int>()); // seller

                    var status = new AccountStatus(
                        jObject["T"].Value <bool>(),  // can trade
                        jObject["W"].Value <bool>(),  // can withdraw
                        jObject["D"].Value <bool>()); // can deposit

                    var balances = jObject["B"]
                                   .Select(entry => new AccountBalance(
                                               entry["a"].Value <string>(),   // asset
                                               entry["f"].Value <decimal>(),  // free amount
                                               entry["l"].Value <decimal>())) // locked amount
                                   .ToList();

                    var eventArgs = new AccountUpdateEventArgs(eventTime, token, new AccountInfo(User, commissions, status, jObject["u"].Value <long>(), balances));

                    try
                    {
                        callback?.Invoke(eventArgs);
                        AccountUpdate?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException) { }
                    catch (Exception e)
                    {
                        if (!token.IsCancellationRequested)
                        {
                            Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled account update event handler exception.");
                        }
                    }
                }
                else if (eventType == "executionReport")
                {
                    var order = new Order(User);

                    FillOrder(order, jObject);

                    var executionType    = ConvertOrderExecutionType(jObject["x"].Value <string>());
                    var rejectedReason   = ConvertOrderRejectedReason(jObject["r"].Value <string>());
                    var newClientOrderId = jObject["c"].Value <string>();

                    if (executionType == OrderExecutionType.Trade) // trade update event.
                    {
                        var trade = new AccountTrade(
                            jObject["s"].Value <string>(),  // symbol
                            jObject["t"].Value <long>(),    // ID
                            jObject["i"].Value <long>(),    // order ID
                            jObject["L"].Value <decimal>(), // price (price of last filled trade)
                            jObject["z"].Value <decimal>(), // quantity (accumulated quantity of filled trades)
                            jObject["n"].Value <decimal>(), // commission
                            jObject["N"].Value <string>(),  // commission asset
                            jObject["T"].Value <long>(),    // timestamp
                            order.Side == OrderSide.Buy,    // is buyer
                            jObject["m"].Value <bool>(),    // is buyer maker
                            jObject["M"].Value <bool>());   // is best price

                        var quantityOfLastFilledTrade = jObject["l"].Value <decimal>();

                        var eventArgs = new AccountTradeUpdateEventArgs(eventTime, token, order, rejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade);

                        try
                        {
                            callback?.Invoke(eventArgs);
                            TradeUpdate?.Invoke(this, eventArgs);
                        }
                        catch (OperationCanceledException) { }
                        catch (Exception e)
                        {
                            if (!token.IsCancellationRequested)
                            {
                                Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled trade update event handler exception.");
                            }
                        }
                    }
                    else // order update event.
                    {
                        var eventArgs = new OrderUpdateEventArgs(eventTime, token, order, executionType, rejectedReason, newClientOrderId);

                        try
                        {
                            callback?.Invoke(eventArgs);
                            OrderUpdate?.Invoke(this, eventArgs);
                        }
                        catch (OperationCanceledException) { }
                        catch (Exception e)
                        {
                            if (!token.IsCancellationRequested)
                            {
                                Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}: Unhandled order update event handler exception.");
                            }
                        }
                    }
                }
                else
                {
                    Logger?.LogWarning($"{nameof(UserDataWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}: Unexpected event type ({eventType}) - \"{json}\"");
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(UserDataWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}");
                }
            }
        }
Ejemplo n.º 21
0
        public async Task <TC> FetchAsync <T, TC>(string query, object paramValues, bool paginatedQuery = false,
                                                  CommandType?dbCommandType = null, int commandTimeout = 0)
            where TC : IRestmeDbEntityCollection <T>, new() where T : IRestmeDbEntity
        {
            try
            {
                SqlMapper.AddTypeMap(typeof(long), DbType.Int32);
                Logger?.LogInformation($"Fetching using DB query: \n {query} ");
                Logger?.LogInformation($"DB query parameters: \n {paramValues?.JsonSerialize()}");
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                var resultSet = new TC();
                // if (paginatedQuery)
                // {
                //     var results =
                //         await (await GetOpenConnectionAsync()).QueryMultipleAsync(query, paramValues,
                //             _currentTransaction,
                //             commandType: dbCommandType);
                //     var totalCount = await results.ReadSingleOrDefaultAsync<int>();
                //     var result = results.Read<T>().AsList();
                //     if (totalCount <= 0) return resultSet;
                //
                //     resultSet.TotalRecordsCount = Convert.ToInt32(totalCount);
                //     if (result.Any())
                //         resultSet.AddRange(result);
                // }
                // else
                // {
                var results =
                    await(await GetOpenConnectionAsync()).QueryAsync <T>(query, paramValues, _currentTransaction,
                                                                         commandType: dbCommandType, commandTimeout: commandTimeout);
                var enumerable = results?.ToList();
                resultSet.TotalRecordsCount = enumerable.Count;

                if (paginatedQuery && enumerable?.Count > 0)
                {
                    var firstItem = enumerable.FirstOrDefault();
                    if (firstItem.BaseSearchCount > 0 && firstItem.BaseSearchCount >= resultSet.TotalRecordsCount)
                    {
                        resultSet.TotalRecordsCount = firstItem.BaseSearchCount;
                    }
                }

                if (enumerable.Any())
                {
                    resultSet.AddRange(enumerable);
                }
                // }

                if (stopwatch.ElapsedMilliseconds >= ExecutionPerformanceThresholdInMs)
                {
                    Logger?.LogWarning($"DB query execution time: \n {stopwatch.ElapsedMilliseconds} ms \n {query}",
                                       dbCommandType,
                                       query, paramValues);
                }
                else
                {
                    Logger?.LogInformation(
                        $"DB query execution time: \n {stopwatch.ElapsedMilliseconds} ms \n {query}");
                }

                return(resultSet);
            }
            catch (Exception ex)
            {
                Logger?.LogError(
                    $"Fetching from db failed\n Query: {query}\n Error: {ex.Message}",
                    ex, query, paramValues, dbCommandType);
                throw ex;
            }
        }
Ejemplo n.º 22
0
        protected override Task <DataFlowResult> Parse(DataFlowContext context)
        {
            var selectable = context.Selectable;

            var results = new ParseResult <T>();

            if (selectable.Properties == null)
            {
                selectable.Properties = new Dictionary <string, object>();
            }

            var environments = new Dictionary <string, string>();

            foreach (var property in context.Response.Request.Properties)
            {
                environments.Add(property.Key, property.Value);
            }

            if (Model.GlobalValueSelectors != null)
            {
                foreach (var selector in Model.GlobalValueSelectors)
                {
                    string name = selector.Name;
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    var value = selectable.Select(selector.ToSelector()).GetValue();
                    if (!environments.ContainsKey(name))
                    {
                        environments.Add(name, value);
                    }
                    else
                    {
                        environments[name] = value;
                    }
                }
            }

            bool singleExtractor = Model.Selector == null;

            if (!singleExtractor)
            {
                var selector = Model.Selector.ToSelector();

                var list = selectable.SelectList(selector).Nodes()?.ToList();
                if (list != null)
                {
                    if (Model.Take > 0 && list.Count > Model.Take)
                    {
                        list = Model.TakeFromHead
                                                        ? list.Take(Model.Take).ToList()
                                                        : list.Skip(list.Count - Model.Take).ToList();
                    }

                    for (var i = 0; i < list.Count; ++i)
                    {
                        var item = list.ElementAt(i);
                        var obj  = ParseObject(environments, item, i);
                        if (obj != null)
                        {
                            results.Add(obj);
                        }
                        else
                        {
                            Logger?.LogWarning($"解析到空数据,类型: {Model.TypeName}");
                        }
                    }
                }
            }
            else
            {
                var obj = ParseObject(environments, selectable, 0);
                if (obj != null)
                {
                    results.Add(obj);
                }
                else
                {
                    Logger?.LogWarning($"解析到空数据,类型: {Model.TypeName}");
                }
            }

            AddParseResult(context, results);

            return(base.Parse(context));
        }
Ejemplo n.º 23
0
        protected override void HandleMessage(IEnumerable <Action <UserDataEventArgs> > callbacks, string stream, string json)
        {
            if (!Users.ContainsKey(stream))
            {
                Logger?.LogError($"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unknown listen key (\"{stream}\").  [thread: {Thread.CurrentThread.ManagedThreadId}]");
                return; // ignore.
            }

            var user = Users[stream];

            try
            {
                var jObject = JObject.Parse(json);

                var eventType = jObject["e"].Value <string>();
                var eventTime = jObject["E"].Value <long>().ToDateTime();

                // ReSharper disable once ConvertIfStatementToSwitchStatement
                if (eventType == "outboundAccountInfo")
                {
                    var commissions = new AccountCommissions(
                        jObject["m"].Value <int>(),  // maker
                        jObject["t"].Value <int>(),  // taker
                        jObject["b"].Value <int>(),  // buyer
                        jObject["s"].Value <int>()); // seller

                    var status = new AccountStatus(
                        jObject["T"].Value <bool>(),  // can trade
                        jObject["W"].Value <bool>(),  // can withdraw
                        jObject["D"].Value <bool>()); // can deposit

                    var balances = jObject["B"]
                                   .Select(entry => new AccountBalance(
                                               entry["a"].Value <string>(),   // asset
                                               entry["f"].Value <decimal>(),  // free amount
                                               entry["l"].Value <decimal>())) // locked amount
                                   .ToList();

                    var eventArgs = new AccountUpdateEventArgs(eventTime, new AccountInfo(user, commissions, status, jObject["u"].Value <long>().ToDateTime(), balances));

                    try
                    {
                        // ReSharper disable once InconsistentlySynchronizedField
                        if (_accountUpdateSubscribers.TryGetValue(stream, out var subscribers))
                        {
                            foreach (var subcriber in subscribers)
                            {
                                subcriber(eventArgs);
                            }
                        }

                        if (callbacks != null)
                        {
                            foreach (var callback in callbacks)
                            {
                                callback(eventArgs);
                            }
                        }

                        AccountUpdate?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException) { /* ignore */ }
                    catch (Exception e)
                    {
                        Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unhandled account update event handler exception.");
                    }
                }
                else if (eventType == "executionReport")
                {
                    var order = new Order(user);

                    FillOrder(order, jObject);

                    var executionType    = ConvertOrderExecutionType(jObject["x"].Value <string>());
                    var rejectedReason   = jObject["r"].Value <string>();
                    var newClientOrderId = jObject["c"].Value <string>();

                    if (executionType == OrderExecutionType.Trade) // trade update event.
                    {
                        var trade = new AccountTrade(
                            jObject["s"].Value <string>(),  // symbol
                            jObject["t"].Value <long>(),    // ID
                            jObject["i"].Value <long>(),    // order ID
                            jObject["L"].Value <decimal>(), // price (price of last filled trade)
                            jObject["z"].Value <decimal>(), // quantity (accumulated quantity of filled trades)
                            jObject["n"].Value <decimal>(), // commission
                            jObject["N"].Value <string>(),  // commission asset
                            jObject["T"].Value <long>()
                            .ToDateTime(),                  // time
                            order.Side == OrderSide.Buy,    // is buyer
                            jObject["m"].Value <bool>(),    // is buyer maker
                            jObject["M"].Value <bool>());   // is best price

                        var quantityOfLastFilledTrade = jObject["l"].Value <decimal>();

                        var eventArgs = new AccountTradeUpdateEventArgs(eventTime, order, rejectedReason, newClientOrderId, trade, quantityOfLastFilledTrade);

                        try
                        {
                            // ReSharper disable once InconsistentlySynchronizedField
                            if (_accountTradeUpdateSubscribers.TryGetValue(stream, out var subscribers))
                            {
                                foreach (var subcriber in subscribers)
                                {
                                    subcriber(eventArgs);
                                }
                            }

                            if (callbacks != null)
                            {
                                foreach (var callback in callbacks)
                                {
                                    callback(eventArgs);
                                }
                            }

                            TradeUpdate?.Invoke(this, eventArgs);
                        }
                        catch (OperationCanceledException) { /* ignore */ }
                        catch (Exception e)
                        {
                            Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unhandled trade update event handler exception.");
                        }
                    }
                    else // order update event.
                    {
                        var eventArgs = new OrderUpdateEventArgs(eventTime, order, executionType, rejectedReason, newClientOrderId);

                        try
                        {
                            // ReSharper disable once InconsistentlySynchronizedField
                            if (_orderUpdateSubscribers.TryGetValue(stream, out var subscribers))
                            {
                                foreach (var subcriber in subscribers)
                                {
                                    subcriber(eventArgs);
                                }
                            }

                            if (callbacks != null)
                            {
                                foreach (var callback in callbacks)
                                {
                                    callback(eventArgs);
                                }
                            }

                            OrderUpdate?.Invoke(this, eventArgs);
                        }
                        catch (OperationCanceledException) { /* ignore */ }
                        catch (Exception e)
                        {
                            Logger?.LogWarning(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unhandled order update event handler exception.");
                        }
                    }
                }
                else
                {
                    Logger?.LogWarning($"{nameof(UserDataClient)}.{nameof(HandleMessage)}: Unexpected event type ({eventType}).");
                }
            }
            catch (OperationCanceledException) { /* ignore */ }
            catch (Exception e)
            {
                Logger?.LogError(e, $"{nameof(UserDataClient)}.{nameof(HandleMessage)}");
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Deserialize JSON and raise <see cref="DepthUpdateEventArgs"/> event.
        /// </summary>
        /// <param name="json"></param>
        /// <param name="token"></param>
        /// <param name="callback"></param>
        protected override void DeserializeJsonAndRaiseEvent(string json, CancellationToken token, Action <DepthUpdateEventArgs> callback = null)
        {
            Throw.IfNullOrWhiteSpace(json, nameof(json));

            Logger?.LogDebug($"{nameof(DepthWebSocketClient)}: \"{json}\"");

            try
            {
                var jObject = JObject.Parse(json);

                var eventType = jObject["e"]?.Value <string>();

                DepthUpdateEventArgs eventArgs = null;

                if (eventType == null) // partial order book stream.
                {
                    // Simulate event time.
                    var eventTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

                    var lastUpdateId = jObject["lastUpdateId"].Value <long>();

                    var bids = jObject["bids"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList();
                    var asks = jObject["asks"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList();

                    eventArgs = new DepthUpdateEventArgs(eventTime, token, Symbol, lastUpdateId, lastUpdateId, bids, asks);
                }
                else if (eventType == "depthUpdate")
                {
                    var symbol    = jObject["s"].Value <string>();
                    var eventTime = jObject["E"].Value <long>();

                    var firstUpdateId = jObject["U"].Value <long>();
                    var lastUpdateId  = jObject["u"].Value <long>();

                    var bids = jObject["b"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList();
                    var asks = jObject["a"].Select(entry => (entry[0].Value <decimal>(), entry[1].Value <decimal>())).ToList();

                    eventArgs = new DepthUpdateEventArgs(eventTime, token, symbol, firstUpdateId, lastUpdateId, bids, asks);
                }
                else
                {
                    Logger?.LogWarning($"{nameof(DepthWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}: Unexpected event type ({eventType}).");
                    return;
                }

                try
                {
                    callback?.Invoke(eventArgs);
                    DepthUpdate?.Invoke(this, eventArgs);
                }
                catch (OperationCanceledException) { }
                catch (Exception e)
                {
                    if (!token.IsCancellationRequested)
                    {
                        Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}: Unhandled depth update event handler exception.");
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(DepthWebSocketClient)}.{nameof(DeserializeJsonAndRaiseEvent)}");
                }
            }
        }
Ejemplo n.º 25
0
        public override async Task StreamAsync(Uri uri, CancellationToken token)
        {
            Throw.IfNull(uri, nameof(uri));

            if (!token.CanBeCanceled)
            {
                throw new ArgumentException($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Token must be capable of being in the canceled state.", nameof(token));
            }

            if (token.IsCancellationRequested)
            {
                return;
            }

            lock (_sync)
            {
                if (IsStreaming)
                {
                    throw new InvalidOperationException($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Already streaming (this method is not reentrant).");
                }

                IsStreaming = true;
            }

            var webSocket = new ClientWebSocket();

            webSocket.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);

            try
            {
                try
                {
                    Logger?.LogInformation($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Web socket connecting...");

                    await webSocket.ConnectAsync(uri, token)
                    .ConfigureAwait(false);

                    if (webSocket.State != WebSocketState.Open)
                    {
                        throw new Exception($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: WebSocket connect failed (state: {webSocket.State}).");
                    }

                    OnOpen();
                }
                catch (OperationCanceledException) { /* ignore */ }
                catch (Exception e)
                {
                    if (!token.IsCancellationRequested)
                    {
                        Logger?.LogWarning(e, $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: WebSocket connect exception (state: {webSocket.State}).");
                        throw;
                    }
                }

                var bytes  = new byte[ReceiveBufferSize];
                var buffer = new ArraySegment <byte>(bytes);

                var stringBuilder = new StringBuilder();

                while (!token.IsCancellationRequested)
                {
                    stringBuilder.Clear();

                    try
                    {
                        WebSocketReceiveResult result;
                        do
                        {
                            if (webSocket.State != WebSocketState.Open && webSocket.State != WebSocketState.CloseSent)
                            {
                                break;
                            }

                            result = await webSocket
                                     .ReceiveAsync(buffer, token)
                                     .ConfigureAwait(false);

                            switch (result.MessageType)
                            {
                            case WebSocketMessageType.Close:
                                var message = result.CloseStatus.HasValue
                                        ? $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Web socket closed ({result.CloseStatus.Value}): \"{result.CloseStatusDescription ?? "[no reason provided]"}\""
                                        : $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Web socket closed: \"{result.CloseStatusDescription ?? "[no reason provided]"}\"";

                                Logger?.LogWarning(message);

                                await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
                                .ConfigureAwait(false);

                                break;

                            case WebSocketMessageType.Text when result.Count > 0:
                                stringBuilder.Append(Encoding.UTF8.GetString(bytes, 0, result.Count));
                                break;

                            case WebSocketMessageType.Binary:
                                Logger?.LogWarning($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Received unsupported binary message type (state: {webSocket.State}).");
                                break;

                            default:
                                throw new ArgumentOutOfRangeException(nameof(result.MessageType), $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Unknown result message type ({result.MessageType}).");
                            }
                        }while (!result.EndOfMessage);
                    }
                    catch (OperationCanceledException) { /* ignore */ }
                    catch (Exception e)
                    {
                        if (!token.IsCancellationRequested)
                        {
                            Logger?.LogWarning(e, $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: WebSocket receive exception (state: {webSocket.State}).");
                            throw;
                        }
                    }

                    if (token.IsCancellationRequested || webSocket.State == WebSocketState.Aborted)
                    {
                        break;
                    }

                    var json = stringBuilder.ToString();
                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        OnMessage(json, uri.AbsolutePath);
                    }
                    else
                    {
                        Logger?.LogWarning($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Received empty JSON message (state: {webSocket.State}).");
                    }
                }
            }
            finally
            {
                //if (webSocket.State == WebSocketState.Open || webSocket.State == WebSocketState.CloseReceived || webSocket.State == WebSocketState.CloseSent)
                //{
                //    try
                //    {
                //        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None)
                //            .ConfigureAwait(false);
                //    }
                //    catch (Exception e)
                //    {
                //        Logger?.LogWarning(e, $"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: WebSocket close exception (state: {webSocket.State}).");
                //    }
                //}

                webSocket?.Dispose();

                lock (_sync) { IsStreaming = false; }

                if (IsOpen)
                {
                    OnClose();
                }

                Logger?.LogDebug($"{nameof(DefaultWebSocketClient)}.{nameof(StreamAsync)}: Task complete.  [thread: {Thread.CurrentThread.ManagedThreadId}]");
            }
        }
Ejemplo n.º 26
0
        protected override void OnWebSocketEvent(WebSocketStreamEventArgs args, IEnumerable <Action <TradeEventArgs> > callbacks)
        {
            Logger?.LogDebug($"{nameof(TradeWebSocketClient)}: \"{args.Json}\"");

            try
            {
                var jObject = JObject.Parse(args.Json);

                var eventType = jObject["e"].Value <string>();

                if (eventType == "trade")
                {
                    var eventTime = jObject["E"].Value <long>().ToDateTimeK();

                    var trade = new Trade(
                        jObject["s"].Value <string>(),  // symbol
                        jObject["t"].Value <long>(),    // trade ID
                        jObject["p"].Value <decimal>(), // price
                        jObject["q"].Value <decimal>(), // quantity
                        jObject["b"].Value <long>(),    // buyer order ID
                        jObject["a"].Value <long>(),    // seller order ID
                        jObject["T"].Value <long>()
                        .ToDateTimeK(),                 // trade time
                        jObject["m"].Value <bool>(),    // is buyer the market maker?
                        jObject["M"].Value <bool>());   // is best price match?

                    var eventArgs = new TradeEventArgs(eventTime, args.Token, trade);

                    try
                    {
                        if (callbacks != null)
                        {
                            foreach (var callback in callbacks)
                            {
                                callback(eventArgs);
                            }
                        }
                        Trade?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException) { }
                    catch (Exception e)
                    {
                        if (!args.Token.IsCancellationRequested)
                        {
                            Logger?.LogError(e, $"{nameof(TradeWebSocketClient)}: Unhandled aggregate trade event handler exception.");
                        }
                    }
                }
                else
                {
                    Logger?.LogWarning($"{nameof(TradeWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unexpected event type ({eventType}).");
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!args.Token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(TradeWebSocketClient)}.{nameof(OnWebSocketEvent)}");
                }
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Tries to fetch the result from disk cache, the memory queue, or create it. If the memory queue has space,
        /// the writeCallback() will be executed and the resulting bytes put in a queue for writing to disk.
        /// If the memory queue is full, writing to disk will be attempted synchronously.
        /// In either case, writing to disk can also fail if the disk cache is full and eviction fails.
        /// If the memory queue is full, eviction will be done synchronously and can cause other threads to time out
        /// while waiting for QueueLock
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataProviderCallback"></param>
        /// <param name="cancellationToken"></param>
        /// <param name="retrieveContentType"></param>
        /// <returns></returns>
        /// <exception cref="OperationCanceledException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public async Task <AsyncCacheResult> GetOrCreateBytes(
            byte[] key,
            AsyncBytesResult dataProviderCallback,
            CancellationToken cancellationToken,
            bool retrieveContentType)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException(cancellationToken);
            }

            var swGetOrCreateBytes = Stopwatch.StartNew();
            var entry = new CacheEntry(key, PathBuilder);

            // Tell cleanup what we're using
            CleanupManager.NotifyUsed(entry);

            // Fast path on disk hit
            var swFileExists = Stopwatch.StartNew();

            var fileBasedResult = await TryGetFileBasedResult(entry, false, retrieveContentType, cancellationToken);

            if (fileBasedResult != null)
            {
                return(fileBasedResult);
            }
            // Just continue on creating the file. It must have been deleted between the calls

            swFileExists.Stop();



            var cacheResult = new AsyncCacheResult();

            //Looks like a miss. Let's enter a lock for the creation of the file. This is a different locking system
            // than for writing to the file
            //This prevents two identical requests from duplicating efforts. Different requests don't lock.

            //Lock execution using relativePath as the sync basis. Ignore casing differences. This prevents duplicate entries in the write queue and wasted CPU/RAM usage.
            var queueLockComplete = await QueueLocks.TryExecuteAsync(entry.StringKey,
                                                                     Options.WaitForIdenticalRequestsTimeoutMs, cancellationToken,
                                                                     async() =>
            {
                var swInsideQueueLock = Stopwatch.StartNew();

                // Now, if the item we seek is in the queue, we have a memcached hit.
                // If not, we should check the filesystem. It's possible the item has been written to disk already.
                // If both are a miss, we should see if there is enough room in the write queue.
                // If not, switch to in-thread writing.

                var existingQueuedWrite = CurrentWrites.Get(entry.StringKey);

                if (existingQueuedWrite != null)
                {
                    cacheResult.Data        = existingQueuedWrite.GetReadonlyStream();
                    cacheResult.ContentType = existingQueuedWrite.ContentType;
                    cacheResult.Detail      = AsyncCacheDetailResult.MemoryHit;
                    return;
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(cancellationToken);
                }

                swFileExists.Start();
                // Fast path on disk hit, now that we're in a synchronized state
                var fileBasedResult2 = await TryGetFileBasedResult(entry, true, retrieveContentType, cancellationToken);
                if (fileBasedResult2 != null)
                {
                    cacheResult = fileBasedResult2;
                    return;
                }
                // Just continue on creating the file. It must have been deleted between the calls

                swFileExists.Stop();

                var swDataCreation = Stopwatch.StartNew();
                //Read, resize, process, and encode the image. Lots of exceptions thrown here.
                var result = await dataProviderCallback(cancellationToken);
                swDataCreation.Stop();

                //Create AsyncWrite object to enqueue
                var w = new AsyncWrite(entry.StringKey, result.Item2, result.Item1);

                cacheResult.Detail      = AsyncCacheDetailResult.Miss;
                cacheResult.ContentType = w.ContentType;
                cacheResult.Data        = w.GetReadonlyStream();

                // Create a lambda which we can call either in a spawned Task (if enqueued successfully), or
                // in this task, if our buffer is full.
                async Task <AsyncCacheDetailResult> EvictWriteAndLogUnsynchronized(bool queueFull, TimeSpan dataCreationTime, CancellationToken ct)
                {
                    var delegateStartedAt = DateTime.UtcNow;
                    var swReserveSpace    = Stopwatch.StartNew();
                    //We only permit eviction proceedings from within the queue or if the queue is disabled
                    var allowEviction      = !queueFull || CurrentWrites.MaxQueueBytes <= 0;
                    var reserveSpaceResult = await CleanupManager.TryReserveSpace(entry, w.ContentType,
                                                                                  w.GetUsedBytes(), allowEviction, EvictAndWriteLocks, ct);
                    swReserveSpace.Stop();

                    var syncString = queueFull ? "synchronous" : "async";
                    if (!reserveSpaceResult.Success)
                    {
                        Logger?.LogError(
                            queueFull
                                    ? "HybridCache synchronous eviction failed; {Message}. Time taken: {1}ms - {2}"
                                    : "HybridCache async eviction failed; {Message}. Time taken: {1}ms - {2}",
                            syncString, reserveSpaceResult.Message, swReserveSpace.ElapsedMilliseconds,
                            entry.RelativePath);

                        return(AsyncCacheDetailResult.CacheEvictionFailed);
                    }

                    var swIo = Stopwatch.StartNew();
                    // We only force an immediate File.Exists check when running from the Queue
                    // Otherwise it happens inside the lock
                    var fileWriteResult = await FileWriter.TryWriteFile(entry, delegate(Stream s, CancellationToken ct2)
                    {
                        if (ct2.IsCancellationRequested)
                        {
                            throw new OperationCanceledException(ct2);
                        }

                        var fromStream = w.GetReadonlyStream();
                        return(fromStream.CopyToAsync(s, 81920, ct2));
                    }, !queueFull, Options.WaitForIdenticalDiskWritesMs, ct);
                    swIo.Stop();

                    var swMarkCreated = Stopwatch.StartNew();
                    // Mark the file as created so it can be deleted
                    await CleanupManager.MarkFileCreated(entry,
                                                         w.ContentType,
                                                         w.GetUsedBytes(),
                                                         DateTime.UtcNow);
                    swMarkCreated.Stop();

                    switch (fileWriteResult)
                    {
                    case CacheFileWriter.FileWriteStatus.LockTimeout:
                        //We failed to lock the file.
                        Logger?.LogWarning("HybridCache {Sync} write failed; disk lock timeout exceeded after {IoTime}ms - {Path}",
                                           syncString, swIo.ElapsedMilliseconds, entry.RelativePath);
                        return(AsyncCacheDetailResult.WriteTimedOut);

                    case CacheFileWriter.FileWriteStatus.FileAlreadyExists:
                        Logger?.LogTrace("HybridCache {Sync} write found file already exists in {IoTime}ms, after a {DelayTime}ms delay and {CreationTime}- {Path}",
                                         syncString, swIo.ElapsedMilliseconds,
                                         delegateStartedAt.Subtract(w.JobCreatedAt).TotalMilliseconds,
                                         dataCreationTime, entry.RelativePath);
                        return(AsyncCacheDetailResult.FileAlreadyExists);

                    case CacheFileWriter.FileWriteStatus.FileCreated:
                        if (queueFull)
                        {
                            Logger?.LogTrace(@"HybridCache synchronous write complete. Create: {CreateTime}ms. Write {WriteTime}ms. Mark Created: {MarkCreatedTime}ms. Eviction: {EvictionTime}ms - {Path}",
                                             Math.Round(dataCreationTime.TotalMilliseconds).ToString(CultureInfo.InvariantCulture).PadLeft(4),
                                             swIo.ElapsedMilliseconds.ToString().PadLeft(4),
                                             swMarkCreated.ElapsedMilliseconds.ToString().PadLeft(4),
                                             swReserveSpace.ElapsedMilliseconds.ToString().PadLeft(4), entry.RelativePath);
                        }
                        else
                        {
                            Logger?.LogTrace(@"HybridCache async write complete. Create: {CreateTime}ms. Write {WriteTime}ms. Mark Created: {MarkCreatedTime}ms Eviction {EvictionTime}ms. Delay {DelayTime}ms. - {Path}",
                                             Math.Round(dataCreationTime.TotalMilliseconds).ToString(CultureInfo.InvariantCulture).PadLeft(4),
                                             swIo.ElapsedMilliseconds.ToString().PadLeft(4),
                                             swMarkCreated.ElapsedMilliseconds.ToString().PadLeft(4),
                                             swReserveSpace.ElapsedMilliseconds.ToString().PadLeft(4),
                                             Math.Round(delegateStartedAt.Subtract(w.JobCreatedAt).TotalMilliseconds).ToString(CultureInfo.InvariantCulture).PadLeft(4),
                                             entry.RelativePath);
                        }

                        return(AsyncCacheDetailResult.WriteSucceeded);

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                async Task <AsyncCacheDetailResult> EvictWriteAndLogSynchronized(bool queueFull,
                                                                                 TimeSpan dataCreationTime, CancellationToken ct)
                {
                    var cacheDetailResult = AsyncCacheDetailResult.Unknown;
                    var writeLockComplete = await EvictAndWriteLocks.TryExecuteAsync(entry.StringKey,
                                                                                     Options.WaitForIdenticalRequestsTimeoutMs, cancellationToken,
                                                                                     async() =>
                    {
                        cacheDetailResult =
                            await EvictWriteAndLogUnsynchronized(queueFull, dataCreationTime, ct);
                    });
                    if (!writeLockComplete)
                    {
                        cacheDetailResult = AsyncCacheDetailResult.EvictAndWriteLockTimedOut;
                    }

                    return(cacheDetailResult);
                }


                var swEnqueue   = Stopwatch.StartNew();
                var queueResult = CurrentWrites.Queue(w, async delegate
                {
                    try
                    {
                        var unused = await EvictWriteAndLogSynchronized(false, swDataCreation.Elapsed, CancellationToken.None);
                    }
                    catch (Exception ex)
                    {
                        Logger?.LogError(ex, "HybridCache failed to flush async write, {Exception} {Path}\n{StackTrace}", ex.ToString(),
                                         entry.RelativePath, ex.StackTrace);
                    }
                });
                swEnqueue.Stop();
                swInsideQueueLock.Stop();
                swGetOrCreateBytes.Stop();

                if (queueResult == AsyncWriteCollection.AsyncQueueResult.QueueFull)
                {
                    if (Options.WriteSynchronouslyWhenQueueFull)
                    {
                        var writerDelegateResult = await EvictWriteAndLogSynchronized(true, swDataCreation.Elapsed, cancellationToken);
                        cacheResult.Detail       = writerDelegateResult;
                    }
                }
            });
Ejemplo n.º 28
0
        public override async Task StreamAsync(Uri uri, CancellationToken token)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            if (!token.CanBeCanceled)
            {
                throw new ArgumentException("Token must be capable of being in the canceled state.", nameof(token));
            }

            token.ThrowIfCancellationRequested();

            Exception exception = null;

            var tcs = new TaskCompletionSource <object>();

            token.Register(() => tcs.TrySetCanceled());

            var webSocket = new WebSocket4Net.WebSocket(uri.AbsoluteUri);

            webSocket.Opened += (s, e) =>
            {
                IsStreaming = true;
                RaiseOpenEvent();
            };

            webSocket.Closed += (s, e) => tcs.TrySetCanceled();

            webSocket.MessageReceived += (s, evt) =>
            {
                try
                {
                    var json = evt.Message;

                    if (!string.IsNullOrWhiteSpace(json))
                    {
                        RaiseMessageEvent(new WebSocketClientEventArgs(json));
                    }
                    else
                    {
                        Logger?.LogWarning($"{nameof(WebSocket4NetClient)}.MessageReceived: Received empty JSON message.");
                    }
                }
                catch (OperationCanceledException) { }
                catch (Exception e)
                {
                    if (!token.IsCancellationRequested)
                    {
                        Logger?.LogError(e, $"{nameof(WebSocket4NetClient)}.MessageReceived: WebSocket read exception.");
                        exception = e;
                        tcs.TrySetCanceled();
                    }
                }
            };

            webSocket.Error += (s, e) =>
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                Logger?.LogError(e.Exception, $"{nameof(WebSocket4NetClient)}.Error: WebSocket exception.");
                exception = e.Exception;
                tcs.TrySetCanceled();
            };

            try
            {
                webSocket.Open();

                await tcs.Task
                .ConfigureAwait(false);

                if (exception != null)
                {
                    throw exception;
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(WebSocket4NetClient)}.{nameof(StreamAsync)}: WebSocket open exception.");
                    throw;
                }
            }
            finally
            {
                if (webSocket.State == WebSocket4Net.WebSocketState.Open)
                {
                    try { webSocket.Close(); }
                    catch (Exception e)
                    {
                        Logger?.LogError(e, $"{nameof(WebSocket4NetClient)}.{nameof(StreamAsync)}: WebSocket close exception.");
                    }
                }

                webSocket.Dispose();

                if (IsStreaming)
                {
                    IsStreaming = false;
                    RaiseCloseEvent();
                }
            }
        }
Ejemplo n.º 29
0
        protected override Task HandleMessageAsync(IEnumerable <Action <SymbolStatisticsEventArgs> > callbacks, string stream, string json, CancellationToken token = default)
        {
            try
            {
                SymbolStatisticsEventArgs eventArgs;

                if (json.IsJsonArray())
                {
                    // Simulate a single event time.
                    var eventTime = DateTime.UtcNow.ToTimestamp().ToDateTime();

                    var statistics = JArray.Parse(json).Select(DeserializeSymbolStatistics).ToArray();

                    eventArgs = new SymbolStatisticsEventArgs(eventTime, token, statistics);
                }
                else
                {
                    var jObject = JObject.Parse(json);

                    var eventType = jObject["e"].Value <string>();

                    if (eventType == "24hrTicker")
                    {
                        var eventTime = jObject["E"].Value <long>().ToDateTime();

                        var statistics = DeserializeSymbolStatistics(jObject);

                        eventArgs = new SymbolStatisticsEventArgs(eventTime, token, statistics);
                    }
                    else
                    {
                        Logger?.LogWarning($"{nameof(SymbolStatisticsClient)}.{nameof(HandleMessageAsync)}: Unexpected event type ({eventType}).");
                        return(Task.CompletedTask);
                    }
                }

                try
                {
                    if (callbacks != null)
                    {
                        foreach (var callback in callbacks)
                        {
                            callback(eventArgs);
                        }
                    }
                    StatisticsUpdate?.Invoke(this, eventArgs);
                }
                catch (OperationCanceledException) { }
                catch (Exception e)
                {
                    if (!token.IsCancellationRequested)
                    {
                        Logger?.LogError(e, $"{nameof(SymbolStatisticsClient)}: Unhandled aggregate trade event handler exception.");
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(SymbolStatisticsClient)}.{nameof(HandleMessageAsync)}");
                }
            }

            return(Task.CompletedTask);
        }
Ejemplo n.º 30
0
        protected override void OnWebSocketEvent(WebSocketStreamEventArgs args, IEnumerable <Action <CandlestickEventArgs> > callbacks)
        {
            Logger?.LogDebug($"{nameof(CandlestickWebSocketClient)}: \"{args.Json}\"");

            try
            {
                var jObject = JObject.Parse(args.Json);

                var eventType = jObject["e"].Value <string>();

                if (eventType == "kline")
                {
                    //var symbol = jObject["s"].Value<string>();
                    var eventTime = jObject["E"].Value <long>();

                    var firstTradeId = jObject["k"]["f"].Value <long>();
                    var lastTradeId  = jObject["k"]["L"].Value <long>();

                    var isFinal = jObject["k"]["x"].Value <bool>();

                    var candlestick = new Candlestick(
                        jObject["k"]["s"].Value <string>(),  // symbol
                        jObject["k"]["i"].Value <string>()
                        .ToCandlestickInterval(),            // interval
                        jObject["k"]["t"].Value <long>(),    // open time
                        jObject["k"]["o"].Value <decimal>(), // open
                        jObject["k"]["h"].Value <decimal>(), // high
                        jObject["k"]["l"].Value <decimal>(), // low
                        jObject["k"]["c"].Value <decimal>(), // close
                        jObject["k"]["v"].Value <decimal>(), // volume
                        jObject["k"]["T"].Value <long>(),    // close time
                        jObject["k"]["q"].Value <decimal>(), // quote asset volume
                        jObject["k"]["n"].Value <long>(),    // number of trades
                        jObject["k"]["V"].Value <decimal>(), // taker buy base asset volume (volume of active buy)
                        jObject["k"]["Q"].Value <decimal>()  // taker buy quote asset volume (quote volume of active buy)
                        );

                    var eventArgs = new CandlestickEventArgs(eventTime, args.Token, candlestick, firstTradeId, lastTradeId, isFinal);

                    try
                    {
                        if (callbacks != null)
                        {
                            foreach (var callback in callbacks)
                            {
                                callback(eventArgs);
                            }
                        }
                        Candlestick?.Invoke(this, eventArgs);
                    }
                    catch (OperationCanceledException) { }
                    catch (Exception e)
                    {
                        if (!args.Token.IsCancellationRequested)
                        {
                            Logger?.LogError(e, $"{nameof(CandlestickWebSocketClient)}: Unhandled candlestick event handler exception.");
                        }
                    }
                }
                else
                {
                    Logger?.LogWarning($"{nameof(CandlestickWebSocketClient)}.{nameof(OnWebSocketEvent)}: Unexpected event type ({eventType}).");
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                if (!args.Token.IsCancellationRequested)
                {
                    Logger?.LogError(e, $"{nameof(CandlestickWebSocketClient)}.{nameof(OnWebSocketEvent)}");
                }
            }
        }