예제 #1
0
    public async Task AddNewFiltersAsync(IEnumerable <FilterModel> filters, CancellationToken cancel)
    {
        var successAny = false;

        foreach (var filter in filters)
        {
            var success = false;

            using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
            {
                success = TryProcessFilter(filter, enqueue: true);
            }
            successAny = successAny || success;

            if (success)
            {
                NewFilter?.Invoke(this, filter);                 // Event always outside the lock.
            }
        }

        if (successAny)
        {
            AbandonedTasks.AddAndClearCompleted(TryCommitToFileAsync(TimeSpan.FromSeconds(3), cancel));
        }
    }
예제 #2
0
        public async Task AddNewFiltersAsync(IEnumerable <FilterModel> filters, CancellationToken cancel)
        {
            foreach (var filter in filters)
            {
                using (await IndexLock.LockAsync())
                {
                    ProcessFilter(filter, enqueue: true);
                }

                NewFilter?.Invoke(this, filter);                 // Event always outside the lock.
            }

            _ = TryCommitToFileAsync(TimeSpan.FromSeconds(3), cancel);
        }
예제 #3
0
 private void OnNewFilter(FilterModel filter) => NewFilter?.Invoke(this, filter);
예제 #4
0
        public void Synchronize(TimeSpan requestInterval)
        {
            Guard.NotNull(nameof(requestInterval), requestInterval);
            Interlocked.Exchange(ref _running, 1);

            Task.Run(async() =>
            {
                FilterModel bestKnownFilter = null;

                try
                {
                    while (IsRunning)
                    {
                        try
                        {
                            // If stop was requested return.
                            if (IsRunning == false)
                            {
                                return;
                            }

                            using (await IndexLock.LockAsync())
                            {
                                bestKnownFilter = Index.Last();
                            }

                            var filters = await WasabiClient.GetFiltersAsync(bestKnownFilter.BlockHash, 1000);

                            if (!filters.Any())
                            {
                                continue;
                            }
                            using (await IndexLock.LockAsync())
                            {
                                var filtersList = filters.ToList();                                 // performance
                                for (int i = 0; i < filtersList.Count; i++)
                                {
                                    var filterModel = FilterModel.FromLine(filtersList[i], bestKnownFilter.BlockHeight + i + 1);

                                    Index.Add(filterModel);
                                    NewFilter?.Invoke(this, filterModel);
                                }

                                if (filtersList.Count == 1)                                 // minor optimization
                                {
                                    await File.AppendAllLinesAsync(IndexFilePath, new[] { Index.Last().ToLine() });
                                }
                                else
                                {
                                    await File.WriteAllLinesAsync(IndexFilePath, Index.Select(x => x.ToLine()));
                                }

                                Logger.LogInfo <IndexDownloader>($"Downloaded filters for blocks from {bestKnownFilter.BlockHeight.Value + 1} to {Index.Last().BlockHeight}.");
                            }

                            continue;
                        }
                        catch (HttpRequestException ex) when(ex.Message.StartsWith(HttpStatusCode.NotFound.ToReasonString()))
                        {
                            // Reorg happened
                            var reorgedHash = bestKnownFilter.BlockHash;
                            Logger.LogInfo <IndexDownloader>($"REORG Invalid Block: {reorgedHash}");
                            // 1. Rollback index
                            using (await IndexLock.LockAsync())
                            {
                                Index.RemoveAt(Index.Count - 1);
                            }

                            Reorged?.Invoke(this, reorgedHash);

                            // 2. Serialize Index. (Remove last line.)
                            var lines = File.ReadAllLines(IndexFilePath);
                            File.WriteAllLines(IndexFilePath, lines.Take(lines.Length - 1).ToArray());

                            // 3. Skip the last valid block.
                            continue;
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError <IndexDownloader>(ex);
                        }
                        finally
                        {
                            await Task.Delay(requestInterval);                             // Ask for new index in every requestInterval.
                        }
                    }
                }
                finally
                {
                    if (IsStopping)
                    {
                        Interlocked.Exchange(ref _running, 3);
                    }
                }
            });
        }
        public static void Main(string[] args)
        {
            #region Single responsibility
            var j = new Journal();
            j.AddEntry("hi");
            j.AddEntry("hello world");
            Console.WriteLine(j);
            //Console.ReadKey();
            var    p        = new Persistance();
            string fileName = @"C:\LOG\test.txt";
            p.SaveFile(j, fileName, true);
            Process.Start(fileName);
            #endregion

            #region Open-closed principle
            var apple = new Product("Apple", Color.Green, Size.Small);
            var tree  = new Product("Tree", Color.Green, Size.Large);
            var house = new Product("House", Color.Blue, Size.Large);

            Product[] products = { apple, tree, house };
            var       nf       = new NewFilter();
            Console.WriteLine("Green products");
            var result1 = nf.Filter(products, new ColorSpecification(Color.Green));
            foreach (var i in result1)
            {
                Console.WriteLine($" - {i.Name} is green");
            }
            Console.WriteLine("Large products");
            var result2 = nf.Filter(products, new SizeSpecification(Size.Large));
            foreach (var i in result2)
            {
                Console.WriteLine($" - {i.Name} is large");
            }
            Console.WriteLine("Blue and Large products");
            var result3 = nf.Filter(products,
                                    new AndSpecification <Product>
                                        (new ColorSpecification(Color.Blue),
                                        new SizeSpecification(Size.Large)
                                        )
                                    );
            foreach (var i in result3)
            {
                Console.WriteLine($" - {i.Name} is large and blue");
            }
            Console.ReadKey();
            #endregion
            #region liskov principle
            Rectangle rec = new Rectangle(4, 3);
            var       d   = new Demo();
            Console.WriteLine($"the area of the rectangle {rec} is {d.Area(rec)}");
            Rectangle sq = new Square();
            sq.Width = 5;
            Console.WriteLine($"the area of the square {sq} is {d.Area(sq)}");
            Console.ReadKey();
            #endregion

            #region DI principle
            var parent = new Person("John");
            var child1 = new Person("Matt");
            var child2 = new Person("Test");

            Relationships rel = new Relationships();
            rel.AddParentAndChild(parent, child1);
            rel.AddParentAndChild(parent, child2);
            Research rs = new Research(rel);
            Console.ReadKey();
            #endregion
        }
