All checks were successful
		
		
	
	test / test (push) Successful in 3m25s
				
			* util/id: add ability to specify what kind of id generate (nanoid/uuid v8) * logger/slog: write stacktrace always on fatal * logger/slog: try to close Out and sleep 1s Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> Reviewed-on: #382 Co-authored-by: Vasiliy Tolstov <v.tolstov@unistack.org> Co-committed-by: Vasiliy Tolstov <v.tolstov@unistack.org>
		
			
				
	
	
		
			417 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			417 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package server
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"crypto/tls"
 | 
						|
	"net"
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"go.unistack.org/micro/v3/broker"
 | 
						|
	"go.unistack.org/micro/v3/codec"
 | 
						|
	"go.unistack.org/micro/v3/logger"
 | 
						|
	"go.unistack.org/micro/v3/metadata"
 | 
						|
	"go.unistack.org/micro/v3/meter"
 | 
						|
	"go.unistack.org/micro/v3/options"
 | 
						|
	"go.unistack.org/micro/v3/register"
 | 
						|
	msync "go.unistack.org/micro/v3/sync"
 | 
						|
	"go.unistack.org/micro/v3/tracer"
 | 
						|
	"go.unistack.org/micro/v3/util/id"
 | 
						|
)
 | 
						|
 | 
						|
// Option func
 | 
						|
type Option func(*Options)
 | 
						|
 | 
						|
// Options server struct
 | 
						|
type Options struct {
 | 
						|
	// Codecs map to handle content-type
 | 
						|
	Codecs map[string]codec.Codec
 | 
						|
	// Metadata holds the server metadata
 | 
						|
	Metadata metadata.Metadata
 | 
						|
 | 
						|
	// ID holds the id of the server
 | 
						|
	ID string
 | 
						|
	// Namespace for te server
 | 
						|
	Namespace string
 | 
						|
	// Name holds the server name
 | 
						|
	Name string
 | 
						|
	// Address holds the server address
 | 
						|
	Address string
 | 
						|
	// Advertise holds the advertise address
 | 
						|
	Advertise string
 | 
						|
	// Version holds the server version
 | 
						|
	Version string
 | 
						|
 | 
						|
	// Context holds the external options and can be used for server shutdown
 | 
						|
	Context context.Context
 | 
						|
	// Broker holds the server broker
 | 
						|
	Broker broker.Broker
 | 
						|
	// Register holds the register
 | 
						|
	Register register.Register
 | 
						|
	// Tracer holds the tracer
 | 
						|
	Tracer tracer.Tracer
 | 
						|
	// Logger holds the logger
 | 
						|
	Logger logger.Logger
 | 
						|
	// Meter holds the meter
 | 
						|
	Meter meter.Meter
 | 
						|
	// Listener may be passed if already created
 | 
						|
	Listener net.Listener
 | 
						|
 | 
						|
	// TLSConfig specifies tls.Config for secure serving
 | 
						|
	TLSConfig *tls.Config
 | 
						|
	// Wait group
 | 
						|
	Wait *msync.WaitGroup
 | 
						|
 | 
						|
	// RegisterCheck run before register server
 | 
						|
	RegisterCheck func(context.Context) error
 | 
						|
 | 
						|
	// Hooks may contains hook actions that performs before/after server handler
 | 
						|
	// or server subscriber handler
 | 
						|
	Hooks options.Hooks
 | 
						|
 | 
						|
	// RegisterInterval holds he interval for re-register
 | 
						|
	RegisterInterval time.Duration
 | 
						|
	// RegisterTTL specifies TTL for register record
 | 
						|
	RegisterTTL time.Duration
 | 
						|
	// GracefulTimeout timeout for graceful stop server
 | 
						|
	GracefulTimeout time.Duration
 | 
						|
	// MaxConn limits number of connections
 | 
						|
	MaxConn int
 | 
						|
	// DeregisterAttempts holds the number of deregister attempts before error
 | 
						|
	DeregisterAttempts int
 | 
						|
	// RegisterAttempts holds the number of register attempts before error
 | 
						|
	RegisterAttempts int
 | 
						|
}
 | 
						|
 | 
						|
// NewOptions returns new options struct with default or passed values
 | 
						|
