예제 #1
0
    public async Task InitializeAsync(CancellationToken cancel = default)
    {
        using (BenchmarkLogger.Measure())
        {
            using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
                using (await MatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                    using (await ImmatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                    {
                        await EnsureBackwardsCompatibilityAsync().ConfigureAwait(false);

                        if (Network == Network.RegTest)
                        {
                            MatureIndexFileManager.DeleteMe();             // RegTest is not a global ledger, better to delete it.
                            ImmatureIndexFileManager.DeleteMe();
                        }
                        cancel.ThrowIfCancellationRequested();

                        if (!MatureIndexFileManager.Exists())
                        {
                            await MatureIndexFileManager.WriteAllLinesAsync(new[] { StartingFilter.ToLine() }, CancellationToken.None).ConfigureAwait(false);
                        }
                        cancel.ThrowIfCancellationRequested();

                        await InitializeFiltersAsync(cancel).ConfigureAwait(false);
                    }
        }
    }
예제 #2
0
    /// <summary>
    /// It'll LogError the exceptions.
    /// If cancelled, it'll LogTrace the exception.
    /// </summary>
    private async Task TryCommitToFileAsync(TimeSpan throttle, CancellationToken cancel)
    {
        try
        {
            // If throttle is requested, then throttle.
            if (throttle != TimeSpan.Zero)
            {
                // Increment the throttle ID and remember the incremented value.
                int incremented = Interlocked.Increment(ref _throttleId);
                if (incremented < 21)
                {
                    await Task.Delay(throttle, cancel).ConfigureAwait(false);
                }

                // If the _throttleId is still the incremented value, then I am the latest CommitToFileAsync request.
                //	In this case I want to make the _throttledId 0 and go ahead and do the writeline.
                // If the _throttledId is not the incremented value anymore then I am not the latest request here,
                //	So just return, the latest request will do the file write in its own time.
                if (Interlocked.CompareExchange(ref _throttleId, 0, incremented) != incremented)
                {
                    return;
                }
            }
            else
            {
                Interlocked.Exchange(ref _throttleId, 0);                 // So to notify the currently throttled threads that they do not have to run.
            }

            using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
                using (await MatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                    using (await ImmatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                    {
                        // Do not feed the cancellationToken here I always want this to finish running for safety.
                        var currentImmatureLines = ImmatureFilters.Select(x => x.ToLine()).ToArray();         // So we do not read on ImmatureFilters while removing them.
                        var matureLinesToAppend  = currentImmatureLines.SkipLast(100);
                        var immatureLines        = currentImmatureLines.TakeLast(100);
                        var tasks = new Task[] { MatureIndexFileManager.AppendAllLinesAsync(matureLinesToAppend, CancellationToken.None), ImmatureIndexFileManager.WriteAllLinesAsync(immatureLines, CancellationToken.None) };
                        while (ImmatureFilters.Count > 100)
                        {
                            ImmatureFilters.RemoveFirst();
                        }
                        await Task.WhenAll(tasks).ConfigureAwait(false);
                    }
        }
        catch (Exception ex) when(ex is OperationCanceledException or TimeoutException)
        {
            Logger.LogTrace(ex);
        }
        catch (Exception ex)
        {
            Logger.LogError(ex);
        }
    }
예제 #3
0
 public async Task ForeachFiltersAsync(Func <FilterModel, Task> todo, Height fromHeight, CancellationToken cancel = default)
 {
     using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
         using (await MatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
         {
             var firstImmatureHeight = ImmatureFilters.FirstOrDefault()?.Header?.Height;
             if (!firstImmatureHeight.HasValue || firstImmatureHeight.Value > fromHeight)
             {
                 if (MatureIndexFileManager.Exists())
                 {
                     uint height = StartingHeight;
                     using var sr = MatureIndexFileManager.OpenText();
                     if (!sr.EndOfStream)
                     {
                         var    lineTask = sr.ReadLineAsync();
                         Task   tTask    = Task.CompletedTask;
                         string?line     = null;
                         while (lineTask is { })
예제 #4
0
    public async Task <IEnumerable <FilterModel> > RemoveAllImmmatureFiltersAsync(CancellationToken cancel, bool deleteAndCrashIfMature = false)
    {
        var removed = new List <FilterModel>();

        using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
        {
            if (ImmatureFilters.Any())
            {
                Logger.LogWarning($"Filters got corrupted. Reorging {ImmatureFilters.Count} immature filters in an attempt to fix them.");
            }
            else
            {
                Logger.LogCritical($"Filters got corrupted and have no more immature filters.");

                if (deleteAndCrashIfMature)
                {
                    Logger.LogCritical($"Deleting all filters and crashing the software...");

                    using (await MatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                        using (await ImmatureIndexAsyncLock.LockAsync(cancel).ConfigureAwait(false))
                        {
                            ImmatureIndexFileManager.DeleteMe();
                            MatureIndexFileManager.DeleteMe();
                        }

                    Environment.Exit(2);
                }
            }
        }

        while (ImmatureFilters.Any())
        {
            removed.Add(await RemoveLastFilterAsync(cancel).ConfigureAwait(false));
        }

        return(removed);
    }