github.com/anycable/anycable-go@v1.5.1/broadcast/legacy_nats.go (about) 1 package broadcast 2 3 import ( 4 "context" 5 "log/slog" 6 7 "github.com/nats-io/nats.go" 8 9 nconfig "github.com/anycable/anycable-go/nats" 10 ) 11 12 type LegacyNATSBroadcaster struct { 13 conn *nats.Conn 14 handler Handler 15 config *nconfig.NATSConfig 16 17 log *slog.Logger 18 } 19 20 var _ Broadcaster = (*LegacyNATSBroadcaster)(nil) 21 22 func NewLegacyNATSBroadcaster(node Handler, c *nconfig.NATSConfig, l *slog.Logger) *LegacyNATSBroadcaster { 23 return &LegacyNATSBroadcaster{ 24 config: c, 25 handler: node, 26 log: l.With("context", "broadcast").With("provider", "nats"), 27 } 28 } 29 30 func (LegacyNATSBroadcaster) IsFanout() bool { 31 return true 32 } 33 34 func (s *LegacyNATSBroadcaster) Start(done chan (error)) error { 35 connectOptions := []nats.Option{ 36 nats.RetryOnFailedConnect(true), 37 nats.MaxReconnects(s.config.MaxReconnectAttempts), 38 nats.DisconnectErrHandler(func(nc *nats.Conn, err error) { 39 if err != nil { 40 s.log.Warn("connection failed", "error", err) 41 } 42 }), 43 nats.ReconnectHandler(func(nc *nats.Conn) { 44 s.log.Info("connection restored", "url", nc.ConnectedUrl()) 45 }), 46 } 47 48 if s.config.DontRandomizeServers { 49 connectOptions = append(connectOptions, nats.DontRandomize()) 50 } 51 52 nc, err := nats.Connect(s.config.Servers, connectOptions...) 53 54 if err != nil { 55 return err 56 } 57 58 _, err = nc.Subscribe(s.config.Channel, func(m *nats.Msg) { 59 s.log.Debug("received pubsub message") 60 s.handler.HandlePubSub(m.Data) 61 }) 62 63 if err != nil { 64 nc.Close() 65 return err 66 } 67 68 s.log.Info("subscribing for broadcasts", "channel", s.config.Channel) 69 70 s.conn = nc 71 72 return nil 73 } 74 75 func (s *LegacyNATSBroadcaster) Shutdown(ctx context.Context) error { 76 if s.conn != nil { 77 s.conn.Close() 78 } 79 80 return nil 81 }