func NewOptions(opts ...Option) Options {
 | 
						|
	options := Options{
 | 
						|
		Codecs:           make(map[string]codec.Codec),
 | 
						|
		Context:          context.Background(),
 | 
						|
		Metadata:         metadata.New(0),
 | 
						|
		RegisterInterval: DefaultRegisterInterval,
 | 
						|
		RegisterTTL:      DefaultRegisterTTL,
 | 
						|
		RegisterCheck:    DefaultRegisterCheck,
 | 
						|
		Logger:           logger.DefaultLogger,
 | 
						|
		Meter:            meter.DefaultMeter,
 | 
						|
		Tracer:           tracer.DefaultTracer,
 | 
						|
		Broker:           broker.DefaultBroker,
 | 
						|
		Register:         register.DefaultRegister,
 | 
						|
		Address:          DefaultAddress,
 | 
						|
		Name:             DefaultName,
 | 
						|
		Version:          DefaultVersion,
 | 
						|
		ID:               id.MustNew(),
 | 
						|
		Namespace:        DefaultNamespace,
 | 
						|
		GracefulTimeout:  DefaultGracefulTimeout,
 | 
						|
	}
 | 
						|
 | 
						|
	for _, o := range opts {
 | 
						|
		o(&options)
 | 
						|
	}
 | 
						|
 | 
						|
	return options
 | 
						|
}
 | 
						|
 | 
						|
// Name sets the server name option
 | 
						|
func Name(n string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Name = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Namespace to register handlers in
 | 
						|
func Namespace(n string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Namespace = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Logger sets the logger option
 | 
						|
func Logger(l logger.Logger) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Logger = l
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Meter sets the meter option
 | 
						|
func Meter(m meter.Meter) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Meter = m
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// ID unique server id
 | 
						|
func ID(id string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.ID = id
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Version of the service
 | 
						|
func Version(v string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Version = v
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Address to bind to - host:port
 | 
						|
func Address(a string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Address = a
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Advertise the address to advertise for discovery - host:port
 | 
						|
func Advertise(a string) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Advertise = a
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Broker to use for pub/sub
 | 
						|
func Broker(b broker.Broker) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Broker = b
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Codec to use to encode/decode requests for a given content type
 | 
						|
func Codec(contentType string, c codec.Codec) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Codecs[contentType] = c
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Context specifies a context for the service.
 | 
						|
// Can be used to signal shutdown of the service
 | 
						|
// Can be used for extra option values.
 | 
						|
func Context(ctx context.Context) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Context = ctx
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Register used for discovery
 | 
						|
func Register(r register.Register) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Register = r
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Tracer mechanism for distributed tracking
 | 
						|
func Tracer(t tracer.Tracer) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Tracer = t
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Metadata associated with the server
 | 
						|
func Metadata(md metadata.Metadata) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Metadata = metadata.Copy(md)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RegisterCheck run func before register service
 | 
						|
func RegisterCheck(fn func(context.Context) error) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.RegisterCheck = fn
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RegisterTTL registers service with a TTL
 | 
						|
func RegisterTTL(t time.Duration) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.RegisterTTL = t
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RegisterInterval registers service with at interval
 | 
						|
func RegisterInterval(t time.Duration) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.RegisterInterval = t
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// TLSConfig specifies a *tls.Config
 | 
						|
func TLSConfig(t *tls.Config) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		// set the internal tls
 | 
						|
		o.TLSConfig = t
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
// WithRouter sets the request router
 | 
						|
func WithRouter(r Router) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Router = r
 | 
						|
	}
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
// Wait tells the server to wait for requests to finish before exiting
 | 
						|
// If `wg` is nil, server only wait for completion of rpc handler.
 | 
						|
// For user need finer grained control, pass a concrete `wg` here, server will
 | 
						|
// wait against it on stop.
 | 
						|
func Wait(wg *sync.WaitGroup) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		if wg == nil {
 | 
						|
			wg = new(sync.WaitGroup)
 | 
						|
		}
 | 
						|
		o.Wait = msync.WrapWaitGroup(wg)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// MaxConn specifies maximum number of max simultaneous connections to server
 | 
						|
func MaxConn(n int) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.MaxConn = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Listener specifies the net.Listener to use instead of the default
 | 
						|
func Listener(l net.Listener) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Listener = l
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// HandlerOption func
 | 
						|
type HandlerOption func(*HandlerOptions)
 | 
						|
 | 
						|
// GracefulTimeout duration
 | 
						|
func GracefulTimeout(td time.Duration) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.GracefulTimeout = td
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// HandlerOptions struct
 | 
						|
type HandlerOptions struct {
 | 
						|
	// Context holds external options
 | 
						|
	Context context.Context
 | 
						|
	// Metadata for handler
 | 
						|
	Metadata map[string]metadata.Metadata
 | 
						|
}
 | 
						|
 | 
						|
// NewHandlerOptions creates new HandlerOptions
 | 
						|
func NewHandlerOptions(opts ...HandlerOption) HandlerOptions {
 | 
						|
	options := HandlerOptions{
 | 
						|
		Context:  context.Background(),
 | 
						|
		Metadata: make(map[string]metadata.Metadata),
 | 
						|
	}
 | 
						|
 | 
						|
	for _, o := range opts {
 | 
						|
		o(&options)
 | 
						|
	}
 | 
						|
 | 
						|
	return options
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberOption func
 | 
						|
type SubscriberOption func(*SubscriberOptions)
 | 
						|
 | 
						|
// SubscriberOptions struct
 | 
						|
type SubscriberOptions struct {
 | 
						|
	// Context holds the external options
 | 
						|
	Context context.Context
 | 
						|
	// Queue holds the subscription queue
 | 
						|
	Queue string
 | 
						|
	// BatchWait flag specifies max wait time for batch filling
 | 
						|
	BatchWait time.Duration
 | 
						|
	// BatchSize flag specifies max size of batch
 | 
						|
	BatchSize int
 | 
						|
	// AutoAck flag for auto ack messages after processing
 | 
						|
	AutoAck bool
 | 
						|
	// BodyOnly flag specifies that message without headers
 | 
						|
	BodyOnly bool
 | 
						|
}
 | 
						|
 | 
						|
// NewSubscriberOptions create new SubscriberOptions
 | 
						|
func NewSubscriberOptions(opts ...SubscriberOption) SubscriberOptions {
 | 
						|
	options := SubscriberOptions{
 | 
						|
		AutoAck: true,
 | 
						|
		Context: context.Background(),
 | 
						|
	}
 | 
						|
 | 
						|
	for _, o := range opts {
 | 
						|
		o(&options)
 | 
						|
	}
 | 
						|
 | 
						|
	return options
 | 
						|
}
 | 
						|
 | 
						|
// EndpointMetadata is a Handler option that allows metadata to be added to
 | 
						|
// individual endpoints.
 | 
						|
func EndpointMetadata(name string, md metadata.Metadata) HandlerOption {
 | 
						|
	return func(o *HandlerOptions) {
 | 
						|
		o.Metadata[name] = metadata.Copy(md)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// DisableAutoAck will disable auto acking of messages
 | 
						|
// after they have been handled.
 | 
						|
func DisableAutoAck() SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.AutoAck = false
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberQueue sets the shared queue name distributed messages across subscribers
 | 
						|
func SubscriberQueue(n string) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.Queue = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberGroup sets the shared group name distributed messages across subscribers
 | 
						|
func SubscriberGroup(n string) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.Queue = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberBodyOnly says broker that message contains raw data with absence of micro broker.Message format
 | 
						|
func SubscriberBodyOnly(b bool) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.BodyOnly = b
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberContext set context options to allow broker SubscriberOption passed
 | 
						|
func SubscriberContext(ctx context.Context) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.Context = ctx
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberAck control auto ack processing for handler
 | 
						|
func SubscriberAck(b bool) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.AutoAck = b
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberBatchSize control batch filling size for handler
 | 
						|
// Batch filling max waiting time controlled by SubscriberBatchWait
 | 
						|
func SubscriberBatchSize(n int) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.BatchSize = n
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SubscriberBatchWait control batch filling wait time for handler
 | 
						|
func SubscriberBatchWait(td time.Duration) SubscriberOption {
 | 
						|
	return func(o *SubscriberOptions) {
 | 
						|
		o.BatchWait = td
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Hooks sets hook runs before action
 | 
						|
func Hooks(h ...options.Hook) Option {
 | 
						|
	return func(o *Options) {
 | 
						|
		o.Hooks = append(o.Hooks, h...)
 | 
						|
	}
 | 
						|
}
 |