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