-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Response Assembler Refactor #138
Merged
Merged
Changes from 4 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
aa9a751
WIP
hannahhoward a20bb4c
WIP
hannahhoward c09f293
network tests passing
87a0d72
fix peermanager test
309dff5
requestmanager passes
549e63e
responsemanager test passing
650edf5
peerresponsebuilder test passing
f9b28aa
network and messagequeue tests are passing
e53444e
fix imports
56cd40a
refactor(responsemanager): test cleanup
hannahhoward 2755185
refactor(graphsync): add more code documentation
hannahhoward 43557bf
refactor(responsemanager): finish rename cleanup
hannahhoward 967e538
fix(messagequeue): don't miss queued messages
hannahhoward 2b30ce0
Apply suggestions from code review
hannahhoward ab4f23f
refactor(responseassembler): rename transaction builder
hannahhoward File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,3 +1,10 @@ | ||||||
/* | ||||||
Package responseassembler assembles responses that are queued for sending in outgoing messages | ||||||
|
||||||
The response assembler's Transaction method allows a caller to specify response actions that will go into a single | ||||||
libp2p2 message. The response assembler will also deduplicate blocks that have already been sent over the network in | ||||||
a previous message | ||||||
*/ | ||||||
package responseassembler | ||||||
|
||||||
import ( | ||||||
|
@@ -13,10 +20,11 @@ import ( | |||||
) | ||||||
|
||||||
// Transaction is a series of operations that should be send together in a single response | ||||||
type Transaction func(PeerResponseTransactionBuilder) error | ||||||
type Transaction func(TransactionBuilder) error | ||||||
|
||||||
// PeerResponseTransactionBuilder is a limited interface for sending responses inside a transaction | ||||||
type PeerResponseTransactionBuilder interface { | ||||||
// TransactionBuilder is a limited interface for assembling responses inside a transaction, so that they are included | ||||||
// in the same message on the protocol | ||||||
type TransactionBuilder interface { | ||||||
SendResponse( | ||||||
link ipld.Link, | ||||||
data []byte, | ||||||
|
@@ -29,8 +37,7 @@ type PeerResponseTransactionBuilder interface { | |||||
AddNotifee(notifications.Notifee) | ||||||
} | ||||||
|
||||||
// PeerMessageHandler is an interface that can send a response for a given peer across | ||||||
// the network. | ||||||
// PeerMessageHandler is an interface that can queues a response for a given peer to go out over the network | ||||||
type PeerMessageHandler interface { | ||||||
BuildMessage(p peer.ID, blkSize uint64, buildResponseFn func(*gsmsg.Builder), notifees []notifications.Notifee) | ||||||
} | ||||||
|
@@ -40,15 +47,16 @@ type Allocator interface { | |||||
AllocateBlockMemory(p peer.ID, amount uint64) <-chan error | ||||||
} | ||||||
|
||||||
// ResponseAssembler manages message queues for peers | ||||||
// ResponseAssembler manages assembling responses to go out over the network | ||||||
// in libp2p messages | ||||||
type ResponseAssembler struct { | ||||||
*peermanager.PeerManager | ||||||
allocator Allocator | ||||||
peerHandler PeerMessageHandler | ||||||
ctx context.Context | ||||||
} | ||||||
|
||||||
// New generates a new peer manager for sending responses | ||||||
// New generates a new ResponseAssembler for sending responses | ||||||
func New(ctx context.Context, allocator Allocator, peerHandler PeerMessageHandler) *ResponseAssembler { | ||||||
return &ResponseAssembler{ | ||||||
PeerManager: peermanager.New(ctx, func(ctx context.Context, p peer.ID) peermanager.PeerHandler { | ||||||
|
@@ -60,40 +68,43 @@ func New(ctx context.Context, allocator Allocator, peerHandler PeerMessageHandle | |||||
} | ||||||
} | ||||||
|
||||||
func (prm *ResponseAssembler) DedupKey(p peer.ID, requestID graphsync.RequestID, key string) { | ||||||
prm.GetProcess(p).(*peerLinkTracker).DedupKey(requestID, key) | ||||||
// DedupKey indicates that outgoing blocks should be deduplicated in a seperate bucket (only with requests that share | ||||||
// supplied key string) | ||||||
func (ra *ResponseAssembler) DedupKey(p peer.ID, requestID graphsync.RequestID, key string) { | ||||||
ra.GetProcess(p).(*peerLinkTracker).DedupKey(requestID, key) | ||||||
} | ||||||
|
||||||
func (prm *ResponseAssembler) IgnoreBlocks(p peer.ID, requestID graphsync.RequestID, links []ipld.Link) { | ||||||
prm.GetProcess(p).(*peerLinkTracker).IgnoreBlocks(requestID, links) | ||||||
// IgnoreBlocks indicates that a list of keys that should be ignored when sending blocks | ||||||
func (ra *ResponseAssembler) IgnoreBlocks(p peer.ID, requestID graphsync.RequestID, links []ipld.Link) { | ||||||
ra.GetProcess(p).(*peerLinkTracker).IgnoreBlocks(requestID, links) | ||||||
} | ||||||
|
||||||
// Transaction Build A Response | ||||||
func (prm *ResponseAssembler) Transaction(p peer.ID, requestID graphsync.RequestID, transaction Transaction) error { | ||||||
// Transaction build a response, and queues it for sending in the next outgoing message | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
func (ra *ResponseAssembler) Transaction(p peer.ID, requestID graphsync.RequestID, transaction Transaction) error { | ||||||
prts := &transactionBuilder{ | ||||||
requestID: requestID, | ||||||
linkTracker: prm.GetProcess(p).(*peerLinkTracker), | ||||||
linkTracker: ra.GetProcess(p).(*peerLinkTracker), | ||||||
} | ||||||
err := transaction(prts) | ||||||
if err == nil { | ||||||
prm.execute(p, prts.operations, prts.notifees) | ||||||
ra.execute(p, prts.operations, prts.notifees) | ||||||
} | ||||||
return err | ||||||
} | ||||||
|
||||||
func (prs *ResponseAssembler) execute(p peer.ID, operations []responseOperation, notifees []notifications.Notifee) { | ||||||
func (ra *ResponseAssembler) execute(p peer.ID, operations []responseOperation, notifees []notifications.Notifee) { | ||||||
size := uint64(0) | ||||||
for _, op := range operations { | ||||||
size += op.size() | ||||||
} | ||||||
if size > 0 { | ||||||
select { | ||||||
case <-prs.allocator.AllocateBlockMemory(p, size): | ||||||
case <-prs.ctx.Done(): | ||||||
case <-ra.allocator.AllocateBlockMemory(p, size): | ||||||
case <-ra.ctx.Done(): | ||||||
return | ||||||
} | ||||||
} | ||||||
prs.peerHandler.BuildMessage(p, size, func(responseBuilder *gsmsg.Builder) { | ||||||
ra.peerHandler.BuildMessage(p, size, func(responseBuilder *gsmsg.Builder) { | ||||||
for _, op := range operations { | ||||||
op.build(responseBuilder) | ||||||
} | ||||||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like
ResponseBuilder
orMessageBuilder
more for this. I can see how this 'adds' to a transaction, but the name suggests it 'builds' a transaction in the sense that a message builder builds a message, but it doesn't really. I can also seeTransactionContext
,TransactionMutator
orTransactionAPI
as this represents the limited set of message building functionality available within a transaction.