예제 #6
0
        public void Synchronize(TimeSpan requestInterval)
        {
            Guard.NotNull(nameof(requestInterval), requestInterval);
            Interlocked.Exchange(ref _running, 1);

            Task.Run(async() =>
            {
                try
                {
                    while (IsRunning)
                    {
                        try
                        {
                            // If stop was requested return.
                            if (IsRunning == false)
                            {
                                return;
                            }

                            FilterModel bestKnownFilter;
                            using (await IndexLock.LockAsync())
                            {
                                bestKnownFilter = Index.Last();
                            }

                            var response = await Client.SendAsync(HttpMethod.Get, $"/api/v1/btc/blockchain/filters?bestKnownBlockHash={bestKnownFilter.BlockHash}&count=1000");

                            if (response.StatusCode == HttpStatusCode.NoContent)
                            {
                                continue;
                            }
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                var filters = await response.Content.ReadAsJsonAsync <List <string> >();
                                using (await IndexLock.LockAsync())
                                {
                                    for (int i = 0; i < filters.Count; i++)
                                    {
                                        var filterModel = FilterModel.FromLine(filters[i], bestKnownFilter.BlockHeight + i + 1);

                                        Index.Add(filterModel);
                                        NewFilter?.Invoke(this, filterModel);
                                    }

                                    if (filters.Count == 1)                                     // minor optimization
                                    {
                                        await File.AppendAllLinesAsync(IndexFilePath, new[] { Index.Last().ToLine() });
                                    }
                                    else
                                    {
                                        await File.WriteAllLinesAsync(IndexFilePath, Index.Select(x => x.ToLine()));
                                    }

                                    Logger.LogInfo <IndexDownloader>($"Downloaded filters for blocks from {bestKnownFilter.BlockHeight.Value + 1} to {Index.Last().BlockHeight}.");
                                }

                                continue;
                            }
                            else if (response.StatusCode == HttpStatusCode.NotFound)
                            {
                                // Reorg happened
                                var reorgedHash = bestKnownFilter.BlockHash;
                                Logger.LogInfo <IndexDownloader>($"REORG Invalid Block: {reorgedHash}");
                                // 1. Rollback index
                                using (await IndexLock.LockAsync())
                                {
                                    Index.RemoveAt(Index.Count - 1);
                                }

                                Reorged?.Invoke(this, reorgedHash);

                                // 2. Serialize Index. (Remove last line.)
                                var lines = File.ReadAllLines(IndexFilePath);
                                File.WriteAllLines(IndexFilePath, lines.Take(lines.Length - 1).ToArray());

                                // 3. Skip the last valid block.
                                continue;
                            }
                            else
                            {
                                var error = await response.Content.ReadAsStringAsync();
                                throw new HttpRequestException($"{response.StatusCode.ToReasonString()}: {error}");
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError <IndexDownloader>(ex);
                        }
                        finally
                        {
                            await Task.Delay(requestInterval);                             // Ask for new index in every requestInterval.
                        }
                    }
                }
                finally
                {
                    if (IsStopping)
                    {
                        Interlocked.Exchange(ref _running, 3);
                    }
                }
            });
        }