Skip to content

Commit b0bd16e

Browse files
authored
fix(requestmanager): remove main thread block on allocation (#216)
remote allocation from main requestmanager thread -- this could block processing of other operations like request cancels
1 parent 2687228 commit b0bd16e

File tree

5 files changed

+26
-31
lines changed

5 files changed

+26
-31
lines changed

impl/graphsync.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ type GraphSync struct {
5858
persistenceOptions *persistenceoptions.PersistenceOptions
5959
ctx context.Context
6060
cancel context.CancelFunc
61-
allocator *allocator.Allocator
61+
responseAllocator *allocator.Allocator
62+
requestAllocator *allocator.Allocator
6263
}
6364

6465
type graphsyncConfigOptions struct {
@@ -191,7 +192,8 @@ func New(parent context.Context, network gsnet.GraphSyncNetwork,
191192
persistenceOptions: persistenceOptions,
192193
ctx: ctx,
193194
cancel: cancel,
194-
allocator: responseAllocator,
195+
responseAllocator: responseAllocator,
196+
requestAllocator: requestAllocator,
195197
}
196198

197199
asyncLoader.Startup()
@@ -334,6 +336,14 @@ func (gsr *graphSyncReceiver) ReceiveMessage(
334336
sender peer.ID,
335337
incoming gsmsg.GraphSyncMessage) {
336338
gsr.graphSync().responseManager.ProcessRequests(ctx, sender, incoming.Requests())
339+
totalMemoryAllocated := uint64(0)
340+
for _, blk := range incoming.Blocks() {
341+
totalMemoryAllocated += uint64(len(blk.RawData()))
342+
}
343+
select {
344+
case <-gsr.graphSync().responseAllocator.AllocateBlockMemory(sender, totalMemoryAllocated):
345+
case <-gsr.ctx.Done():
346+
}
337347
gsr.graphSync().requestManager.ProcessResponses(sender, incoming.Responses(), incoming.Blocks())
338348
}
339349

requestmanager/asyncloader/asyncloader.go

+1-10
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ type alternateQueue struct {
3131

3232
// Allocator indicates a mechanism for tracking memory used by a given peer
3333
type Allocator interface {
34-
AllocateBlockMemory(p peer.ID, amount uint64) <-chan error
3534
ReleaseBlockMemory(p peer.ID, amount uint64) error
3635
}
3736

@@ -113,16 +112,8 @@ func (al *AsyncLoader) StartRequest(requestID graphsync.RequestID, persistenceOp
113112

114113
// ProcessResponse injests new responses and completes asynchronous loads as
115114
// neccesary
116-
func (al *AsyncLoader) ProcessResponse(p peer.ID, responses map[graphsync.RequestID]metadata.Metadata,
115+
func (al *AsyncLoader) ProcessResponse(responses map[graphsync.RequestID]metadata.Metadata,
117116
blks []blocks.Block) {
118-
totalMemoryAllocated := uint64(0)
119-
for _, blk := range blks {
120-
totalMemoryAllocated += uint64(len(blk.RawData()))
121-
}
122-
select {
123-
case <-al.allocator.AllocateBlockMemory(p, totalMemoryAllocated):
124-
case <-al.ctx.Done():
125-
}
126117
select {
127118
case <-al.ctx.Done():
128119
case al.incomingMessages <- &newResponsesAvailableMessage{responses, blks}:

requestmanager/asyncloader/asyncloader_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestAsyncLoadInitialLoadSucceedsResponsePresent(t *testing.T) {
4949
},
5050
}
5151
p := testutil.GeneratePeers(1)[0]
52-
asyncLoader.ProcessResponse(p, responses, blocks)
52+
asyncLoader.ProcessResponse(responses, blocks)
5353
resultChan := asyncLoader.AsyncLoad(p, requestID, link, ipld.LinkContext{})
5454

5555
assertSuccessResponse(ctx, t, resultChan)
@@ -73,7 +73,7 @@ func TestAsyncLoadInitialLoadFails(t *testing.T) {
7373
},
7474
}
7575
p := testutil.GeneratePeers(1)[0]
76-
asyncLoader.ProcessResponse(p, responses, nil)
76+
asyncLoader.ProcessResponse(responses, nil)
7777

7878
resultChan := asyncLoader.AsyncLoad(p, requestID, link, ipld.LinkContext{})
7979
assertFailResponse(ctx, t, resultChan)
@@ -117,7 +117,7 @@ func TestAsyncLoadInitialLoadIndeterminateThenSucceeds(t *testing.T) {
117117
},
118118
},
119119
}
120-
asyncLoader.ProcessResponse(p, responses, blocks)
120+
asyncLoader.ProcessResponse(responses, blocks)
121121
assertSuccessResponse(ctx, t, resultChan)
122122
st.AssertLocalLoads(t, 1)
123123
st.AssertBlockStored(t, block)
@@ -145,7 +145,7 @@ func TestAsyncLoadInitialLoadIndeterminateThenFails(t *testing.T) {
145145
},
146146
},
147147
}
148-
asyncLoader.ProcessResponse(p, responses, nil)
148+
asyncLoader.ProcessResponse(responses, nil)
149149
assertFailResponse(ctx, t, resultChan)
150150
st.AssertLocalLoads(t, 1)
151151
})
@@ -183,7 +183,7 @@ func TestAsyncLoadTwiceLoadsLocallySecondTime(t *testing.T) {
183183
},
184184
}
185185
p := testutil.GeneratePeers(1)[0]
186-
asyncLoader.ProcessResponse(p, responses, blocks)
186+
asyncLoader.ProcessResponse(responses, blocks)
187187
resultChan := asyncLoader.AsyncLoad(p, requestID, link, ipld.LinkContext{})
188188

