Пример #1
0
        public async Task StartAsync(CancellationToken cancel)
        {
            var ptcv = PrintToConsole ? 1 : 0;

            using var process = Start($"{NetworkTranslator.GetCommandLineArguments(Network)} -datadir=\"{DataDir}\" -printtoconsole={ptcv}", false);

            await PidFile.WriteFileAsync(process.Id).ConfigureAwait(false);

            CachedPid = process.Id;

            string latestFailureMessage = null;

            while (true)
            {
                var ex = await RpcClient.TestAsync().ConfigureAwait(false);

                if (ex is null)
                {
                    Logger.LogInfo($"RPC connection is successfully established.");
                    break;
                }
                else if (latestFailureMessage != ex.Message)
                {
                    latestFailureMessage = ex.Message;
                    Logger.LogInfo($"{Constants.BuiltinBitcoinNodeName} is not yet ready... Reason: {latestFailureMessage}");
                }

                if (process is null || process.HasExited)
                {
                    throw new BitcoindException($"Failed to start daemon, location: '{process?.StartInfo.FileName} {process?.StartInfo.Arguments}'", ex);
                }

                if (cancel.IsCancellationRequested)
                {
                    await StopAsync(true).ConfigureAwait(false);

                    cancel.ThrowIfCancellationRequested();
                }

                await Task.Delay(100).ConfigureAwait(false);                 // So to leave some breathing room before the next check.
            }
        }
Пример #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;
            }
        }