Commit 014157ca authored by Brian Tiger Chow's avatar Brian Tiger Chow

refac(bitswap) simply network interfaces

parent c34d4df9
......@@ -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)
}
}
......
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
}
......
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
}
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
......
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
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment