mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 17:03:58 +08:00
refac(bitswap) simply network interfaces
This commit is contained in:
@ -8,10 +8,9 @@ import (
|
||||
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
|
||||
|
||||
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
|
||||
bsnet "github.com/jbenet/go-ipfs/bitswap/network"
|
||||
notifications "github.com/jbenet/go-ipfs/bitswap/notifications"
|
||||
tx "github.com/jbenet/go-ipfs/bitswap/transmission"
|
||||
blocks "github.com/jbenet/go-ipfs/blocks"
|
||||
net "github.com/jbenet/go-ipfs/net"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
routing "github.com/jbenet/go-ipfs/routing"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
@ -34,7 +33,7 @@ type BitSwap struct {
|
||||
peer *peer.Peer
|
||||
|
||||
// sender delivers messages on behalf of the session
|
||||
sender tx.Sender
|
||||
sender bsnet.NetworkAdapter
|
||||
|
||||
// datastore is the local database // Ledgers of known
|
||||
datastore ds.Datastore
|
||||
@ -62,21 +61,16 @@ type BitSwap struct {
|
||||
}
|
||||
|
||||
// NewSession initializes a bitswap session.
|
||||
func NewSession(parent context.Context, s net.Sender, p *peer.Peer, d ds.Datastore, r routing.IpfsRouting) *BitSwap {
|
||||
func NewSession(parent context.Context, s bsnet.NetworkService, p *peer.Peer, d ds.Datastore, r routing.IpfsRouting) *BitSwap {
|
||||
|
||||
// TODO(brian): define a contract for management of async operations that
|
||||
// fall under bitswap's purview
|
||||
// ctx, _ := context.WithCancel(parent)
|
||||
|
||||
receiver := tx.Forwarder{}
|
||||
sender := tx.NewSender(s)
|
||||
receiver := bsnet.Forwarder{}
|
||||
bs := &BitSwap{
|
||||
peer: p,
|
||||
datastore: d,
|
||||
partners: LedgerMap{},
|
||||
wantList: KeySet{},
|
||||
routing: r,
|
||||
sender: sender,
|
||||
sender: bsnet.NewNetworkAdapter(s, &receiver),
|
||||
haltChan: make(chan struct{}),
|
||||
notifications: notifications.New(),
|
||||
strategy: YesManStrategy,
|
||||
@ -246,7 +240,7 @@ func (bs *BitSwap) Halt() {
|
||||
|
||||
func (bs *BitSwap) ReceiveMessage(
|
||||
ctx context.Context, sender *peer.Peer, incoming bsmsg.BitSwapMessage) (
|
||||
bsmsg.BitSwapMessage, *peer.Peer, error) {
|
||||
*peer.Peer, bsmsg.BitSwapMessage, error) {
|
||||
if incoming.Blocks() != nil {
|
||||
for _, block := range incoming.Blocks() {
|
||||
go bs.blockReceive(sender, block)
|
||||
@ -255,6 +249,7 @@ func (bs *BitSwap) ReceiveMessage(
|
||||
|
||||
if incoming.Wantlist() != nil {
|
||||
for _, want := range incoming.Wantlist() {
|
||||
// TODO(brian): return the block synchronously
|
||||
go bs.peerWantsBlock(sender, want)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package transmission
|
||||
package network
|
||||
|
||||
import (
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
@ -6,17 +6,17 @@ import (
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
)
|
||||
|
||||
// Forwarder breaks the circular dependency between bitswap and its sender
|
||||
// NB: A sender is instantiated with a handler and this sender is then passed
|
||||
// as a constructor argument to BitSwap. However, the handler is BitSwap!
|
||||
// Hence, this receiver.
|
||||
// Forwarder receives messages and forwards them to the delegate.
|
||||
//
|
||||
// Forwarder breaks the circular dependency between the BitSwap Session and the
|
||||
// Network Service.
|
||||
type Forwarder struct {
|
||||
delegate Receiver
|
||||
}
|
||||
|
||||
func (r *Forwarder) ReceiveMessage(
|
||||
ctx context.Context, sender *peer.Peer, incoming bsmsg.BitSwapMessage) (
|
||||
bsmsg.BitSwapMessage, *peer.Peer, error) {
|
||||
*peer.Peer, bsmsg.BitSwapMessage, error) {
|
||||
if r.delegate == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package transmission
|
||||
package network
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@ -13,4 +13,14 @@ func TestDoesntPanicIfDelegateNotPresent(t *testing.T) {
|
||||
fwdr.ReceiveMessage(context.Background(), &peer.Peer{}, bsmsg.New())
|
||||
}
|
||||
|
||||
// TODO(brian): func TestForwardsMessageToDelegate(t *testing.T)
|
||||
func TestForwardsMessageToDelegate(t *testing.T) {
|
||||
fwdr := Forwarder{delegate: &EchoDelegate{}}
|
||||
fwdr.ReceiveMessage(context.Background(), &peer.Peer{}, bsmsg.New())
|
||||
}
|
||||
|
||||
type EchoDelegate struct{}
|
||||
|
||||
func (d *EchoDelegate) ReceiveMessage(ctx context.Context, p *peer.Peer,
|
||||
incoming bsmsg.BitSwapMessage) (*peer.Peer, bsmsg.BitSwapMessage, error) {
|
||||
return p, incoming, nil
|
||||
}
|
||||
|
@ -1,23 +1,38 @@
|
||||
package transmission
|
||||
package network
|
||||
|
||||
import (
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
netservice "github.com/jbenet/go-ipfs/net/service"
|
||||
|
||||
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
|
||||
netmsg "github.com/jbenet/go-ipfs/net/message"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
)
|
||||
|
||||
type Sender interface {
|
||||
SendMessage(ctx context.Context, destination *peer.Peer, message bsmsg.Exportable) error
|
||||
SendRequest(ctx context.Context, destination *peer.Peer, outgoing bsmsg.Exportable) (
|
||||
incoming bsmsg.BitSwapMessage, err error)
|
||||
// NetworkAdapter mediates the exchange's communication with the network.
|
||||
type NetworkAdapter interface {
|
||||
|
||||
// SendMessage sends a BitSwap message to a peer.
|
||||
SendMessage(
|
||||
context.Context,
|
||||
*peer.Peer,
|
||||
bsmsg.BitSwapMessage) error
|
||||
|
||||
// SendRequest sends a BitSwap message to a peer and waits for a response.
|
||||
SendRequest(
|
||||
context.Context,
|
||||
*peer.Peer,
|
||||
bsmsg.BitSwapMessage) (incoming bsmsg.BitSwapMessage, err error)
|
||||
|
||||
// SetDelegate registers the Reciver to handle messages received from the
|
||||
// network.
|
||||
SetDelegate(Receiver)
|
||||
}
|
||||
|
||||
// TODO(brian): consider returning a NetMessage
|
||||
type Receiver interface {
|
||||
ReceiveMessage(
|
||||
ctx context.Context, sender *peer.Peer, incoming bsmsg.BitSwapMessage) (
|
||||
outgoing bsmsg.BitSwapMessage, destination *peer.Peer, err error)
|
||||
destination *peer.Peer, outgoing bsmsg.BitSwapMessage, err error)
|
||||
}
|
||||
|
||||
// TODO(brian): move this to go-ipfs/net package
|
||||
|
@ -1,43 +1,54 @@
|
||||
package transmission
|
||||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
|
||||
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
|
||||
net "github.com/jbenet/go-ipfs/net"
|
||||
netmsg "github.com/jbenet/go-ipfs/net/message"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
)
|
||||
|
||||
// NewSender wraps the net.service.Sender to perform translation between
|
||||
// NewSender wraps a network Service to perform translation between
|
||||
// BitSwapMessage and NetMessage formats. This allows the BitSwap session to
|
||||
// ignore these details.
|
||||
func NewSender(s net.Sender) Sender {
|
||||
return &senderWrapper{s}
|
||||
func NewNetworkAdapter(s NetworkService, r Receiver) NetworkAdapter {
|
||||
adapter := networkAdapter{
|
||||
networkService: s,
|
||||
receiver: r,
|
||||
}
|
||||
s.SetHandler(&adapter)
|
||||
return &adapter
|
||||
}
|
||||
|
||||
// handlerWrapper implements the net.service.Handler interface. It is
|
||||
// responsible for converting between
|
||||
// delegates calls to the BitSwap delegate.
|
||||
type handlerWrapper struct {
|
||||
bitswapDelegate Receiver
|
||||
// networkAdapter implements NetworkAdapter
|
||||
type networkAdapter struct {
|
||||
networkService NetworkService
|
||||
receiver Receiver
|
||||
}
|
||||
|
||||
// HandleMessage marshals and unmarshals net messages, forwarding them to the
|
||||
// BitSwapMessage receiver
|
||||
func (wrapper *handlerWrapper) HandleMessage(
|
||||
func (adapter *networkAdapter) HandleMessage(
|
||||
ctx context.Context, incoming netmsg.NetMessage) (netmsg.NetMessage, error) {
|
||||
|
||||
if adapter.receiver == nil {
|
||||
return nil, errors.New("No receiver. NetMessage dropped")
|
||||
}
|
||||
|
||||
received, err := bsmsg.FromNet(incoming)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bsmsg, p, err := wrapper.bitswapDelegate.ReceiveMessage(ctx, incoming.Peer(), received)
|
||||
p, bsmsg, err := adapter.receiver.ReceiveMessage(ctx, incoming.Peer(), received)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bsmsg == nil {
|
||||
|
||||
// TODO(brian): put this in a helper function
|
||||
if bsmsg == nil || p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -49,29 +60,34 @@ func (wrapper *handlerWrapper) HandleMessage(
|
||||
return outgoing, nil
|
||||
}
|
||||
|
||||
type senderWrapper struct {
|
||||
serviceDelegate net.Sender
|
||||
}
|
||||
func (adapter *networkAdapter) SendMessage(
|
||||
ctx context.Context,
|
||||
p *peer.Peer,
|
||||
outgoing bsmsg.BitSwapMessage) error {
|
||||
|
||||
func (wrapper *senderWrapper) SendMessage(
|
||||
ctx context.Context, p *peer.Peer, outgoing bsmsg.Exportable) error {
|
||||
nmsg, err := outgoing.ToNet(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return wrapper.serviceDelegate.SendMessage(ctx, nmsg)
|
||||
return adapter.networkService.SendMessage(ctx, nmsg)
|
||||
}
|
||||
|
||||
func (wrapper *senderWrapper) SendRequest(ctx context.Context,
|
||||
p *peer.Peer, outgoing bsmsg.Exportable) (bsmsg.BitSwapMessage, error) {
|
||||
func (adapter *networkAdapter) SendRequest(
|
||||
ctx context.Context,
|
||||
p *peer.Peer,
|
||||
outgoing bsmsg.BitSwapMessage) (bsmsg.BitSwapMessage, error) {
|
||||
|
||||
outgoingMsg, err := outgoing.ToNet(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
incomingMsg, err := wrapper.serviceDelegate.SendRequest(ctx, outgoingMsg)
|
||||
incomingMsg, err := adapter.networkService.SendRequest(ctx, outgoingMsg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bsmsg.FromNet(incomingMsg)
|
||||
}
|
||||
|
||||
func (adapter *networkAdapter) SetDelegate(r Receiver) {
|
||||
adapter.receiver = r
|
||||
}
|
||||
|
Reference in New Issue
Block a user