swarm/network/stream: disambiguate chunk delivery messages (retrieval… (#17920)

* swarm/network/stream: disambiguate chunk delivery messages (retrieval vs syncing)

* swarm/network/stream: addressed PR comments

* swarm/network/stream: stream protocol version change due to new message types in this PR
This commit is contained in:
holisticode 2018-10-21 02:30:41 -05:00 committed by Viktor Trón
parent 66debd91d9
commit 88b41a9e68
4 changed files with 47 additions and 12 deletions

View File

@ -173,7 +173,8 @@ func (d *Delivery) handleRetrieveRequestMsg(ctx context.Context, sp *Peer, req *
return return
} }
if req.SkipCheck { if req.SkipCheck {
err = sp.Deliver(ctx, chunk, s.priority) syncing := false
err = sp.Deliver(ctx, chunk, s.priority, syncing)
if err != nil { if err != nil {
log.Warn("ERROR in handleRetrieveRequestMsg", "err", err) log.Warn("ERROR in handleRetrieveRequestMsg", "err", err)
} }
@ -189,12 +190,22 @@ func (d *Delivery) handleRetrieveRequestMsg(ctx context.Context, sp *Peer, req *
return nil return nil
} }
//Chunk delivery always uses the same message type....
type ChunkDeliveryMsg struct { type ChunkDeliveryMsg struct {
Addr storage.Address Addr storage.Address
SData []byte // the stored chunk Data (incl size) SData []byte // the stored chunk Data (incl size)
peer *Peer // set in handleChunkDeliveryMsg peer *Peer // set in handleChunkDeliveryMsg
} }
//...but swap accounting needs to disambiguate if it is a delivery for syncing or for retrieval
//as it decides based on message type if it needs to account for this message or not
//defines a chunk delivery for retrieval (with accounting)
type ChunkDeliveryMsgRetrieval ChunkDeliveryMsg
//defines a chunk delivery for syncing (without accounting)
type ChunkDeliveryMsgSyncing ChunkDeliveryMsg
// TODO: Fix context SNAFU // TODO: Fix context SNAFU
func (d *Delivery) handleChunkDeliveryMsg(ctx context.Context, sp *Peer, req *ChunkDeliveryMsg) error { func (d *Delivery) handleChunkDeliveryMsg(ctx context.Context, sp *Peer, req *ChunkDeliveryMsg) error {
var osp opentracing.Span var osp opentracing.Span

View File

@ -357,7 +357,8 @@ func (p *Peer) handleWantedHashesMsg(ctx context.Context, req *WantedHashesMsg)
return fmt.Errorf("handleWantedHashesMsg get data %x: %v", hash, err) return fmt.Errorf("handleWantedHashesMsg get data %x: %v", hash, err)
} }
chunk := storage.NewChunk(hash, data) chunk := storage.NewChunk(hash, data)
if err := p.Deliver(ctx, chunk, s.priority); err != nil { syncing := true
if err := p.Deliver(ctx, chunk, s.priority, syncing); err != nil {
return err return err
} }
} }

View File

@ -128,17 +128,34 @@ func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer {
} }
// Deliver sends a storeRequestMsg protocol message to the peer // Deliver sends a storeRequestMsg protocol message to the peer
func (p *Peer) Deliver(ctx context.Context, chunk storage.Chunk, priority uint8) error { // Depending on the `syncing` parameter we send different message types
func (p *Peer) Deliver(ctx context.Context, chunk storage.Chunk, priority uint8, syncing bool) error {
var sp opentracing.Span var sp opentracing.Span
ctx, sp = spancontext.StartSpan( var msg interface{}
ctx,
"send.chunk.delivery")
defer sp.Finish()
msg := &ChunkDeliveryMsg{ spanName := "send.chunk.delivery"
//we send different types of messages if delivery is for syncing or retrievals,
//even if handling and content of the message are the same,
//because swap accounting decides which messages need accounting based on the message type
if syncing {
msg = &ChunkDeliveryMsgSyncing{
Addr: chunk.Address(), Addr: chunk.Address(),
SData: chunk.Data(), SData: chunk.Data(),
} }
spanName += ".syncing"
} else {
msg = &ChunkDeliveryMsgRetrieval{
Addr: chunk.Address(),
SData: chunk.Data(),
}
spanName += ".retrieval"
}
ctx, sp = spancontext.StartSpan(
ctx,
spanName)
defer sp.Finish()
return p.SendPriority(ctx, msg, priority) return p.SendPriority(ctx, msg, priority)
} }

View File

@ -489,8 +489,13 @@ func (p *Peer) HandleMsg(ctx context.Context, msg interface{}) error {
case *WantedHashesMsg: case *WantedHashesMsg:
return p.handleWantedHashesMsg(ctx, msg) return p.handleWantedHashesMsg(ctx, msg)
case *ChunkDeliveryMsg: case *ChunkDeliveryMsgRetrieval:
return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, msg) //handling chunk delivery is the same for retrieval and syncing, so let's cast the msg
return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, ((*ChunkDeliveryMsg)(msg)))
case *ChunkDeliveryMsgSyncing:
//handling chunk delivery is the same for retrieval and syncing, so let's cast the msg
return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, ((*ChunkDeliveryMsg)(msg)))
case *RetrieveRequestMsg: case *RetrieveRequestMsg:
return p.streamer.delivery.handleRetrieveRequestMsg(ctx, p, msg) return p.streamer.delivery.handleRetrieveRequestMsg(ctx, p, msg)
@ -681,7 +686,7 @@ func (c *clientParams) clientCreated() {
// Spec is the spec of the streamer protocol // Spec is the spec of the streamer protocol
var Spec = &protocols.Spec{ var Spec = &protocols.Spec{
Name: "stream", Name: "stream",
Version: 7, Version: 8,
MaxMsgSize: 10 * 1024 * 1024, MaxMsgSize: 10 * 1024 * 1024,
Messages: []interface{}{ Messages: []interface{}{
UnsubscribeMsg{}, UnsubscribeMsg{},
@ -690,10 +695,11 @@ var Spec = &protocols.Spec{
TakeoverProofMsg{}, TakeoverProofMsg{},
SubscribeMsg{}, SubscribeMsg{},
RetrieveRequestMsg{}, RetrieveRequestMsg{},
ChunkDeliveryMsg{}, ChunkDeliveryMsgRetrieval{},
SubscribeErrorMsg{}, SubscribeErrorMsg{},
RequestSubscriptionMsg{}, RequestSubscriptionMsg{},
QuitMsg{}, QuitMsg{},
ChunkDeliveryMsgSyncing{},
}, },
} }