github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/mempool/chunk_requests.go (about) 1 package mempool 2 3 import ( 4 "time" 5 6 "github.com/onflow/flow-go/model/chunks" 7 "github.com/onflow/flow-go/model/flow" 8 "github.com/onflow/flow-go/model/verification" 9 ) 10 11 // ChunkRequestHistoryUpdaterFunc is a function type that used by ChunkRequests mempool to perform atomic and isolated updates on the 12 // underlying chunk requests history. 13 type ChunkRequestHistoryUpdaterFunc func(uint64, time.Duration) (uint64, time.Duration, bool) 14 15 // ExponentialUpdater is a chunk request history updater factory that updates the retryAfter value of a request to 16 // multiplier * retryAfter. For example, if multiplier = 2, 17 // then invoking it n times results in a retryAfter value of 2^n * retryAfter, which follows an exponential series. 18 // 19 // It also keeps updated retryAfter value between the minInterval and maxInterval inclusive. It means that if updated retryAfter value 20 // is below minInterval, it is bumped up to the minInterval. Also, if updated retryAfter value is above maxInterval, it is skimmed off back 21 // to the maxInterval. 22 // 23 // Note: if initial retryAfter is below minInterval, the first call to this function returns minInterval, and hence after the nth invocations, 24 // the retryAfter value is set to 2^(n-1) * minInterval. 25 func ExponentialUpdater(multiplier float64, maxInterval time.Duration, minInterval time.Duration) ChunkRequestHistoryUpdaterFunc { 26 return func(attempts uint64, retryAfter time.Duration) (uint64, time.Duration, bool) { 27 if float64(retryAfter) >= float64(maxInterval)/multiplier { 28 retryAfter = maxInterval 29 } else { 30 retryAfter = time.Duration(float64(retryAfter) * multiplier) 31 32 if retryAfter < minInterval { 33 retryAfter = minInterval 34 } 35 } 36 37 return attempts + 1, retryAfter, true 38 } 39 } 40 41 // IncrementalAttemptUpdater is a chunk request history updater factory that increments the attempt field of request status 42 // and makes it instantly available against any retryAfter qualifier. 43 func IncrementalAttemptUpdater() ChunkRequestHistoryUpdaterFunc { 44 return func(attempts uint64, _ time.Duration) (uint64, time.Duration, bool) { 45 attempts++ 46 // makes request instantly qualified against any retry after qualifier. 47 return attempts, time.Nanosecond, true 48 } 49 } 50 51 // ChunkRequests is an in-memory storage for maintaining chunk data pack requests. 52 type ChunkRequests interface { 53 // RequestHistory returns the number of times the chunk has been requested, 54 // last time the chunk has been requested, and the retryAfter duration of the 55 // underlying request status of this chunk. 56 // 57 // The last boolean parameter returns whether a chunk request for this chunk ID 58 // exists in memory-pool. 59 RequestHistory(chunkID flow.Identifier) (uint64, time.Time, time.Duration, bool) 60 61 // Add provides insertion functionality into the memory pool. 62 // The insertion is only successful if there is no duplicate chunk request with the same 63 // chunk ID in the memory. Otherwise, it aborts the insertion and returns false. 64 Add(request *verification.ChunkDataPackRequest) bool 65 66 // Remove provides deletion functionality from the memory pool. 67 // If there is a chunk request with this ID, Remove removes it and returns true. 68 // Otherwise, it returns false. 69 Remove(chunkID flow.Identifier) bool 70 71 // PopAll atomically returns all locators associated with this chunk ID while clearing out the 72 // chunk request status for this chunk id. 73 // Boolean return value indicates whether there are requests in the memory pool associated 74 // with chunk ID. 75 PopAll(chunkID flow.Identifier) (chunks.LocatorMap, bool) 76 77 // IncrementAttempt increments the Attempt field of the corresponding status of the 78 // chunk request in memory pool that has the specified chunk ID. 79 // If such chunk ID does not exist in the memory pool, it returns false. 80 // 81 // The increments are done atomically, thread-safe, and in isolation. 82 IncrementAttempt(chunkID flow.Identifier) bool 83 84 // UpdateRequestHistory updates the request history of the specified chunk ID. If the update was successful, i.e., 85 // the updater returns true, the result of update is committed to the mempool, and the time stamp of the chunk request 86 // is updated to the current time. Otherwise, it aborts and returns false. 87 // 88 // It returns the updated request history values. 89 // 90 // The updates under this method are atomic, thread-safe, and done in isolation. 91 UpdateRequestHistory(chunkID flow.Identifier, updater ChunkRequestHistoryUpdaterFunc) (uint64, time.Time, time.Duration, bool) 92 93 // All returns all chunk requests stored in this memory pool. 94 All() verification.ChunkDataPackRequestInfoList 95 96 // Size returns total number of chunk requests in the memory pool. 97 Size() uint 98 } 99 100 const DefaultChunkDataPackRequestQueueSize = 100_000 101 102 // ChunkDataPackRequest is an internal data type for Execution Nodes that 103 // represents a request for a chunk data pack. 104 type ChunkDataPackRequest struct { 105 // Identifier of the chunk. 106 ChunkId flow.Identifier 107 // Identifier of the requester node. 108 RequesterId flow.Identifier 109 }