github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/rpc/nats/subscribers.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  // Subscribers subscriber list for a Client Connect.
    13  type Subscribers 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  // NewSubscribers Create subscriber list for a Client Connect.
    24  func NewSubscribers(nc *nats.Conn, subject []string, msgHandler []nats.MsgHandler) *Subscribers {
    25  	sub := &Subscribers{
    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 *Subscribers) 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  		for _, s := range sub.sub {
    51  			_ = s.Unsubscribe()
    52  		}
    53  		// Drain connection (Preferred for responders), Close() not needed if this is called.
    54  		_ = sub.Conn.Drain()
    55  
    56  		// os.Exit(1)
    57  		if err != nil {
    58  			log.Fatal(err)
    59  		}
    60  	}()
    61  
    62  	// Async Subscriber.
    63  	sub.sub = make([]*nats.Subscription, len(sub.Subj))
    64  	for i, subj := range sub.Subj {
    65  		sub.sub[i], err = sub.Conn.Subscribe(subj, sub.Hand[i])
    66  
    67  		// Set listening.
    68  		SubscribeErrorHandle(sub.sub[i], true, err)
    69  		if err != nil {
    70  			log.Fatal(err)
    71  		}
    72  
    73  		// Set pending limits.
    74  		SubscribeLimitHandle(sub.sub[i], sub.MsgLimit, sub.BytesLimit)
    75  
    76  		// Flush connection to server, returns when all messages have been processed.
    77  		FlushAndCheckLastError(sub.Conn)
    78  	}
    79  
    80  	if len(waitFunc) > 0 {
    81  		waitFunc[0]()
    82  		return
    83  	}
    84  
    85  	// Pass the signals you want to end your application.
    86  	death := f.NewDeath(syscall.SIGINT, syscall.SIGTERM)
    87  	// When you want to block for shutdown signals.
    88  	death.WaitForDeathWithFunc(func() {
    89  		Log.Error().Msg("[nats] forced to shutdown.")
    90  	})
    91  }