Example #1
0
    public void ProcessTest()
    {
        var let = new LastExceptionTracker();

        // Process first exception to process.
        {
            ExceptionInfo lastException = let.Process(new ArgumentOutOfRangeException());

            Assert.IsType <ArgumentOutOfRangeException>(lastException.Exception);
            Assert.Equal(1, lastException.ExceptionCount);
        }

        // Same exception encountered.
        {
            ExceptionInfo lastException = let.Process(new ArgumentOutOfRangeException());

            Assert.IsType <ArgumentOutOfRangeException>(lastException.Exception);
            Assert.Equal(2, lastException.ExceptionCount);
        }

        // Different exception encountered.
        {
            ExceptionInfo lastException = let.Process(new NotImplementedException());

            Assert.IsType <NotImplementedException>(lastException.Exception);
            Assert.Equal(1, lastException.ExceptionCount);
        }
    }
Example #2
0
        /// <summary>
        /// This method can be called only once.
        /// </summary>
        public async Task StartAsync(CancellationToken cancel)
        {
            int    ptcv            = PrintToConsole ? 1 : 0;
            string processPath     = MicroserviceHelpers.GetBinaryPath("bitcoind");
            string networkArgument = NetworkTranslator.GetCommandLineArguments(Network);

            string args = $"{networkArgument} -datadir=\"{DataDir}\" -printtoconsole={ptcv}";

            // Start bitcoind process.
            Process = new ProcessAsync(ProcessStartInfoFactory.Make(processPath, args));
            Process.Start();

            // Store PID in PID file.
            await PidFile.WriteFileAsync(Process.Id).ConfigureAwait(false);

            CachedPid = Process.Id;

            try
            {
                var exceptionTracker = new LastExceptionTracker();

                // Try to connect to bitcoin daemon RPC until we succeed.
                while (true)
                {
                    try
                    {
                        TimeSpan timeSpan = await RpcClient.UptimeAsync(cancel).ConfigureAwait(false);

                        Logger.LogInfo("RPC connection is successfully established.");
                        Logger.LogDebug($"RPC uptime is: {timeSpan}.");

                        // Bitcoin daemon is started. We are done.
                        break;
                    }
                    catch (Exception ex)
                    {
                        ExceptionInfo exceptionInfo = exceptionTracker.Process(ex);

                        // Don't log extensively.
                        if (exceptionInfo.IsFirst)
                        {
                            Logger.LogInfo($"{Constants.BuiltinBitcoinNodeName} is not yet ready... Reason: {exceptionInfo.Exception.Message}");
                        }

                        if (Process is { } p&& p.HasExited)
                        {
                            throw new BitcoindException($"Failed to start daemon, location: '{p.StartInfo.FileName} {p.StartInfo.Arguments}'", ex);
                        }
                    }

                    if (cancel.IsCancellationRequested)
                    {
                        Logger.LogDebug("Bitcoin daemon was not started yet and user requested to cancel the operation.");
                        await StopAsync(onlyOwned : true).ConfigureAwait(false);

                        cancel.ThrowIfCancellationRequested();
                    }

                    // Wait a moment before the next check.
                    await Task.Delay(100, cancel).ConfigureAwait(false);
                }
            }
            catch (Exception)
            {
                Process?.Dispose();
                throw;
            }
        }
 protected PeriodicRunner(TimeSpan period)
 {
     Period           = period;
     ExceptionTracker = new LastExceptionTracker();
 }