private async Task Listen() { while (await _Channel.Reader.WaitToReadAsync()) { List <RefillPoolRequest> pendingRequests = new List <RefillPoolRequest>(); try { _Channel.Reader.TryRead(out var modelItem); if (modelItem == null) { continue; } retry: RefillPoolRequest nextItem = null; pendingRequests.Add(modelItem); // Try to batch several requests together while (_Channel.Reader.TryRead(out var item)) { if (modelItem.DerivationStrategy == item.DerivationStrategy && modelItem.Feature == item.Feature) { pendingRequests.Add(item); } else { nextItem = item; break; } } var query = new GenerateAddressQuery(); foreach (var i in pendingRequests.Where(o => o.MinAddresses is int).Select(o => o.MinAddresses.Value)) { if (query.MinAddresses is int min) { query.MinAddresses = min + i; } else { query.MinAddresses = new int?(i); } } if (query.MinAddresses is int) { query.MinAddresses = Math.Min(1000, query.MinAddresses.Value); } var c = await _Repository.GenerateAddresses(modelItem.DerivationStrategy, modelItem.Feature, query); pendingRequests.ForEach(i => i.Done?.TrySetResult(true)); if (nextItem != null) { modelItem = nextItem; pendingRequests.Clear(); goto retry; } } catch (Exception ex) { pendingRequests.ForEach(i => i.Done?.TrySetException(ex)); Logs.Explorer.LogError(ex, $"{_Repository.Network.CryptoCode}: Error in the Listen of the AddressPoolService"); await Task.Delay(1000); } } }
public Task GenerateAddresses(NBXplorerNetwork network, DerivationStrategyBase derivationStrategy, DerivationFeature feature, GenerateAddressQuery generateAddressQuery = null) { var completion = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); if (!_AddressPoolByNetwork[network]._Channel.Writer.TryWrite(new RefillPoolRequest() { DerivationStrategy = derivationStrategy, Feature = feature, Done = completion, GenerateAddressQuery = generateAddressQuery })) { completion.TrySetCanceled(); } return(completion.Task); }