189189
assertSuccessResponse(ctx, t, resultChan)
@@ -283,7 +283,7 @@ func TestRequestSplittingSameBlockTwoStores(t *testing.T) {
283283
},
284284
},
285285
}
286-
asyncLoader.ProcessResponse(p, responses, blocks)
286+
asyncLoader.ProcessResponse(responses, blocks)
287287

288288
assertSuccessResponse(ctx, t, resultChan1)
289289
assertSuccessResponse(ctx, t, resultChan2)
@@ -318,7 +318,7 @@ func TestRequestSplittingSameBlockOnlyOneResponse(t *testing.T) {
318318
},
319319
},
320320
}
321-
asyncLoader.ProcessResponse(p, responses, blocks)
321+
asyncLoader.ProcessResponse(responses, blocks)
322322
asyncLoader.CompleteResponsesFor(requestID1)
323323

324324
assertFailResponse(ctx, t, resultChan1)

requestmanager/requestmanager.go

+5-11
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type PeerHandler interface {
5959
// results as new responses are processed
6060
type AsyncLoader interface {
6161
StartRequest(graphsync.RequestID, string) error
62-
ProcessResponse(p peer.ID, responses map[graphsync.RequestID]metadata.Metadata,
62+
ProcessResponse(responses map[graphsync.RequestID]metadata.Metadata,
6363
blks []blocks.Block)
6464
AsyncLoad(p peer.ID, requestID graphsync.RequestID, link ipld.Link, linkContext ipld.LinkContext) <-chan types.AsyncLoadResult
6565
CompleteResponsesFor(requestID graphsync.RequestID)
@@ -278,17 +278,15 @@ type processResponseMessage struct {
278278
p peer.ID
279279
responses []gsmsg.GraphSyncResponse
280280
blks []blocks.Block
281-
response chan error
282281
}
283282

284283
// ProcessResponses ingests the given responses from the network and
285284
// and updates the in progress requests based on those responses.
286285
func (rm *RequestManager) ProcessResponses(p peer.ID, responses []gsmsg.GraphSyncResponse,
287286
blks []blocks.Block) {
288-
response := make(chan error, 1)
289-
err := rm.sendSyncMessage(&processResponseMessage{p, responses, blks, response}, response, nil)
290-
if err != nil {
291-
log.Warnf("ProcessResponses: %s", err)
287+
select {
288+
case rm.messages <- &processResponseMessage{p, responses, blks}:
289+
case <-rm.ctx.Done():
292290
}
293291
}
294292

@@ -485,12 +483,8 @@ func (prm *processResponseMessage) handle(rm *RequestManager) {
485483
filteredResponses = rm.filterResponsesForPeer(filteredResponses, prm.p)
486484
rm.updateLastResponses(filteredResponses)
487485
responseMetadata := metadataForResponses(filteredResponses)
488-
rm.asyncLoader.ProcessResponse(prm.p, responseMetadata, prm.blks)
486+
rm.asyncLoader.ProcessResponse(responseMetadata, prm.blks)
489487
rm.processTerminations(filteredResponses)
490-
select {
491-
case <-rm.ctx.Done():
492-
case prm.response <- nil:
493-
}
494488
}
495489

496490
func (rm *RequestManager) filterResponsesForPeer(responses []gsmsg.GraphSyncResponse, p peer.ID) []gsmsg.GraphSyncResponse {

requestmanager/testloader/asyncloader.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (fal *FakeAsyncLoader) StartRequest(requestID graphsync.RequestID, name str
6161
}
6262

6363
// ProcessResponse just records values passed to verify expectations later
64-
func (fal *FakeAsyncLoader) ProcessResponse(p peer.ID, responses map[graphsync.RequestID]metadata.Metadata,
64+
func (fal *FakeAsyncLoader) ProcessResponse(responses map[graphsync.RequestID]metadata.Metadata,
6565
blks []blocks.Block) {
6666
fal.responses <- responses
6767
fal.blks <- blks

0 commit comments

Comments
 (0)