1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-28 17:03:58 +08:00

feat(bs:net) impl service wrapper

This commit is contained in:
Brian Tiger Chow
2014-09-12 20:51:57 -07:00
parent b8bd2bc455
commit 7fcb5d3a4b
7 changed files with 173 additions and 6 deletions

View File

@ -1,12 +1,14 @@
package bitswap
import (
"errors"
"time"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
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"
blocks "github.com/jbenet/go-ipfs/blocks"
swarm "github.com/jbenet/go-ipfs/net/swarm"
@ -31,6 +33,7 @@ type BitSwap struct {
peer *peer.Peer
// net holds the connections to all peers.
sender bsnet.Sender
net swarm.Network
meschan *swarm.Chan
@ -61,17 +64,22 @@ type BitSwap struct {
// NewBitSwap creates a new BitSwap instance. It does not check its parameters.
func NewBitSwap(p *peer.Peer, net swarm.Network, d ds.Datastore, r routing.IpfsRouting) *BitSwap {
receiver := receiver{}
sender := bsnet.NewBSNetService(context.Background(), &receiver)
bs := &BitSwap{
peer: p,
net: net,
datastore: d,
partners: LedgerMap{},
wantList: KeySet{},
routing: r.(*dht.IpfsDHT),
peer: p,
net: net,
datastore: d,
partners: LedgerMap{},
wantList: KeySet{},
routing: r.(*dht.IpfsDHT),
// TODO(brian): replace |meschan| with |sender| in BitSwap impl
meschan: net.GetChannel(swarm.PBWrapper_BITSWAP),
sender: sender,
haltChan: make(chan struct{}),
notifications: notifications.New(),
}
receiver.Delegate(bs)
go bs.handleMessages()
return bs
@ -274,3 +282,9 @@ func (bs *BitSwap) SetStrategy(sf StrategyFunc) {
ledger.Strategy = sf
}
}
func (r *BitSwap) ReceiveMessage(
ctx context.Context, incoming bsmsg.BitSwapMessage) (
bsmsg.BitSwapMessage, *peer.Peer, error) {
return nil, nil, errors.New("TODO implement")
}

8
bitswap/message/Makefile Normal file
View File

@ -0,0 +1,8 @@
# TODO(brian): add proto tasks
all: message.pb.go
message.pb.go: message.proto
protoc --gogo_out=. --proto_path=../../../../../:/usr/local/opt/protobuf/include:. $<
clean:
rm message.pb.go

View File

@ -1,7 +1,10 @@
package message
import (
"errors"
proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
netmsg "github.com/jbenet/go-ipfs/net/message"
blocks "github.com/jbenet/go-ipfs/blocks"
nm "github.com/jbenet/go-ipfs/net/message"
@ -55,6 +58,10 @@ func (m *message) AppendBlock(b *blocks.Block) {
m.pb.Blocks = append(m.pb.Blocks, b.Data)
}
func FromNet(nmsg netmsg.NetMessage) (BitSwapMessage, error) {
return nil, errors.New("TODO implement")
}
func FromSwarm(sms swarm.Message) (BitSwapMessage, error) {
var protoMsg PBMessage
err := proto.Unmarshal(sms.Data, &protoMsg)

View File

@ -0,0 +1,20 @@
package network
import (
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
bsmsg "github.com/jbenet/go-ipfs/bitswap/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)
}
// TODO(brian): consider returning a NetMessage
type Receiver interface {
ReceiveMessage(ctx context.Context, incoming bsmsg.BitSwapMessage) (
outgoing bsmsg.BitSwapMessage, destination *peer.Peer, err error)
}

View File

@ -0,0 +1,76 @@
package network
import (
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
netmsg "github.com/jbenet/go-ipfs/net/message"
netservice "github.com/jbenet/go-ipfs/net/service"
peer "github.com/jbenet/go-ipfs/peer"
)
func NewBSNetService(ctx context.Context, r Receiver) Sender {
h := &handlerWrapper{r}
s := netservice.NewService(ctx, h)
return &serviceWrapper{*s}
}
// handlerWrapper is responsible for marshaling/unmarshaling NetMessages. It
// delegates calls to the BitSwap delegate.
type handlerWrapper struct {
bitswapDelegate Receiver
}
// HandleMessage marshals and unmarshals net messages, forwarding them to the
// BitSwapMessage receiver
func (wrapper *handlerWrapper) HandleMessage(
ctx context.Context, incoming netmsg.NetMessage) (netmsg.NetMessage, error) {
received, err := bsmsg.FromNet(incoming)
if err != nil {
return nil, err
}
bsmsg, p, err := wrapper.bitswapDelegate.ReceiveMessage(ctx, received)
if err != nil {
return nil, err
}
if bsmsg == nil {
return nil, nil
}
outgoing, err := bsmsg.ToNet(p)
if err != nil {
return nil, err
}
return outgoing, nil
}
type serviceWrapper struct {
serviceDelegate netservice.Service
}
func (wrapper *serviceWrapper) SendMessage(
ctx context.Context, p *peer.Peer, outgoing bsmsg.Exportable) error {
nmsg, err := outgoing.ToNet(p)
if err != nil {
return err
}
req, err := netservice.NewRequest(p.ID)
return wrapper.serviceDelegate.SendMessage(ctx, nmsg, req.ID)
}
func (wrapper *serviceWrapper) SendRequest(ctx context.Context,
p *peer.Peer, outgoing bsmsg.Exportable) (bsmsg.BitSwapMessage, error) {
outgoingMsg, err := outgoing.ToNet(p)
if err != nil {
return nil, err
}
incomingMsg, err := wrapper.serviceDelegate.SendRequest(ctx, outgoingMsg)
if err != nil {
return nil, err
}
return bsmsg.FromNet(incomingMsg)
}

29
bitswap/receiver.go Normal file
View File

@ -0,0 +1,29 @@
package bitswap
import (
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
bsnet "github.com/jbenet/go-ipfs/bitswap/network"
peer "github.com/jbenet/go-ipfs/peer"
)
// receiver 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.
type receiver struct {
delegate bsnet.Receiver
}
func (r *receiver) ReceiveMessage(
ctx context.Context, incoming bsmsg.BitSwapMessage) (
bsmsg.BitSwapMessage, *peer.Peer, error) {
if r.delegate == nil {
return nil, nil, nil
}
return r.delegate.ReceiveMessage(ctx, incoming)
}
func (r *receiver) Delegate(delegate bsnet.Receiver) {
r.delegate = delegate
}

13
bitswap/receiver_test.go Normal file
View File

@ -0,0 +1,13 @@
package bitswap
import (
"testing"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
bsmsg "github.com/jbenet/go-ipfs/bitswap/message"
)
func TestDoesntPanicIfDelegateNotPresent(t *testing.T) {
r := receiver{}
r.ReceiveMessage(context.Background(), bsmsg.New())
}