mirror of https://github.com/status-im/go-waku.git
103 lines
2.8 KiB
Go
103 lines
2.8 KiB
Go
|
package relay
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
|
||
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||
|
"github.com/libp2p/go-libp2p/core/event"
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
"github.com/waku-org/go-waku/logging"
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
// EvtRelaySubscribed is an event emitted when a new subscription to a pubsub topic is created
|
||
|
type EvtRelaySubscribed struct {
|
||
|
Topic string
|
||
|
TopicInst *pubsub.Topic
|
||
|
}
|
||
|
|
||
|
// EvtRelayUnsubscribed is an event emitted when a subscription to a pubsub topic is closed
|
||
|
type EvtRelayUnsubscribed struct {
|
||
|
Topic string
|
||
|
}
|
||
|
|
||
|
type PeerTopicState int
|
||
|
|
||
|
const (
|
||
|
PEER_JOINED = iota
|
||
|
PEER_LEFT
|
||
|
)
|
||
|
|
||
|
type EvtPeerTopic struct {
|
||
|
PubsubTopic string
|
||
|
PeerID peer.ID
|
||
|
State PeerTopicState
|
||
|
}
|
||
|
|
||
|
// Events returns the event bus on which WakuRelay events will be emitted
|
||
|
func (w *WakuRelay) Events() event.Bus {
|
||
|
return w.events
|
||
|
}
|
||
|
|
||
|
func (w *WakuRelay) addPeerTopicEventListener(topic *pubsub.Topic) (*pubsub.TopicEventHandler, error) {
|
||
|
handler, err := topic.EventHandler()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
w.WaitGroup().Add(1)
|
||
|
go w.topicEventPoll(topic.String(), handler)
|
||
|
return handler, nil
|
||
|
}
|
||
|
|
||
|
func (w *WakuRelay) topicEventPoll(topic string, handler *pubsub.TopicEventHandler) {
|
||
|
defer w.WaitGroup().Done()
|
||
|
for {
|
||
|
evt, err := handler.NextPeerEvent(w.Context())
|
||
|
if err != nil {
|
||
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||
|
break
|
||
|
}
|
||
|
w.log.Error("failed to get next peer event", zap.String("topic", topic), zap.Error(err))
|
||
|
continue
|
||
|
}
|
||
|
if evt.Peer.Validate() != nil { //Empty peerEvent is returned when context passed in done.
|
||
|
break
|
||
|
}
|
||
|
if evt.Type == pubsub.PeerJoin {
|
||
|
w.log.Debug("received a PeerJoin event", zap.String("topic", topic), logging.HostID("peerID", evt.Peer))
|
||
|
err = w.emitters.EvtPeerTopic.Emit(EvtPeerTopic{PubsubTopic: topic, PeerID: evt.Peer, State: PEER_JOINED})
|
||
|
if err != nil {
|
||
|
w.log.Error("failed to emit PeerJoin", zap.String("topic", topic), zap.Error(err))
|
||
|
}
|
||
|
} else if evt.Type == pubsub.PeerLeave {
|
||
|
w.log.Debug("received a PeerLeave event", zap.String("topic", topic), logging.HostID("peerID", evt.Peer))
|
||
|
err = w.emitters.EvtPeerTopic.Emit(EvtPeerTopic{PubsubTopic: topic, PeerID: evt.Peer, State: PEER_LEFT})
|
||
|
if err != nil {
|
||
|
w.log.Error("failed to emit PeerLeave", zap.String("topic", topic), zap.Error(err))
|
||
|
}
|
||
|
} else {
|
||
|
w.log.Error("unknown event type received", zap.String("topic", topic),
|
||
|
zap.Int("eventType", int(evt.Type)))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (w *WakuRelay) CreateEventEmitters() error {
|
||
|
var err error
|
||
|
w.emitters.EvtRelaySubscribed, err = w.events.Emitter(new(EvtRelaySubscribed))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
w.emitters.EvtRelayUnsubscribed, err = w.events.Emitter(new(EvtRelayUnsubscribed))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
w.emitters.EvtPeerTopic, err = w.events.Emitter(new(EvtPeerTopic))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|