/// <summary>
        /// RealTimeTelemetryManager constructor for RealTimeTelemetryManager instance creation
        /// </summary>
        /// <param name="nodeId">Node Id </param>
        /// <param name="jsonRpcUrl">JSON Rpc of Parity </param>
        /// <param name="webSocketUrl">Web Socket URL of Parity </param>
        /// <param name="ingressEndPoint">Ingress REal time restful End Point </param>
        /// <param name="ingressFingerPrint">Ingress Finger Print </param>
        /// <param name="signer">Payload Signer instance reference </param>
        /// <param name="ftpMgr">FTPManager instance reference </param>
        /// <param name="verbose">if detailed logs are required set verbose to true </param>
        /// <returns>returns instance of RealTimeTelemetryManager</returns>
        /// <exception cref="System.ArgumentException">Thrown when any of provided argument is null or empty.</exception>
        public RealTimeTelemetryManager(string nodeId, string jsonRpcUrl, string webSocketUrl, string ingressEndPoint, string ingressFingerPrint, PayloadSigner signer, FtpManager ftpMgr, bool verbose = true)
        {
            if (string.IsNullOrWhiteSpace(nodeId))
            {
                throw new ArgumentException("Node ID is empty", nameof(nodeId));
            }

            if (string.IsNullOrWhiteSpace(jsonRpcUrl))
            {
                throw new ArgumentException("RPC URL is empty", nameof(jsonRpcUrl));
            }

            if (string.IsNullOrWhiteSpace(webSocketUrl))
            {
                throw new ArgumentException("Web Socket URL is empty", nameof(webSocketUrl));
            }

            if (string.IsNullOrWhiteSpace(ingressEndPoint))
            {
                throw new ArgumentException("Ingress END Point is empty", nameof(ingressEndPoint));
            }

            if (string.IsNullOrWhiteSpace(ingressFingerPrint))
            {
                throw new ArgumentException("Ingress Finger Point is empty", nameof(ingressFingerPrint));
            }

            _ftpMgr = ftpMgr ?? throw new ArgumentException("FTP Manager is null", nameof(ftpMgr));
            _signer = signer ?? throw new ArgumentException("Signer is null", nameof(signer));

            _webSocketUri = webSocketUrl;
            _jsonRpcUrl   = jsonRpcUrl;
            _nodeId       = nodeId;
            _verbose      = verbose;


            _tti = new TalkToIngress(ingressEndPoint, ingressFingerPrint);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sends data to Ingress restful end point
        /// </summary>
        /// <param name="state">Object state</param>
        private static void FlushToIngress(object state)
        {
            // Flush to ingress if more than 10 telemetry recordings -or- last flush older that 1 minute
            if (_globalQueue.Count <= 10 && DateTime.UtcNow - _lastFlush <= new TimeSpan(0, 1, 0))
            {
                Console.WriteLine($"Not flushing: {_globalQueue.Count} Queued - {(DateTime.UtcNow - _lastFlush).TotalSeconds} seconds since flush");
                return;
            }

            List <string> telemetryToSend = new List <string>();

            while (telemetryToSend.Count < 50 && _globalQueue.TryDequeue(out string lineFromQueue))
            {
                telemetryToSend.Add(lineFromQueue);
            }

            Console.WriteLine($"Flushing {telemetryToSend.Count} to ingress. {_globalQueue.Count} still in queue." + (_flushHighspeed ? " [HighSpeed]" : ""));

            TelemetryPacket pkt = new TelemetryPacket
            {
                NodeId    = _configuration.NodeId,
                Payload   = telemetryToSend,
                Signature = _signer.SignPayload(string.Join(string.Empty, telemetryToSend))
            };

            string jsonPayload = JsonConvert.SerializeObject(pkt);

            // Send data
            TalkToIngress tti         = new TalkToIngress(_configuration.IngressHost + "/api/ingress/influx", _configuration.IngressFingerprint);
            bool          sendSuccess = tti.SendRequest(jsonPayload).Result;

            if (!sendSuccess)
            {
                if (DateTime.UtcNow - _lastFlush > TimeSpan.FromMinutes(5))
                {
                    // unable to send to ingress for 5 minutes - send by second channel
                    Console.WriteLine("ERROR: Unable to send to ingress for more then 5 minutes. Sending queue on second channel.");
                    string fileName = $"{_configuration.NodeId}-{DateTime.UtcNow:yyyy-MM-dd_HH:mm:ss}.json";
                    try
                    {
                        if (!_ftpMgr.TransferData(jsonPayload, fileName))
                        {
                            Console.WriteLine("ERROR: Unable to send data on second channel. Data File {0}", fileName);

                            // second channel also not available - requeue
                            Console.WriteLine("Unable to flush to second channel - re queueing");
                            telemetryToSend.ForEach(_globalQueue.Enqueue);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("ERROR: Unable to send data on second channel. Error Details {0}", ex);

                        // second channel also not available - requeue
                        Console.WriteLine("Unable to flush to second channel - re queueing");
                        telemetryToSend.ForEach(_globalQueue.Enqueue);
                    }
                }
                else
                {
                    // 5min second channel delay not reached -> re-queue
                    Console.WriteLine("Unable to flush. Re-queuing...");
                    telemetryToSend.ForEach(_globalQueue.Enqueue);
                }
            }
            else
            {
                if (_globalQueue.Count > 250 && !_flushHighspeed)
                {
                    // increase processing speed to 2 seconds
                    Console.WriteLine("Increasing push speed due to queue size");
                    _flushTimer.Change(2000, 2000);
                    _flushHighspeed = true;
                }
                else if (_globalQueue.Count < 250 && _flushHighspeed) // queue is small enough to get processed. back to normal speed
                {
                    Console.WriteLine("Decreasing push speed due to queue size");
                    _flushTimer.Change(10000, 10000);
                    _flushHighspeed = false;
                }
                _lastFlush = DateTime.UtcNow;
            }
        }