public Task <SyncPeerAllocation> BorrowAsync(IPeerSelectionStrategy peerSelectionStrategy, string description = "", int timeoutMilliseconds = 0) { SyncPeerAllocation allocation = new SyncPeerAllocation(peerSelectionStrategy); allocation.AllocateBestPeer(UsefulPeers.Where(p => !p.IsAllocated), new NodeStatsManager(new StatsConfig(), LimboLogs.Instance), SyncPeerTree, description); return(Task.FromResult(allocation)); }
/// <summary> /// This is an important operation for long lasting allocations. /// For example the full sync tends to allocate the same peer for many minutes and we use this method to ensure that /// a newly arriving better peer can replace a currently selected one. /// Consider that there are some external changes (e.g. node stats values change based on the sync transfer rates) /// which may not be controlled from inside here, hence we decide to monitor the potential upgrades in a loop. /// </summary> /// <param name="reason">Reason for the method invocation for the diagnostics</param> /// <exception cref="InvalidOperationException">Thrown if an irreplaceable allocation is being replaced by this method (internal implementation error).</exception> private void UpgradeAllocations(string reason) { DropUselessPeers(); WakeUpPeerThatSleptEnough(reason); foreach ((SyncPeerAllocation allocation, _) in _replaceableAllocations) { lock (_isAllocatedChecks) { var unallocatedPeers = UsefulPeers.Where(p => !p.IsAllocated); allocation.AllocateBestPeer(unallocatedPeers, _stats, _blockTree, reason); } } }
public async Task <SyncPeerAllocation> BorrowAsync(IPeerSelectionStrategy peerSelectionStrategy, string description = "", int timeoutMilliseconds = 0) { int tryCount = 1; DateTime startTime = DateTime.UtcNow; SyncPeerAllocation allocation = new SyncPeerAllocation(peerSelectionStrategy); while (true) { lock (_isAllocatedChecks) { allocation.AllocateBestPeer(UsefulPeers.Where(p => !p.IsAllocated), _stats, _blockTree, "INIT"); if (allocation.HasPeer) { if (peerSelectionStrategy.CanBeReplaced) { _replaceableAllocations.TryAdd(allocation, null); } return(allocation); } } bool timeoutReached = timeoutMilliseconds == 0 || (DateTime.UtcNow - startTime).TotalMilliseconds > timeoutMilliseconds; if (timeoutReached) { return(SyncPeerAllocation.FailedAllocation); } int waitTime = 10 * tryCount++; await _signals.WaitOneAsync(waitTime, CancellationToken.None); _signals.Reset(); // without this we have no delay } }