mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
swarm/network/stream: add API.UnsubscribeStream and tests
This commit is contained in:
parent
a14e4e7280
commit
f568ef178e
3 changed files with 132 additions and 3 deletions
|
|
@ -31,7 +31,10 @@ import (
|
||||||
|
|
||||||
var sendTimeout = 5 * time.Second
|
var sendTimeout = 5 * time.Second
|
||||||
|
|
||||||
var errServerNotFound = errors.New("server not found")
|
var (
|
||||||
|
errServerNotFound = errors.New("server not found")
|
||||||
|
errClientNotFound = errors.New("client not found")
|
||||||
|
)
|
||||||
|
|
||||||
// Peer is the Peer extention for the streaming protocol
|
// Peer is the Peer extention for the streaming protocol
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
|
|
@ -189,6 +192,19 @@ func (p *Peer) setClient(s string, key []byte, i Client, priority uint8, live bo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Peer) removeClient(s string, key []byte) error {
|
||||||
|
p.clientMu.Lock()
|
||||||
|
defer p.clientMu.Unlock()
|
||||||
|
|
||||||
|
sk := s + keyToString(key)
|
||||||
|
client, ok := p.clients[sk]
|
||||||
|
if !ok {
|
||||||
|
return errClientNotFound
|
||||||
|
}
|
||||||
|
client.close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Peer) close() {
|
func (p *Peer) close() {
|
||||||
for _, s := range p.servers {
|
for _, s := range p.servers {
|
||||||
s.Close()
|
s.Close()
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,24 @@ func (r *Registry) Subscribe(peerId discover.NodeID, s string, t []byte, from, t
|
||||||
return peer.SendPriority(msg, priority)
|
return peer.SendPriority(msg, priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Registry) Unsubscribe(peerId discover.NodeID, s string, t []byte) error {
|
||||||
|
peer := r.getPeer(peerId)
|
||||||
|
if peer == nil {
|
||||||
|
return fmt.Errorf("peer not found %v", peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &UnsubscribeMsg{
|
||||||
|
Stream: s,
|
||||||
|
Key: t,
|
||||||
|
}
|
||||||
|
log.Debug("Unsubscribe ", "peer", peerId, "stream", s, "key", t)
|
||||||
|
|
||||||
|
if err := peer.Send(msg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return peer.removeClient(s, t)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Registry) Retrieve(chunk *storage.Chunk) error {
|
func (r *Registry) Retrieve(chunk *storage.Chunk) error {
|
||||||
return r.delivery.RequestFromPeers(chunk.Key[:], r.skipCheck)
|
return r.delivery.RequestFromPeers(chunk.Key[:], r.skipCheck)
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +342,10 @@ func (c *client) batchDone(p *Peer, req *OfferedHashesMsg, hashes []byte) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *client) close() {
|
||||||
|
close(c.next)
|
||||||
|
}
|
||||||
|
|
||||||
// Spec is the spec of the streamer protocol
|
// Spec is the spec of the streamer protocol
|
||||||
var Spec = &protocols.Spec{
|
var Spec = &protocols.Spec{
|
||||||
Name: "stream",
|
Name: "stream",
|
||||||
|
|
@ -337,6 +359,7 @@ var Spec = &protocols.Spec{
|
||||||
SubscribeMsg{},
|
SubscribeMsg{},
|
||||||
RetrieveRequestMsg{},
|
RetrieveRequestMsg{},
|
||||||
ChunkDeliveryMsg{},
|
ChunkDeliveryMsg{},
|
||||||
|
SubscribeErrorMsg{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,3 +433,7 @@ func (api *API) ReadAll(hash common.Hash) (int64, error) {
|
||||||
func (api *API) SubscribeStream(peerId discover.NodeID, s string, t []byte, from, to uint64, priority uint8, live bool) error {
|
func (api *API) SubscribeStream(peerId discover.NodeID, s string, t []byte, from, to uint64, priority uint8, live bool) error {
|
||||||
return api.streamer.Subscribe(peerId, s, t, from, to, priority, live)
|
return api.streamer.Subscribe(peerId, s, t, from, to, priority, live)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) UnsubscribeStream(peerId discover.NodeID, s string, t []byte) error {
|
||||||
|
return api.streamer.Unsubscribe(peerId, s, t)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func (self *testServer) GetData([]byte) ([]byte, error) {
|
||||||
func (self *testServer) Close() {
|
func (self *testServer) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamerDownstreamSubscribeMsgExchange(t *testing.T) {
|
func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
|
||||||
tester, streamer, _, teardown, err := newStreamerTester(t)
|
tester, streamer, _, teardown, err := newStreamerTester(t)
|
||||||
defer teardown()
|
defer teardown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -128,9 +128,32 @@ func TestStreamerDownstreamSubscribeMsgExchange(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = streamer.Unsubscribe(peerID, "foo", []byte{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamerUpstreamSubscribeMsgExchange(t *testing.T) {
|
err = tester.TestExchanges(p2ptest.Exchange{
|
||||||
|
Label: "Unsubscribe message",
|
||||||
|
Expects: []p2ptest.Expect{
|
||||||
|
p2ptest.Expect{
|
||||||
|
Code: 0,
|
||||||
|
Msg: &UnsubscribeMsg{
|
||||||
|
Stream: "foo",
|
||||||
|
Key: []byte{},
|
||||||
|
},
|
||||||
|
Peer: peerID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
|
||||||
tester, streamer, _, teardown, err := newStreamerTester(t)
|
tester, streamer, _, teardown, err := newStreamerTester(t)
|
||||||
defer teardown()
|
defer teardown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -182,6 +205,69 @@ func TestStreamerUpstreamSubscribeMsgExchange(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = tester.TestExchanges(p2ptest.Exchange{
|
||||||
|
Label: "unsubscribe message",
|
||||||
|
Triggers: []p2ptest.Trigger{
|
||||||
|
p2ptest.Trigger{
|
||||||
|
Code: 0,
|
||||||
|
Msg: &UnsubscribeMsg{
|
||||||
|
Stream: "foo",
|
||||||
|
Key: []byte{},
|
||||||
|
},
|
||||||
|
Peer: peerID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) {
|
||||||
|
tester, streamer, _, teardown, err := newStreamerTester(t)
|
||||||
|
defer teardown()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
streamer.RegisterServerFunc("foo", func(p *Peer, t []byte) (Server, error) {
|
||||||
|
return &testServer{
|
||||||
|
t: t,
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
peerID := tester.IDs[0]
|
||||||
|
|
||||||
|
err = tester.TestExchanges(p2ptest.Exchange{
|
||||||
|
Label: "Subscribe message",
|
||||||
|
Triggers: []p2ptest.Trigger{
|
||||||
|
p2ptest.Trigger{
|
||||||
|
Code: 4,
|
||||||
|
Msg: &SubscribeMsg{
|
||||||
|
Stream: "bar",
|
||||||
|
Key: []byte{},
|
||||||
|
From: 5,
|
||||||
|
To: 8,
|
||||||
|
Priority: Top,
|
||||||
|
},
|
||||||
|
Peer: peerID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Expects: []p2ptest.Expect{
|
||||||
|
p2ptest.Expect{
|
||||||
|
Code: 7,
|
||||||
|
Msg: &SubscribeErrorMsg{
|
||||||
|
Error: "stream bar not registered",
|
||||||
|
},
|
||||||
|
Peer: peerID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
|
func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue