github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/rpc/nats/connect.go (about)

     1  package nats
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/angenalZZZ/gofunc/log"
     7  	"github.com/nats-io/nats.go"
     8  )
     9  
    10  // Conn represents a bare connection to global nats-server.
    11  // The connection is safe to use in multiple Go routines concurrently.
    12  var Conn *nats.Conn
    13  
    14  // Subject global subscription. This can be different
    15  // than the received subject inside a Msg if this is a wildcard.
    16  var Subject string
    17  
    18  // Log logger for global Conn.
    19  var Log *log.Logger
    20  
    21  // Connection addr and token, credentials, cert and key
    22  // to be used when connecting to a nats-server.
    23  type Connection struct {
    24  	Addr  string
    25  	Token string
    26  	Cred  string
    27  	Cert  string
    28  	Key   string
    29  }
    30  
    31  // New creates a client connect.
    32  func New(name, flagAddr, flagCred string, flagToken string, flagCert, flagKey string) (nc *nats.Conn, err error) {
    33  	var (
    34  		addr = nats.DefaultURL
    35  		ops  = []nats.Option{nats.Name(name)}
    36  	)
    37  
    38  	if Log == nil {
    39  		Log = log.InitConsole("15:04:05.000", false)
    40  	}
    41  
    42  	if flagAddr != "" {
    43  		addr = flagAddr
    44  	}
    45  	if flagCred != "" {
    46  		ops = append(ops, nats.UserCredentials(flagCred))
    47  	}
    48  	if flagToken != "" {
    49  		ops = append(ops, nats.Token(flagToken))
    50  	}
    51  
    52  	// If the server requires client certificate
    53  	// E.g. /certs/client-cert.pem  /certs/client-Index.pem
    54  	if flagCert != "" && flagKey != "" {
    55  		cert := nats.ClientCert(flagCert, flagKey)
    56  		ops = append(ops, cert)
    57  	}
    58  	// If you are using a self-signed certificate, you need to have a tls.Config with RootCAs setup
    59  	// E.g. /certs/ca.pem
    60  	if flagCert != "" {
    61  		cert := nats.RootCAs(flagCert)
    62  		ops = append(ops, cert)
    63  	}
    64  
    65  	ops = append(ops,
    66  		nats.MaxReconnects(1200),
    67  		nats.PingInterval(time.Minute),
    68  		nats.ReconnectWait(2*time.Second),
    69  		nats.PingInterval(time.Minute),
    70  		nats.Timeout(2*time.Second),
    71  		nats.SyncQueueLen(100000000),     // sets number of messages will buffer internally.
    72  		nats.ReconnectBufSize(104857600), // 100Mb size of messages kept while busy reconnecting.
    73  		nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
    74  			Log.Error().Msgf("[nats] disconnected due to: %s, will attempt reconnects for 10 minutes", err)
    75  		}),
    76  		nats.ReconnectHandler(func(nc *nats.Conn) {
    77  			Log.Error().Msgf("[nats] reconnected %q", nc.ConnectedUrl())
    78  		}),
    79  		nats.ClosedHandler(func(nc *nats.Conn) {
    80  			Log.Error().Msgf("[nats] exiting")
    81  		}),
    82  	)
    83  
    84  	nc, err = nats.Connect(addr, ops...)
    85  	return
    86  }
    87  
    88  // FlushAndCheckLastError Flush connection to server, returns when all messages have been processed.
    89  func FlushAndCheckLastError(nc *nats.Conn) {
    90  	if err := nc.Flush(); err != nil {
    91  		Log.Error().Msgf("[nats] flush messages > %s", err)
    92  	} else if err = nc.LastError(); err != nil {
    93  		Log.Error().Msgf("[nats] after flush and get last error > %s", err)
    94  	}
    95  }
    96  
    97  // SubscribeLimitHandle Set pending limits error handle.
    98  func SubscribeLimitHandle(sub *nats.Subscription, msgLimit, bytesLimitOfMsg int) {
    99  	if err := sub.SetPendingLimits(msgLimit, msgLimit*bytesLimitOfMsg); err != nil {
   100  		Log.Error().Msgf("[nats] set pending limits > %s", err)
   101  	}
   102  
   103  	// Delivered returns the number of delivered messages for this subscription.
   104  	if deliveredNum, err := sub.Delivered(); err != nil {
   105  		Log.Error().Msgf("[nats] number of messages deliver > %s", err)
   106  	} else if deliveredNum > 0 {
   107  		Log.Info().Msgf("[nats] number of messages deliver: %d", deliveredNum)
   108  	}
   109  
   110  	// Dropped returns the number of known dropped messages for this subscription.
   111  	if droppedNum, err := sub.Dropped(); err != nil {
   112  		Log.Error().Msgf("[nats] number of messages dropped > %s", err)
   113  	} else if droppedNum > 0 {
   114  		Log.Info().Msgf("[nats] number of messages dropped: %d", droppedNum)
   115  	}
   116  }
   117  
   118  // SubscribeErrorHandle Set listening error handle.
   119  func SubscribeErrorHandle(sub *nats.Subscription, async bool, err error) {
   120  	if err != nil {
   121  		Log.Error().Msgf("[nats] failed listening on %q > %s", sub.Subject, err)
   122  	} else {
   123  		a, v := "async", "available"
   124  		if async == false {
   125  			a = "sync"
   126  		}
   127  		if sub.IsValid() == false {
   128  			v = "invalid"
   129  		}
   130  		Log.Info().Msgf("[nats] successful listening on %s subject: %q", v, sub.Subject)
   131  		Log.Info().Msgf("[nats] start %s waiting to receive messages on %q", a, sub.Subject)
   132  	}
   133  }