mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 08:47:42 +08:00
feat(bs:net) impl service wrapper
This commit is contained in:
@ -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
8
bitswap/message/Makefile
Normal 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
|
@ -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)
|
||||
|
20
bitswap/network/interface.go
Normal file
20
bitswap/network/interface.go
Normal 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)
|
||||
}
|
76
bitswap/network/service_wrapper.go
Normal file
76
bitswap/network/service_wrapper.go
Normal 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
29
bitswap/receiver.go
Normal 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
13
bitswap/receiver_test.go
Normal 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())
|
||||
}
|
Reference in New Issue
Block a user