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  }