github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/rpc/nats/subscriber.go (about) 1 package nats 2 3 import ( 4 "log" 5 "syscall" 6 "time" 7 8 "github.com/angenalZZZ/gofunc/f" 9 "github.com/nats-io/nats.go" 10 ) 11 12 // Subscriber a subscriber for Client Connect. 13 type Subscriber struct { 14 *nats.Conn 15 sub *nats.Subscription 16 Subj string 17 Hand nats.MsgHandler 18 Since *f.TimeStamp 19 MsgLimit int // sets the limits for pending messages for this subscription. 20 BytesLimit int // sets the limits for a message's bytes for this subscription. 21 } 22 23 // NewSubscriber Create a subscriber for Client Connect. 24 func NewSubscriber(nc *nats.Conn, subject string, msgHandler nats.MsgHandler) *Subscriber { 25 sub := &Subscriber{ 26 Conn: nc, 27 Subj: subject, 28 Hand: msgHandler, 29 Since: f.TimeFrom(time.Now(), true), 30 MsgLimit: 100000000, // pending messages: 100 million 31 BytesLimit: 1048576, // a message's size: 1MB 32 } 33 return sub 34 } 35 36 // Run runtime to end your application. 37 func (sub *Subscriber) Run(waitFunc ...func()) { 38 var err error 39 40 // Handle panic. 41 defer func() { 42 err := recover() 43 if err != nil { 44 Log.Error().Msgf("[nats] run error > %v", err) 45 } else { 46 Log.Warn().Msg("[nats] stop receive new data") 47 } 48 49 // Unsubscribe will remove interest in the given subject. 50 _ = sub.sub.Unsubscribe() 51 // Drain connection (Preferred for responders), Close() not needed if this is called. 52 _ = sub.Conn.Drain() 53 54 // os.Exit(1) 55 if err != nil { 56 log.Fatal(err) 57 } 58 }() 59 60 // Async Subscriber. 61 sub.sub, err = sub.Conn.Subscribe(sub.Subj, sub.Hand) 62 // Set listening. 63 SubscribeErrorHandle(sub.sub, true, err) 64 if err != nil { 65 log.Fatal(err) 66 } 67 68 // Set pending limits. 69 SubscribeLimitHandle(sub.sub, sub.MsgLimit, sub.BytesLimit) 70 71 // Flush connection to server, returns when all messages have been processed. 72 FlushAndCheckLastError(sub.Conn) 73 74 if len(waitFunc) > 0 { 75 waitFunc[0]() 76 return 77 } 78 79 // Pass the signals you want to end your application. 80 death := f.NewDeath(syscall.SIGINT, syscall.SIGTERM) 81 // When you want to block for shutdown signals. 82 death.WaitForDeathWithFunc(func() { 83 Log.Error().Msg("[nats] forced to shutdown.") 84 }) 85 }