workflow fix #371

Merged
vtolstov merged 5 commits from workflowfix into v3 2024-12-10 01:40:56 +03:00
67 changed files with 480 additions and 398 deletions
Showing only changes of commit e266683d96 - Show all commits

View File

@ -74,7 +74,7 @@ func TestMemoryBroker(t *testing.T) {
topic := "test" topic := "test"
count := 10 count := 10
fn := func(p broker.Event) error { fn := func(_ broker.Event) error {
return nil return nil
} }

View File

@ -16,6 +16,9 @@ import (
// Options struct // Options struct
type Options struct { type Options struct {
// Name holds the broker name
Name string
// Tracer used for tracing // Tracer used for tracing
Tracer tracer.Tracer Tracer tracer.Tracer
// Register can be used for clustering // Register can be used for clustering
@ -28,23 +31,25 @@ type Options struct {
Meter meter.Meter Meter meter.Meter
// Context holds external options // Context holds external options
Context context.Context Context context.Context
// Wait waits for a collection of goroutines to finish
Wait *sync.WaitGroup
// TLSConfig holds tls.TLSConfig options // TLSConfig holds tls.TLSConfig options
TLSConfig *tls.Config TLSConfig *tls.Config
// ErrorHandler used when broker can't unmarshal incoming message // ErrorHandler used when broker can't unmarshal incoming message
ErrorHandler Handler ErrorHandler Handler
// BatchErrorHandler used when broker can't unmashal incoming messages // BatchErrorHandler used when broker can't unmashal incoming messages
BatchErrorHandler BatchHandler BatchErrorHandler BatchHandler
// Name holds the broker name
Name string
// Addrs holds the broker address // Addrs holds the broker address
Addrs []string Addrs []string
// Wait waits for a collection of goroutines to finish
Wait *sync.WaitGroup
// GracefulTimeout contains time to wait to finish in flight requests
GracefulTimeout time.Duration
// Hooks can be run before broker Publish/BatchPublish and // Hooks can be run before broker Publish/BatchPublish and
// Subscribe/BatchSubscribe methods // Subscribe/BatchSubscribe methods
Hooks options.Hooks Hooks options.Hooks
// GracefulTimeout contains time to wait to finish in flight requests
GracefulTimeout time.Duration
} }
// NewOptions create new Options // NewOptions create new Options

View File

@ -17,13 +17,13 @@ func BackoffExp(_ context.Context, _ Request, attempts int) (time.Duration, erro
} }
// BackoffInterval specifies randomization interval for backoff func // BackoffInterval specifies randomization interval for backoff func
func BackoffInterval(min time.Duration, max time.Duration) BackoffFunc { func BackoffInterval(minTime time.Duration, maxTime time.Duration) BackoffFunc {
return func(_ context.Context, _ Request, attempts int) (time.Duration, error) { return func(_ context.Context, _ Request, attempts int) (time.Duration, error) {
td := time.Duration(math.Pow(float64(attempts), math.E)) * time.Millisecond * 100 td := time.Duration(math.Pow(float64(attempts), math.E)) * time.Millisecond * 100
if td < min { if td < minTime {
return min, nil return minTime, nil
} else if td > max { } else if td > maxTime {
return max, nil return maxTime, nil
} }
return td, nil return td, nil
} }

View File

@ -34,23 +34,23 @@ func TestBackoffExp(t *testing.T) {
} }
func TestBackoffInterval(t *testing.T) { func TestBackoffInterval(t *testing.T) {
min := 100 * time.Millisecond minTime := 100 * time.Millisecond
max := 300 * time.Millisecond maxTime := 300 * time.Millisecond
r := &testRequest{ r := &testRequest{
service: "test", service: "test",
method: "test", method: "test",
} }
fn := BackoffInterval(min, max) fn := BackoffInterval(minTime, maxTime)
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
d, err := fn(context.TODO(), r, i) d, err := fn(context.TODO(), r, i)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if d < min || d > max { if d < minTime || d > maxTime {
t.Fatalf("Expected %v < %v < %v", min, d, max) t.Fatalf("Expected %v < %v < %v", minTime, d, maxTime)
} }
} }
} }

View File

@ -298,7 +298,7 @@ func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, o
// call backoff first. Someone may want an initial start delay // call backoff first. Someone may want an initial start delay
t, err := callOpts.Backoff(ctx, req, i) t, err := callOpts.Backoff(ctx, req, i)
if err != nil { if err != nil {
return errors.InternalServerError("go.micro.client", "%s", err.Error()) return errors.InternalServerError("go.micro.client", "%s", err)
} }
// only sleep if greater than 0 // only sleep if greater than 0
@ -312,7 +312,7 @@ func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, o
// TODO apply any filtering here // TODO apply any filtering here
routes, err = n.opts.Lookup(ctx, req, callOpts) routes, err = n.opts.Lookup(ctx, req, callOpts)
if err != nil { if err != nil {
return errors.InternalServerError("go.micro.client", "%s", err.Error()) return errors.InternalServerError("go.micro.client", "%s", err)
} }
// balance the list of nodes // balance the list of nodes
@ -372,7 +372,7 @@ func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, o
return gerr return gerr
} }
func (n *noopClient) NewRequest(service, endpoint string, req interface{}, opts ...RequestOption) Request { func (n *noopClient) NewRequest(service, endpoint string, _ interface{}, _ ...RequestOption) Request {
return &noopRequest{service: service, endpoint: endpoint} return &noopRequest{service: service, endpoint: endpoint}
} }
@ -466,7 +466,7 @@ func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOpti
// call backoff first. Someone may want an initial start delay // call backoff first. Someone may want an initial start delay
t, cerr := callOpts.Backoff(ctx, req, i) t, cerr := callOpts.Backoff(ctx, req, i)
if cerr != nil { if cerr != nil {
return nil, errors.InternalServerError("go.micro.client", "%s", cerr.Error()) return nil, errors.InternalServerError("go.micro.client", "%s", cerr)
} }
// only sleep if greater than 0 // only sleep if greater than 0
@ -480,7 +480,7 @@ func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOpti
// TODO apply any filtering here // TODO apply any filtering here
routes, err = n.opts.Lookup(ctx, req, callOpts) routes, err = n.opts.Lookup(ctx, req, callOpts)
if err != nil { if err != nil {
return nil, errors.InternalServerError("go.micro.client", "%s", err.Error()) return nil, errors.InternalServerError("go.micro.client", "%s", err)
} }
// balance the list of nodes // balance the list of nodes
@ -546,7 +546,7 @@ func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOpti
return nil, grr return nil, grr
} }
func (n *noopClient) stream(ctx context.Context, addr string, req Request, opts CallOptions) (Stream, error) { func (n *noopClient) stream(ctx context.Context, _ string, _ Request, _ CallOptions) (Stream, error) {
return &noopStream{ctx: ctx}, nil return &noopStream{ctx: ctx}, nil
} }
@ -609,13 +609,13 @@ func (n *noopClient) publish(ctx context.Context, ps []Message, opts ...PublishO
// use codec for payload // use codec for payload
cf, err := n.newCodec(p.ContentType()) cf, err := n.newCodec(p.ContentType())
if err != nil { if err != nil {
return errors.InternalServerError("go.micro.client", "%s", err.Error()) return errors.InternalServerError("go.micro.client", "%s", err)
} }
// set the body // set the body
b, err := cf.Marshal(p.Payload()) b, err := cf.Marshal(p.Payload())
if err != nil { if err != nil {
return errors.InternalServerError("go.micro.client", "%s", err.Error()) return errors.InternalServerError("go.micro.client", "%s", err)
} }
body = b body = b
} }

View File

@ -21,6 +21,16 @@ import (
// Options holds client options // Options holds client options
type Options struct { type Options struct {
// Codecs map
Codecs map[string]codec.Codec
// Proxy is used for proxy requests
Proxy string
// ContentType is used to select codec
ContentType string
// Name is the client name
Name string
// Selector used to select needed address // Selector used to select needed address
Selector selector.Selector Selector selector.Selector
// Logger used to log messages // Logger used to log messages
@ -35,31 +45,28 @@ type Options struct {
Context context.Context Context context.Context
// Router used to get route // Router used to get route
Router router.Router Router router.Router
// TLSConfig specifies tls.Config for secure connection // TLSConfig specifies tls.Config for secure connection
TLSConfig *tls.Config TLSConfig *tls.Config
// Codecs map
Codecs map[string]codec.Codec
// Lookup func used to get destination addr // Lookup func used to get destination addr
Lookup LookupFunc Lookup LookupFunc
// Proxy is used for proxy requests // ContextDialer used to connect
Proxy string ContextDialer func(context.Context, string) (net.Conn, error)
// ContentType is used to select codec
ContentType string
// Name is the client name
Name string
// Wrappers contains wrappers // Wrappers contains wrappers
Wrappers []Wrapper Wrappers []Wrapper
// Hooks can be run before broker Publish/BatchPublish and
// Subscribe/BatchSubscribe methods
Hooks options.Hooks
// CallOptions contains default CallOptions // CallOptions contains default CallOptions
CallOptions CallOptions CallOptions CallOptions
// PoolSize connection pool size // PoolSize connection pool size
PoolSize int PoolSize int
// PoolTTL connection pool ttl // PoolTTL connection pool ttl
PoolTTL time.Duration PoolTTL time.Duration
// ContextDialer used to connect
ContextDialer func(context.Context, string) (net.Conn, error)
// Hooks can be run before broker Publish/BatchPublish and
// Subscribe/BatchSubscribe methods
Hooks options.Hooks
} }
// NewCallOptions creates new call options struct // NewCallOptions creates new call options struct
@ -73,6 +80,16 @@ func NewCallOptions(opts ...CallOption) CallOptions {
// CallOptions holds client call options // CallOptions holds client call options
type CallOptions struct { type CallOptions struct {
// RequestMetadata holds additional metadata for call
RequestMetadata metadata.Metadata
// Network name
Network string
// Content-Type
ContentType string
// AuthToken string
AuthToken string
// Selector selects addr // Selector selects addr
Selector selector.Selector Selector selector.Selector
// Context used for deadline // Context used for deadline
@ -80,33 +97,30 @@ type CallOptions struct {
// Router used for route // Router used for route
Router router.Router Router router.Router
// Retry func used for retries // Retry func used for retries
// ResponseMetadata holds additional metadata from call
ResponseMetadata *metadata.Metadata
Retry RetryFunc Retry RetryFunc
// Backoff func used for backoff when retry // Backoff func used for backoff when retry
Backoff BackoffFunc Backoff BackoffFunc
// Network name // ContextDialer used to connect
Network string ContextDialer func(context.Context, string) (net.Conn, error)
// Content-Type
ContentType string
// AuthToken string
AuthToken string
// Address specifies static addr list // Address specifies static addr list
Address []string Address []string
// SelectOptions selector options // SelectOptions selector options
SelectOptions []selector.SelectOption SelectOptions []selector.SelectOption
// StreamTimeout stream timeout // StreamTimeout stream timeout
StreamTimeout time.Duration StreamTimeout time.Duration
// RequestTimeout request timeout // RequestTimeout request timeout
RequestTimeout time.Duration RequestTimeout time.Duration
// RequestMetadata holds additional metadata for call
RequestMetadata metadata.Metadata
// ResponseMetadata holds additional metadata from call
ResponseMetadata *metadata.Metadata
// DialTimeout dial timeout // DialTimeout dial timeout
DialTimeout time.Duration DialTimeout time.Duration
// Retries specifies retries num // Retries specifies retries num
Retries int Retries int
// ContextDialer used to connect
ContextDialer func(context.Context, string) (net.Conn, error)
} }
// ContextDialer pass ContextDialer to client // ContextDialer pass ContextDialer to client

View File

@ -13,7 +13,7 @@ type Validator interface {
} }
// DefaultConfig default config // DefaultConfig default config
var DefaultConfig Config = NewConfig() var DefaultConfig = NewConfig()
// DefaultWatcherMinInterval default min interval for poll changes // DefaultWatcherMinInterval default min interval for poll changes
var DefaultWatcherMinInterval = 5 * time.Second var DefaultWatcherMinInterval = 5 * time.Second

View File

@ -3,6 +3,7 @@ package config_test
import ( import (
"context" "context"
"fmt" "fmt"
"reflect"
"testing" "testing"
"time" "time"
@ -12,15 +13,17 @@ import (
) )
type cfg struct { type cfg struct {
MapValue map[string]bool `default:"key1=true,key2=false"`
StructValue *cfgStructValue
StringValue string `default:"string_value"` StringValue string `default:"string_value"`
IgnoreValue string `json:"-"` IgnoreValue string `json:"-"`
StructValue *cfgStructValue
IntValue int `default:"99"`
DurationValue time.Duration `default:"10s"`
MDurationValue mtime.Duration `default:"10s"`
MapValue map[string]bool `default:"key1=true,key2=false"`
UUIDValue string `default:"micro:generate uuid"` UUIDValue string `default:"micro:generate uuid"`
IDValue string `default:"micro:generate id"` IDValue string `default:"micro:generate id"`
DurationValue time.Duration `default:"10s"`
MDurationValue mtime.Duration `default:"10s"`
IntValue int `default:"99"`
} }
type cfgStructValue struct { type cfgStructValue struct {
@ -134,3 +137,13 @@ func TestValidate(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
func Test_SizeOf(t *testing.T) {
st := cfg{}
tVal := reflect.TypeOf(st)
for i := 0; i < tVal.NumField(); i++ {
field := tVal.Field(i)
fmt.Printf("Field: %s, Offset: %d, Size: %d\n", field.Name, field.Offset, field.Type.Size())
}
}

View File

@ -41,14 +41,16 @@ type Options struct {
BeforeInit []func(context.Context, Config) error BeforeInit []func(context.Context, Config) error
// AfterInit contains slice of funcs that runs after Init // AfterInit contains slice of funcs that runs after Init
AfterInit []func(context.Context, Config) error AfterInit []func(context.Context, Config) error
// AllowFail flag to allow fail in config source
AllowFail bool
// SkipLoad runs only if condition returns true // SkipLoad runs only if condition returns true
SkipLoad func(context.Context, Config) bool SkipLoad func(context.Context, Config) bool
// SkipSave runs only if condition returns true // SkipSave runs only if condition returns true
SkipSave func(context.Context, Config) bool SkipSave func(context.Context, Config) bool
// Hooks can be run before/after config Save/Load // Hooks can be run before/after config Save/Load
Hooks options.Hooks Hooks options.Hooks
// AllowFail flag to allow fail in config source
AllowFail bool
} }
// Option function signature // Option function signature
@ -278,10 +280,10 @@ func WatchCoalesce(b bool) WatchOption {
} }
// WatchInterval specifies min and max time.Duration for pulling changes // WatchInterval specifies min and max time.Duration for pulling changes
func WatchInterval(min, max time.Duration) WatchOption { func WatchInterval(minTime, maxTime time.Duration) WatchOption {
return func(o *WatchOptions) { return func(o *WatchOptions) {
o.MinInterval = min o.MinInterval = minTime
o.MaxInterval = max o.MaxInterval = maxTime
} }
} }

View File

@ -3,7 +3,6 @@ package errors
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
er "errors"
"fmt" "fmt"
"net/http" "net/http"
"testing" "testing"
@ -43,7 +42,7 @@ func TestFromError(t *testing.T) {
if merr.ID != "go.micro.test" || merr.Code != 404 { if merr.ID != "go.micro.test" || merr.Code != 404 {
t.Fatalf("invalid conversation %v != %v", err, merr) t.Fatalf("invalid conversation %v != %v", err, merr)
} }
err = er.New(err.Error()) err = errors.New(err.Error())
merr = FromError(err) merr = FromError(err)
if merr.ID != "go.micro.test" || merr.Code != 404 { if merr.ID != "go.micro.test" || merr.Code != 404 {
t.Fatalf("invalid conversation %v != %v", err, merr) t.Fatalf("invalid conversation %v != %v", err, merr)
@ -58,7 +57,7 @@ func TestEqual(t *testing.T) {
t.Fatal("errors must be equal") t.Fatal("errors must be equal")
} }
err3 := er.New("my test err") err3 := errors.New("my test err")
if Equal(err1, err3) { if Equal(err1, err3) {
t.Fatal("errors must be not equal") t.Fatal("errors must be not equal")
} }

View File

@ -32,7 +32,7 @@ type fsm struct {
// NewFSM creates a new finite state machine having the specified initial state // NewFSM creates a new finite state machine having the specified initial state
// with specified options // with specified options
func NewFSM(opts ...Option) *fsm { func NewFSM(opts ...Option) FSM {
return &fsm{ return &fsm{
statesMap: map[string]StateFunc{}, statesMap: map[string]StateFunc{},
opts: NewOptions(opts...), opts: NewOptions(opts...),

1
go.mod
View File

@ -14,6 +14,7 @@ require (
golang.org/x/sync v0.3.0 golang.org/x/sync v0.3.0
google.golang.org/grpc v1.57.0 google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.33.0 google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v3 v3.0.1
) )
require ( require (

2
go.sum
View File

@ -74,5 +74,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -7,12 +7,12 @@ type loggerKey struct{}
// MustContext returns logger from passed context or DefaultLogger if empty // MustContext returns logger from passed context or DefaultLogger if empty
func MustContext(ctx context.Context) Logger { func MustContext(ctx context.Context) Logger {
if ctx == nil { if ctx == nil {
return DefaultLogger return DefaultLogger.Clone()
} }
if l, ok := ctx.Value(loggerKey{}).(Logger); ok && l != nil { if l, ok := ctx.Value(loggerKey{}).(Logger); ok && l != nil {
return l return l
} }
return DefaultLogger return DefaultLogger.Clone()
} }
// FromContext returns logger from passed context // FromContext returns logger from passed context

View File

@ -11,7 +11,7 @@ var DefaultContextAttrFuncs []ContextAttrFunc
var ( var (
// DefaultLogger variable // DefaultLogger variable
DefaultLogger Logger = NewLogger() DefaultLogger = NewLogger()
// DefaultLevel used by logger // DefaultLevel used by logger
DefaultLevel = InfoLevel DefaultLevel = InfoLevel
) )

View File

@ -15,18 +15,6 @@ type Option func(*Options)
// Options holds logger options // Options holds logger options
type Options struct { type Options struct {
// Out holds the output writer
Out io.Writer
// Context holds exernal options
Context context.Context
// Name holds the logger name
Name string
// Fields holds additional metadata
Fields []interface{}
// callerSkipCount number of frmaes to skip
CallerSkipCount int
// ContextAttrFuncs contains funcs that executed before log func on context
ContextAttrFuncs []ContextAttrFunc
// TimeKey is the key used for the time of the log call // TimeKey is the key used for the time of the log call
TimeKey string TimeKey string
// LevelKey is the key used for the level of the log call // LevelKey is the key used for the level of the log call
@ -39,16 +27,31 @@ type Options struct {
SourceKey string SourceKey string
// StacktraceKey is the key used for the stacktrace // StacktraceKey is the key used for the stacktrace
StacktraceKey string StacktraceKey string
// AddStacktrace controls writing of stacktaces on error // Name holds the logger name
AddStacktrace bool Name string
// AddSource enabled writing source file and position in log
AddSource bool // Out holds the output writer
// The logging level the logger should log Out io.Writer
Level Level // Context holds exernal options
// TimeFunc used to obtain current time Context context.Context
TimeFunc func() time.Time
// Meter used to count logs for specific level // Meter used to count logs for specific level
Meter meter.Meter Meter meter.Meter
// TimeFunc used to obtain current time
TimeFunc func() time.Time
// Fields holds additional metadata
Fields []interface{}
// ContextAttrFuncs contains funcs that executed before log func on context
ContextAttrFuncs []ContextAttrFunc
// callerSkipCount number of frmaes to skip
CallerSkipCount int
// The logging level the logger should log
Level Level
// AddSource enabled writing source file and position in log
AddSource bool
// AddStacktrace controls writing of stacktaces on error
AddStacktrace bool
} }
// NewOptions creates new options struct // NewOptions creates new options struct
@ -153,8 +156,8 @@ func WithTimeFunc(fn func() time.Time) Option {
func WithZapKeys() Option { func WithZapKeys() Option {
return func(o *Options) { return func(o *Options) {
o.TimeKey = "@timestamp" o.TimeKey = "@timestamp"
o.LevelKey = "level" o.LevelKey = slog.LevelKey
o.MessageKey = "msg" o.MessageKey = slog.MessageKey
o.SourceKey = "caller" o.SourceKey = "caller"
o.StacktraceKey = "stacktrace" o.StacktraceKey = "stacktrace"
o.ErrorKey = "error" o.ErrorKey = "error"
@ -163,8 +166,8 @@ func WithZapKeys() Option {
func WithZerologKeys() Option { func WithZerologKeys() Option {
return func(o *Options) { return func(o *Options) {
o.TimeKey = "time" o.TimeKey = slog.TimeKey
o.LevelKey = "level" o.LevelKey = slog.LevelKey
o.MessageKey = "message" o.MessageKey = "message"
o.SourceKey = "caller" o.SourceKey = "caller"
o.StacktraceKey = "stacktrace" o.StacktraceKey = "stacktrace"
@ -186,8 +189,8 @@ func WithSlogKeys() Option {
func WithMicroKeys() Option { func WithMicroKeys() Option {
return func(o *Options) { return func(o *Options) {
o.TimeKey = "timestamp" o.TimeKey = "timestamp"
o.LevelKey = "level" o.LevelKey = slog.LevelKey
o.MessageKey = "msg" o.MessageKey = slog.MessageKey
o.SourceKey = "caller" o.SourceKey = "caller"
o.StacktraceKey = "stacktrace" o.StacktraceKey = "stacktrace"
o.ErrorKey = "error" o.ErrorKey = "error"

View File

@ -340,7 +340,7 @@ func (s *slogLogger) argsAttrs(args []interface{}) ([]slog.Attr, error) {
case string: case string:
if idx+1 < len(args) { if idx+1 < len(args) {
attrs = append(attrs, slog.Any(arg, args[idx+1])) attrs = append(attrs, slog.Any(arg, args[idx+1]))
idx += 1 idx++
} else { } else {
attrs = append(attrs, slog.String(badKey, arg)) attrs = append(attrs, slog.String(badKey, arg))
} }

View File

@ -11,9 +11,8 @@ import (
"testing" "testing"
"github.com/google/uuid" "github.com/google/uuid"
"go.unistack.org/micro/v3/metadata"
"go.unistack.org/micro/v3/logger" "go.unistack.org/micro/v3/logger"
"go.unistack.org/micro/v3/metadata"
) )
func TestWithHandlerFunc(t *testing.T) { func TestWithHandlerFunc(t *testing.T) {
@ -133,7 +132,7 @@ func TestErrorf(t *testing.T) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), logger.WithAddStacktrace(true)) l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), logger.WithAddStacktrace(true))
if err := l.Init(logger.WithContextAttrFuncs(func(ctx context.Context) []interface{} { if err := l.Init(logger.WithContextAttrFuncs(func(_ context.Context) []interface{} {
return nil return nil
})); err != nil { })); err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -52,13 +52,15 @@ type protoMessage interface {
} }
type Wrapper struct { type Wrapper struct {
pointers map[uintptr]int
takeMap map[int]bool
val interface{} val interface{}
s fmt.State s fmt.State
pointers map[uintptr]int
opts *Options opts *Options
depth int depth int
ignoreNextType bool ignoreNextType bool
takeMap map[int]bool
protoWrapperType bool protoWrapperType bool
sqlWrapperType bool sqlWrapperType bool
} }

View File

@ -88,15 +88,14 @@ func TestPassing(t *testing.T) {
ctx = NewIncomingContext(ctx, md1) ctx = NewIncomingContext(ctx, md1)
testCtx(ctx) testCtx(ctx)
md, ok := FromOutgoingContext(ctx) _, ok := FromOutgoingContext(ctx)
if ok { if ok {
t.Fatalf("create outgoing context") t.Fatalf("create outgoing context")
} }
_ = md
ctx = NewOutgoingContext(ctx, New(1)) ctx = NewOutgoingContext(ctx, New(1))
testCtx(ctx) testCtx(ctx)
md, ok = FromOutgoingContext(ctx) md, ok := FromOutgoingContext(ctx)
if !ok { if !ok {
t.Fatalf("missing metadata from outgoing context") t.Fatalf("missing metadata from outgoing context")
} }
@ -119,7 +118,7 @@ func TestMerge(t *testing.T) {
} }
} }
func TestIterator(t *testing.T) { func TestIterator(_ *testing.T) {
md := Metadata{ md := Metadata{
"1Last": "last", "1Last": "last",
"2First": "first", "2First": "first",

View File

@ -11,7 +11,7 @@ import (
var ( var (
// DefaultMeter is the default meter // DefaultMeter is the default meter
DefaultMeter Meter = NewMeter() DefaultMeter = NewMeter()
// DefaultAddress data will be made available on this host:port // DefaultAddress data will be made available on this host:port
DefaultAddress = ":9090" DefaultAddress = ":9090"
// DefaultPath the meter endpoint where the Meter data will be made available // DefaultPath the meter endpoint where the Meter data will be made available

View File

@ -37,32 +37,32 @@ func (r *noopMeter) Init(opts ...Option) error {
} }
// Counter implements the Meter interface // Counter implements the Meter interface
func (r *noopMeter) Counter(name string, labels ...string) Counter { func (r *noopMeter) Counter(_ string, labels ...string) Counter {
return &noopCounter{labels: labels} return &noopCounter{labels: labels}
} }
// FloatCounter implements the Meter interface // FloatCounter implements the Meter interface
func (r *noopMeter) FloatCounter(name string, labels ...string) FloatCounter { func (r *noopMeter) FloatCounter(_ string, labels ...string) FloatCounter {
return &noopFloatCounter{labels: labels} return &noopFloatCounter{labels: labels}
} }
// Gauge implements the Meter interface // Gauge implements the Meter interface
func (r *noopMeter) Gauge(name string, f func() float64, labels ...string) Gauge { func (r *noopMeter) Gauge(_ string, _ func() float64, labels ...string) Gauge {
return &noopGauge{labels: labels} return &noopGauge{labels: labels}
} }
// Summary implements the Meter interface // Summary implements the Meter interface
func (r *noopMeter) Summary(name string, labels ...string) Summary { func (r *noopMeter) Summary(_ string, labels ...string) Summary {
return &noopSummary{labels: labels} return &noopSummary{labels: labels}
} }
// SummaryExt implements the Meter interface // SummaryExt implements the Meter interface
func (r *noopMeter) SummaryExt(name string, window time.Duration, quantiles []float64, labels ...string) Summary { func (r *noopMeter) SummaryExt(_ string, _ time.Duration, _ []float64, labels ...string) Summary {
return &noopSummary{labels: labels} return &noopSummary{labels: labels}
} }
// Histogram implements the Meter interface // Histogram implements the Meter interface
func (r *noopMeter) Histogram(name string, labels ...string) Histogram { func (r *noopMeter) Histogram(_ string, labels ...string) Histogram {
return &noopHistogram{labels: labels} return &noopHistogram{labels: labels}
} }
@ -77,7 +77,7 @@ func (r *noopMeter) Set(opts ...Option) Meter {
return m return m
} }
func (r *noopMeter) Write(w io.Writer, opts ...Option) error { func (r *noopMeter) Write(_ io.Writer, _ ...Option) error {
return nil return nil
} }

View File

@ -18,26 +18,27 @@ func TestAs(t *testing.T) {
testCases := []struct { testCases := []struct {
b any b any
target any target any
match bool
want any want any
match bool
}{ }{
{ {
broTarget, b: broTarget,
&b, target: &b,
true, match: true,
broTarget, want: broTarget,
}, },
{ {
nil, b: nil,
&b, target: &b,
false, match: false,
nil, want: nil,
}, },
{ {
fsmTarget, b: fsmTarget,
&b, target: &b,
false, match: false,
nil, want: nil,
}, },
} }
for i, tc := range testCases { for i, tc := range testCases {
@ -72,7 +73,7 @@ func (p *bro) Ready() bool { return true }
func (p *bro) Health() bool { return true } func (p *bro) Health() bool { return true }
func (p *bro) Init(opts ...broker.Option) error { return nil } func (p *bro) Init(_ ...broker.Option) error { return nil }
// Options returns broker options // Options returns broker options
func (p *bro) Options() broker.Options { return broker.Options{} } func (p *bro) Options() broker.Options { return broker.Options{} }
@ -81,28 +82,28 @@ func (p *bro) Options() broker.Options { return broker.Options{} }
func (p *bro) Address() string { return "" } func (p *bro) Address() string { return "" }
// Connect connects to broker // Connect connects to broker
func (p *bro) Connect(ctx context.Context) error { return nil } func (p *bro) Connect(_ context.Context) error { return nil }
// Disconnect disconnect from broker // Disconnect disconnect from broker
func (p *bro) Disconnect(ctx context.Context) error { return nil } func (p *bro) Disconnect(_ context.Context) error { return nil }
// Publish message, msg can be single broker.Message or []broker.Message // Publish message, msg can be single broker.Message or []broker.Message
func (p *bro) Publish(ctx context.Context, topic string, msg *broker.Message, opts ...broker.PublishOption) error { func (p *bro) Publish(_ context.Context, _ string, _ *broker.Message, _ ...broker.PublishOption) error {
return nil return nil
} }
// BatchPublish messages to broker with multiple topics // BatchPublish messages to broker with multiple topics
func (p *bro) BatchPublish(ctx context.Context, msgs []*broker.Message, opts ...broker.PublishOption) error { func (p *bro) BatchPublish(_ context.Context, _ []*broker.Message, _ ...broker.PublishOption) error {
return nil return nil
} }
// BatchSubscribe subscribes to topic messages via handler // BatchSubscribe subscribes to topic messages via handler
func (p *bro) BatchSubscribe(ctx context.Context, topic string, h broker.BatchHandler, opts ...broker.SubscribeOption) (broker.Subscriber, error) { func (p *bro) BatchSubscribe(_ context.Context, _ string, _ broker.BatchHandler, _ ...broker.SubscribeOption) (broker.Subscriber, error) {
return nil, nil return nil, nil
} }
// Subscribe subscribes to topic message via handler // Subscribe subscribes to topic message via handler
func (p *bro) Subscribe(ctx context.Context, topic string, handler broker.Handler, opts ...broker.SubscribeOption) (broker.Subscriber, error) { func (p *bro) Subscribe(_ context.Context, _ string, _ broker.Handler, _ ...broker.SubscribeOption) (broker.Subscriber, error) {
return nil, nil return nil, nil
} }
@ -113,9 +114,9 @@ type fsmT struct {
name string name string
} }
func (f *fsmT) Start(ctx context.Context, a interface{}, o ...Option) (interface{}, error) { func (f *fsmT) Start(_ context.Context, _ interface{}, _ ...Option) (interface{}, error) {
return nil, nil return nil, nil
} }
func (f *fsmT) Current() string { return f.name } func (f *fsmT) Current() string { return f.name }
func (f *fsmT) Reset() {} func (f *fsmT) Reset() {}
func (f *fsmT) State(s string, sf fsm.StateFunc) {} func (f *fsmT) State(_ string, _ fsm.StateFunc) {}

View File

@ -8,17 +8,18 @@ import (
// CertificateOptions holds options for x509.CreateCertificate // CertificateOptions holds options for x509.CreateCertificate
type CertificateOptions struct { type CertificateOptions struct {
Organization []string
OrganizationalUnit []string
CommonName string
OCSPServer []string
IssuingCertificateURL []string
SerialNumber *big.Int SerialNumber *big.Int
NotAfter time.Time NotAfter time.Time
NotBefore time.Time NotBefore time.Time
CommonName string
Organization []string
OrganizationalUnit []string
OCSPServer []string
IssuingCertificateURL []string
ExtKeyUsage []x509.ExtKeyUsage
SignatureAlgorithm x509.SignatureAlgorithm SignatureAlgorithm x509.SignatureAlgorithm
PublicKeyAlgorithm x509.PublicKeyAlgorithm PublicKeyAlgorithm x509.PublicKeyAlgorithm
ExtKeyUsage []x509.ExtKeyUsage
KeyUsage x509.KeyUsage KeyUsage x509.KeyUsage
IsCA bool IsCA bool
} }

View File

@ -10,7 +10,7 @@ import (
var ( var (
// DefaultTransport is the global default transport // DefaultTransport is the global default transport
DefaultTransport Transport = NewTransport() DefaultTransport = NewTransport()
// DefaultDialTimeout the default dial timeout // DefaultDialTimeout the default dial timeout
DefaultDialTimeout = time.Second * 5 DefaultDialTimeout = time.Second * 5
) )

View File

@ -84,7 +84,7 @@ func (t *tunBroker) Disconnect(ctx context.Context) error {
return t.tunnel.Close(ctx) return t.tunnel.Close(ctx)
} }
func (t *tunBroker) BatchPublish(ctx context.Context, msgs []*broker.Message, opts ...broker.PublishOption) error { func (t *tunBroker) BatchPublish(ctx context.Context, msgs []*broker.Message, _ ...broker.PublishOption) error {
// TODO: this is probably inefficient, we might want to just maintain an open connection // TODO: this is probably inefficient, we might want to just maintain an open connection
// it may be easier to add broadcast to the tunnel // it may be easier to add broadcast to the tunnel
topicMap := make(map[string]tunnel.Session) topicMap := make(map[string]tunnel.Session)
@ -114,7 +114,7 @@ func (t *tunBroker) BatchPublish(ctx context.Context, msgs []*broker.Message, op
return nil return nil
} }
func (t *tunBroker) Publish(ctx context.Context, topic string, m *broker.Message, opts ...broker.PublishOption) error { func (t *tunBroker) Publish(ctx context.Context, topic string, m *broker.Message, _ ...broker.PublishOption) error {
// TODO: this is probably inefficient, we might want to just maintain an open connection // TODO: this is probably inefficient, we might want to just maintain an open connection
// it may be easier to add broadcast to the tunnel // it may be easier to add broadcast to the tunnel
c, err := t.tunnel.Dial(ctx, topic, tunnel.DialMode(tunnel.Multicast)) c, err := t.tunnel.Dial(ctx, topic, tunnel.DialMode(tunnel.Multicast))

View File

@ -15,6 +15,6 @@ func (p *noopProfiler) String() string {
} }
// NewProfiler returns new noop profiler // NewProfiler returns new noop profiler
func NewProfiler(opts ...Option) Profiler { func NewProfiler(_ ...Option) Profiler {
return &noopProfiler{} return &noopProfiler{}
} }

View File

@ -12,7 +12,7 @@ type Profiler interface {
} }
// DefaultProfiler holds the default profiler // DefaultProfiler holds the default profiler
var DefaultProfiler Profiler = NewProfiler() var DefaultProfiler = NewProfiler()
// Options holds the options for profiler // Options holds the options for profiler
type Options struct { type Options struct {

View File

@ -31,10 +31,10 @@ type record struct {
} }
type memory struct { type memory struct {
sync.RWMutex
records map[string]services records map[string]services
watchers map[string]*watcher watchers map[string]*watcher
opts register.Options opts register.Options
sync.RWMutex
} }
// services is a KV map with service name as the key and a map of records as the value // services is a KV map with service name as the key and a map of records as the value
@ -100,11 +100,11 @@ func (m *memory) sendEvent(r *register.Result) {
} }
} }
func (m *memory) Connect(ctx context.Context) error { func (m *memory) Connect(_ context.Context) error {
return nil return nil
} }
func (m *memory) Disconnect(ctx context.Context) error { func (m *memory) Disconnect(_ context.Context) error {
return nil return nil
} }
@ -124,7 +124,7 @@ func (m *memory) Options() register.Options {
return m.opts return m.opts
} }
func (m *memory) Register(ctx context.Context, s *register.Service, opts ...register.RegisterOption) error { func (m *memory) Register(_ context.Context, s *register.Service, opts ...register.RegisterOption) error {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()

View File

@ -208,9 +208,9 @@ func TestMemoryRegistryTTLConcurrent(t *testing.T) {
} }
} }
//if len(os.Getenv("IN_TRAVIS_CI")) == 0 { // if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
// t.Logf("test will wait %v, then check TTL timeouts", waitTime) // t.Logf("test will wait %v, then check TTL timeouts", waitTime)
//} // }
errChan := make(chan error, concurrency) errChan := make(chan error, concurrency)
syncChan := make(chan struct{}) syncChan := make(chan struct{})
@ -290,8 +290,12 @@ func TestWatcher(t *testing.T) {
ctx := context.TODO() ctx := context.TODO()
m := NewRegister() m := NewRegister()
_ = m.Init() if err := m.Init(); err != nil {
_ = m.Connect(ctx) t.Fatal(err)
}
if err := m.Connect(ctx); err != nil {
t.Fatal(err)
}
wc, err := m.Watch(ctx) wc, err := m.Watch(ctx)
if err != nil { if err != nil {
t.Fatalf("cant watch: %v", err) t.Fatalf("cant watch: %v", err)

View File

@ -18,7 +18,7 @@ var DefaultDomain = "micro"
var ( var (
// DefaultRegister is the global default register // DefaultRegister is the global default register
DefaultRegister Register = NewRegister() DefaultRegister = NewRegister()
// ErrNotFound returned when LookupService is called and no services found // ErrNotFound returned when LookupService is called and no services found
ErrNotFound = errors.New("service not found") ErrNotFound = errors.New("service not found")
// ErrWatcherStopped returned when when watcher is stopped // ErrWatcherStopped returned when when watcher is stopped

View File

@ -9,6 +9,6 @@ import (
type Resolver struct{} type Resolver struct{}
// Resolve returns the list of nodes // Resolve returns the list of nodes
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) { func (r *Resolver) Resolve(_ string) ([]*resolver.Record, error) {
return []*resolver.Record{}, nil return []*resolver.Record{}, nil
} }

View File

@ -7,7 +7,7 @@ import (
var ( var (
// DefaultRouter is the global default router // DefaultRouter is the global default router
DefaultRouter Router = NewRouter() DefaultRouter = NewRouter()
// DefaultNetwork is default micro network // DefaultNetwork is default micro network
DefaultNetwork = "micro" DefaultNetwork = "micro"
// ErrRouteNotFound is returned when no route was found in the routing table // ErrRouteNotFound is returned when no route was found in the routing table

View File

@ -25,7 +25,7 @@ func (r *random) Select(routes []string, opts ...selector.SelectOption) (selecto
}, nil }, nil
} }
func (r *random) Record(addr string, err error) error { func (r *random) Record(_ string, _ error) error {
return nil return nil
} }

View File

@ -6,14 +6,14 @@ import (
) )
// NewSelector returns an initialised round robin selector // NewSelector returns an initialised round robin selector
func NewSelector(opts ...selector.Option) selector.Selector { func NewSelector(_ ...selector.Option) selector.Selector {
return new(roundrobin) return new(roundrobin)
} }
type roundrobin struct{} type roundrobin struct{}
// Select return routes based on algo // Select return routes based on algo
func (r *roundrobin) Select(routes []string, opts ...selector.SelectOption) (selector.Next, error) { func (r *roundrobin) Select(routes []string, _ ...selector.SelectOption) (selector.Next, error) {
if len(routes) == 0 { if len(routes) == 0 {
return nil, selector.ErrNoneAvailable return nil, selector.ErrNoneAvailable
} }
@ -28,7 +28,7 @@ func (r *roundrobin) Select(routes []string, opts ...selector.SelectOption) (sel
}, nil }, nil
} }
func (r *roundrobin) Record(addr string, err error) error { return nil } func (r *roundrobin) Record(_ string, _ error) error { return nil }
func (r *roundrobin) Reset() error { return nil } func (r *roundrobin) Reset() error { return nil }

View File

@ -775,13 +775,16 @@ func (s *subscriber) Options() SubscriberOptions {
} }
type subscriber struct { type subscriber struct {
topic string
typ reflect.Type typ reflect.Type
subscriber interface{} subscriber interface{}
topic string
endpoints []*register.Endpoint endpoints []*register.Endpoint
handlers []*handler handlers []*handler
opts SubscriberOptions
rcvr reflect.Value rcvr reflect.Value
opts SubscriberOptions
} }
type handler struct { type handler struct {

View File

@ -38,7 +38,9 @@ func TestNoopSub(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
_ = logger.DefaultLogger.Init(logger.WithLevel(logger.ErrorLevel)) if err := logger.DefaultLogger.Init(logger.WithLevel(logger.ErrorLevel)); err != nil {
t.Fatal(err)
}
s := server.NewServer( s := server.NewServer(
server.Broker(b), server.Broker(b),
server.Codec("application/octet-stream", codec.NewCodec()), server.Codec("application/octet-stream", codec.NewCodec()),

View File

@ -24,36 +24,11 @@ type Option func(*Options)
// Options server struct // Options server struct
type Options struct { type Options struct {
// 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
/*
// Router for requests
Router Router
*/
// Listener may be passed if already created
Listener net.Listener
// Wait group
Wait *msync.WaitGroup
// TLSConfig specifies tls.Config for secure serving
TLSConfig *tls.Config
// Metadata holds the server metadata
Metadata metadata.Metadata
// RegisterCheck run before register server
RegisterCheck func(context.Context) error
// Codecs map to handle content-type // Codecs map to handle content-type
Codecs map[string]codec.Codec Codecs map[string]codec.Codec
// Metadata holds the server metadata
Metadata metadata.Metadata
// ID holds the id of the server // ID holds the id of the server
ID string ID string
// Namespace for te server // Namespace for te server
@ -66,21 +41,46 @@ type Options struct {
Advertise string Advertise string
// Version holds the server version // Version holds the server version
Version string Version string
// RegisterAttempts holds the number of register attempts before error
RegisterAttempts int // 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 holds he interval for re-register
RegisterInterval time.Duration RegisterInterval time.Duration
// RegisterTTL specifies TTL for register record // RegisterTTL specifies TTL for register record
RegisterTTL time.Duration RegisterTTL time.Duration
// GracefulTimeout timeout for graceful stop server
GracefulTimeout time.Duration
// MaxConn limits number of connections // MaxConn limits number of connections
MaxConn int MaxConn int
// DeregisterAttempts holds the number of deregister attempts before error // DeregisterAttempts holds the number of deregister attempts before error
DeregisterAttempts int DeregisterAttempts int
// Hooks may contains hook actions that performs before/after server handler // RegisterAttempts holds the number of register attempts before error
// or server subscriber handler RegisterAttempts int
Hooks options.Hooks
// GracefulTimeout timeout for graceful stop server
GracefulTimeout time.Duration
} }
// NewOptions returns new options struct with default or passed values // NewOptions returns new options struct with default or passed values
@ -318,14 +318,14 @@ type SubscriberOptions struct {
Context context.Context Context context.Context
// Queue holds the subscription queue // Queue holds the subscription queue
Queue string 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 flag for auto ack messages after processing
AutoAck bool AutoAck bool
// BodyOnly flag specifies that message without headers // BodyOnly flag specifies that message without headers
BodyOnly bool BodyOnly bool
// BatchSize flag specifies max size of batch
BatchSize int
// BatchWait flag specifies max wait time for batch filling
BatchWait time.Duration
} }
// NewSubscriberOptions create new SubscriberOptions // NewSubscriberOptions create new SubscriberOptions

View File

@ -12,7 +12,7 @@ import (
// DefaultServer default server // DefaultServer default server
var ( var (
DefaultServer Server = NewServer() DefaultServer = NewServer()
) )
var ( var (

View File

@ -121,8 +121,10 @@ func TestNewService(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
args args
want Service want Service
args args
}{ }{
{ {
name: "NewService", name: "NewService",
@ -147,8 +149,9 @@ func Test_service_Name(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
fields fields
want string want string
fields fields
}{ }{
{ {
name: "Test_service_Name", name: "Test_service_Name",
@ -246,9 +249,11 @@ func Test_service_Broker(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want broker.Broker
fields fields fields fields
args args args args
want broker.Broker
}{ }{
{ {
name: "service.Broker", name: "service.Broker",
@ -302,9 +307,11 @@ func Test_service_Tracer(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want tracer.Tracer
fields fields fields fields
args args args args
want tracer.Tracer
}{ }{
{ {
name: "service.Tracer", name: "service.Tracer",
@ -339,9 +346,10 @@ func Test_service_Config(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want config.Config
fields fields fields fields
args args args args
want config.Config
}{ }{
{ {
name: "service.Config", name: "service.Config",
@ -376,9 +384,11 @@ func Test_service_Client(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want client.Client
fields fields fields fields
args args args args
want client.Client
}{ }{
{ {
name: "service.Client", name: "service.Client",
@ -413,9 +423,11 @@ func Test_service_Server(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want server.Server
fields fields fields fields
args args args args
want server.Server
}{ }{
{ {
name: "service.Server", name: "service.Server",
@ -450,9 +462,11 @@ func Test_service_Store(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want store.Store
fields fields fields fields
args args args args
want store.Store
}{ }{
{ {
name: "service.Store", name: "service.Store",
@ -487,9 +501,11 @@ func Test_service_Register(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want register.Register
fields fields fields fields
args args args args
want register.Register
}{ }{
{ {
name: "service.Register", name: "service.Register",
@ -524,9 +540,11 @@ func Test_service_Logger(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want logger.Logger
fields fields fields fields
args args args args
want logger.Logger
}{ }{
{ {
name: "service.Logger", name: "service.Logger",
@ -561,9 +579,11 @@ func Test_service_Router(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want router.Router
fields fields fields fields
args args args args
want router.Router
}{ }{
{ {
name: "service.Router", name: "service.Router",
@ -598,9 +618,11 @@ func Test_service_Meter(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
want meter.Meter
fields fields fields fields
args args args args
want meter.Meter
}{ }{
{ {
name: "service.Meter", name: "service.Meter",
@ -631,8 +653,8 @@ func Test_service_String(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
fields fields
want string want string
fields fields
}{ }{
{ {
name: "service.String", name: "service.String",

View File

@ -96,15 +96,15 @@ func (m *memoryStore) list(prefix string, limit, offset uint) []string {
if limit != 0 || offset != 0 { if limit != 0 || offset != 0 {
sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] }) sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] })
sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] }) sort.Slice(allKeys, func(i, j int) bool { return allKeys[i] < allKeys[j] })
end := len(allKeys) end := uint(len(allKeys))
if limit > 0 { if limit > 0 {
calcLimit := int(offset + limit) calcLimit := offset + limit
if calcLimit < end { if calcLimit < end {
end = calcLimit end = calcLimit
} }
} }
if int(offset) >= end { if offset >= end {
return nil return nil
} }
return allKeys[offset:end] return allKeys[offset:end]

View File

@ -12,15 +12,18 @@ import (
var _ Store = (*noopStore)(nil) var _ Store = (*noopStore)(nil)
type noopStore struct { type noopStore struct {
mu sync.Mutex
watchers map[string]Watcher watchers map[string]Watcher
funcRead FuncRead funcRead FuncRead
funcWrite FuncWrite funcWrite FuncWrite
funcExists FuncExists funcExists FuncExists
funcList FuncList funcList FuncList
funcDelete FuncDelete funcDelete FuncDelete
opts Options opts Options
isConnected atomic.Int32 isConnected atomic.Int32
mu sync.Mutex
} }
func (n *noopStore) Live() bool { func (n *noopStore) Live() bool {
@ -35,7 +38,7 @@ func (n *noopStore) Health() bool {
return true return true
} }
func NewStore(opts ...Option) *noopStore { func NewStore(opts ...Option) Store {
options := NewOptions(opts...) options := NewOptions(opts...)
return &noopStore{opts: options} return &noopStore{opts: options}
} }
@ -94,7 +97,7 @@ func (n *noopStore) Read(ctx context.Context, key string, val interface{}, opts
return n.funcRead(ctx, key, val, opts...) return n.funcRead(ctx, key, val, opts...)
} }
func (n *noopStore) fnRead(ctx context.Context, key string, val interface{}, opts ...ReadOption) error { func (n *noopStore) fnRead(ctx context.Context, _ string, _ interface{}, _ ...ReadOption) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@ -112,7 +115,7 @@ func (n *noopStore) Delete(ctx context.Context, key string, opts ...DeleteOption
return n.funcDelete(ctx, key, opts...) return n.funcDelete(ctx, key, opts...)
} }
func (n *noopStore) fnDelete(ctx context.Context, key string, opts ...DeleteOption) error { func (n *noopStore) fnDelete(ctx context.Context, _ string, _ ...DeleteOption) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@ -130,7 +133,7 @@ func (n *noopStore) Exists(ctx context.Context, key string, opts ...ExistsOption
return n.funcExists(ctx, key, opts...) return n.funcExists(ctx, key, opts...)
} }
func (n *noopStore) fnExists(ctx context.Context, key string, opts ...ExistsOption) error { func (n *noopStore) fnExists(ctx context.Context, _ string, _ ...ExistsOption) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@ -148,7 +151,7 @@ func (n *noopStore) Write(ctx context.Context, key string, val interface{}, opts
return n.funcWrite(ctx, key, val, opts...) return n.funcWrite(ctx, key, val, opts...)
} }
func (n *noopStore) fnWrite(ctx context.Context, key string, val interface{}, opts ...WriteOption) error { func (n *noopStore) fnWrite(ctx context.Context, _ string, _ interface{}, _ ...WriteOption) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
@ -200,13 +203,13 @@ func (n *noopStore) connect(ctx context.Context) error {
} }
type watcher struct { type watcher struct {
opts WatchOptions
ch chan Event
exit chan bool exit chan bool
id string id string
ch chan Event
opts WatchOptions
} }
func (m *noopStore) Watch(ctx context.Context, opts ...WatchOption) (Watcher, error) { func (n *noopStore) Watch(_ context.Context, opts ...WatchOption) (Watcher, error) {
id, err := id.New() id, err := id.New()
if err != nil { if err != nil {
return nil, err return nil, err
@ -223,9 +226,9 @@ func (m *noopStore) Watch(ctx context.Context, opts ...WatchOption) (Watcher, er
opts: wo, opts: wo,
} }
m.mu.Lock() n.mu.Lock()
m.watchers[w.id] = w n.watchers[w.id] = w
m.mu.Unlock() n.mu.Unlock()
return w, nil return w, nil
} }

View File

@ -15,6 +15,13 @@ import (
// Options contains configuration for the Store // Options contains configuration for the Store
type Options struct { type Options struct {
// Name specifies store name
Name string
// Namespace of the records
Namespace string
// Separator used as key parts separator
Separator string
// Meter used for metrics // Meter used for metrics
Meter meter.Meter Meter meter.Meter
// Tracer used for tracing // Tracer used for tracing
@ -25,22 +32,17 @@ type Options struct {
Codec codec.Codec Codec codec.Codec
// Logger used for logging // Logger used for logging
Logger logger.Logger Logger logger.Logger
// TLSConfig holds tls.TLSConfig options // TLSConfig holds tls.TLSConfig options
TLSConfig *tls.Config TLSConfig *tls.Config
// Name specifies store name
Name string
// Namespace of the records
Namespace string
// Separator used as key parts separator
Separator string
// Addrs contains store address // Addrs contains store address
Addrs []string Addrs []string
// Wrappers store wrapper that called before actual functions
// Wrappers []Wrapper
// Timeout specifies timeout duration for all operations
Timeout time.Duration
// Hooks can be run before/after store Read/List/Write/Exists/Delete // Hooks can be run before/after store Read/List/Write/Exists/Delete
Hooks options.Hooks Hooks options.Hooks
// Timeout specifies timeout duration for all operations
Timeout time.Duration
// LazyConnect creates a connection when using store // LazyConnect creates a connection when using store
LazyConnect bool LazyConnect bool
} }

View File

@ -16,7 +16,7 @@ var (
// ErrInvalidKey is returned when a key has empty or have invalid format // ErrInvalidKey is returned when a key has empty or have invalid format
ErrInvalidKey = errors.New("invalid key") ErrInvalidKey = errors.New("invalid key")
// DefaultStore is the global default store // DefaultStore is the global default store
DefaultStore Store = NewStore() DefaultStore = NewStore()
// DefaultSeparator is the gloabal default key parts separator // DefaultSeparator is the gloabal default key parts separator
DefaultSeparator = "/" DefaultSeparator = "/"
) )

View File

@ -6,9 +6,10 @@ import (
) )
type memorySync struct { type memorySync struct {
mtx gosync.RWMutex
locks map[string]*memoryLock locks map[string]*memoryLock
options Options options Options
mtx gosync.RWMutex
} }
type memoryLock struct { type memoryLock struct {

View File

@ -43,7 +43,7 @@ func NewNetDialer(parent DialFunc, opts ...Option) DialFunc {
if cache.opts.MaxCacheEntries == 0 { if cache.opts.MaxCacheEntries == 0 {
cache.opts.MaxCacheEntries = DefaultMaxCacheEntries cache.opts.MaxCacheEntries = DefaultMaxCacheEntries
} }
return func(ctx context.Context, network, address string) (net.Conn, error) { return func(_ context.Context, network, address string) (net.Conn, error) {
conn := &dnsConn{} conn := &dnsConn{}
conn.roundTrip = cachingRoundTrip(&cache, network, address) conn.roundTrip = cachingRoundTrip(&cache, network, address)
return conn, nil return conn, nil
@ -132,12 +132,12 @@ func PreferIPV6(b bool) Option {
} }
type cache struct { type cache struct {
sync.RWMutex
dial DialFunc
entries map[string]cacheEntry entries map[string]cacheEntry
dial DialFunc
opts Options opts Options
sync.RWMutex
} }
type cacheEntry struct { type cacheEntry struct {
@ -306,7 +306,7 @@ func getNameLen(msg string) int {
for i < len(msg) { for i < len(msg) {
if msg[i] == 0 { if msg[i] == 0 {
// end of name // end of name
i += 1 i++
break break
} }
if msg[i] >= 0xc0 { if msg[i] >= 0xc0 {
@ -336,8 +336,7 @@ func cachingRoundTrip(cache *cache, network, address string) roundTripper {
cache.opts.Meter.Counter(semconv.CacheRequestInflight, "type", "dns").Inc() cache.opts.Meter.Counter(semconv.CacheRequestInflight, "type", "dns").Inc()
defer cache.opts.Meter.Counter(semconv.CacheRequestInflight, "type", "dns").Dec() defer cache.opts.Meter.Counter(semconv.CacheRequestInflight, "type", "dns").Dec()
// check cache // check cache
if res := cache.get(req); res != "" { if res = cache.get(req); res != "" {
cache.opts.Meter.Counter(semconv.CacheRequestTotal, "type", "dns", "method", "get", "status", "hit").Inc()
return res, nil return res, nil
} }
cache.opts.Meter.Counter(semconv.CacheRequestTotal, "type", "dns", "method", "get", "status", "miss").Inc() cache.opts.Meter.Counter(semconv.CacheRequestTotal, "type", "dns", "method", "get", "status", "miss").Inc()

View File

@ -8,15 +8,13 @@ import (
func TestCache(t *testing.T) { func TestCache(t *testing.T) {
net.DefaultResolver = NewNetResolver(PreferIPV4(true)) net.DefaultResolver = NewNetResolver(PreferIPV4(true))
addrs, err := net.LookupHost("unistack.org") _, err := net.LookupHost("unistack.org")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
addrs, err = net.LookupHost("unistack.org") _, err = net.LookupHost("unistack.org")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = addrs
} }

View File

@ -11,12 +11,15 @@ import (
) )
type dnsConn struct { type dnsConn struct {
deadline time.Time
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
roundTrip roundTripper roundTrip roundTripper
deadline time.Time
ibuf bytes.Buffer ibuf bytes.Buffer
obuf bytes.Buffer obuf bytes.Buffer
sync.Mutex sync.Mutex
} }
@ -81,7 +84,7 @@ func (c *dnsConn) SetReadDeadline(t time.Time) error {
return nil return nil
} }
func (c *dnsConn) SetWriteDeadline(t time.Time) error { func (c *dnsConn) SetWriteDeadline(_ time.Time) error {
// writes do not timeout // writes do not timeout
return nil return nil
} }
@ -159,7 +162,7 @@ func readMessage(c net.Conn) (string, error) {
return "", err return "", err
} }
return string(b[:n]), nil return string(b[:n]), nil
} else { }
var sz [2]byte var sz [2]byte
_, err := io.ReadFull(c, sz[:]) _, err := io.ReadFull(c, sz[:])
if err != nil { if err != nil {
@ -177,5 +180,4 @@ func readMessage(c net.Conn) (string, error) {
return "", err return "", err
} }
return str.String(), nil return str.String(), nil
}
} }

View File

@ -71,7 +71,7 @@ func (h *serverHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) {
} }
// TagConn can attach some information to the given context. // TagConn can attach some information to the given context.
func (h *serverHandler) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context { func (h *serverHandler) TagConn(ctx context.Context, _ *stats.ConnTagInfo) context.Context {
if span, ok := tracer.SpanFromContext(ctx); ok { if span, ok := tracer.SpanFromContext(ctx); ok {
attrs := peerAttr(peerFromCtx(ctx)) attrs := peerAttr(peerFromCtx(ctx))
span.AddLabels(attrs...) span.AddLabels(attrs...)
@ -80,7 +80,7 @@ func (h *serverHandler) TagConn(ctx context.Context, info *stats.ConnTagInfo) co
} }
// HandleConn processes the Conn stats. // HandleConn processes the Conn stats.
func (h *serverHandler) HandleConn(ctx context.Context, info stats.ConnStats) { func (h *serverHandler) HandleConn(_ context.Context, _ stats.ConnStats) {
} }
type clientHandler struct { type clientHandler struct {

View File

@ -665,12 +665,12 @@ func patParamKeys(pattern string) ([]string, error) {
// longestPrefix finds the length of the shared prefix // longestPrefix finds the length of the shared prefix
// of two strings // of two strings
func longestPrefix(k1, k2 string) int { func longestPrefix(k1, k2 string) int {
max := len(k1) maxLen := len(k1)
if l := len(k2); l < max { if l := len(k2); l < maxLen {
max = l maxLen = l
} }
var i int var i int
for i = 0; i < max; i++ { for i = 0; i < maxLen; i++ {
if k1[i] != k2[i] { if k1[i] != k2[i] {
break break
} }

View File

@ -14,7 +14,7 @@ func Random(d time.Duration) time.Duration {
return time.Duration(v) return time.Duration(v)
} }
func RandomInterval(min, max time.Duration) time.Duration { func RandomInterval(minTime, maxTime time.Duration) time.Duration {
var rng rand.Rand var rng rand.Rand
return time.Duration(rng.Int63n(max.Nanoseconds()-min.Nanoseconds())+min.Nanoseconds()) * time.Nanosecond return time.Duration(rng.Int63n(maxTime.Nanoseconds()-minTime.Nanoseconds())+minTime.Nanoseconds()) * time.Nanosecond
} }

View File

@ -23,12 +23,12 @@ type Ticker struct {
// NewTickerContext returns a pointer to an initialized instance of the Ticker. // NewTickerContext returns a pointer to an initialized instance of the Ticker.
// It works like NewTicker except that it has ability to close via context. // It works like NewTicker except that it has ability to close via context.
// Also it works fine with context.WithTimeout to handle max time to run ticker. // Also it works fine with context.WithTimeout to handle max time to run ticker.
func NewTickerContext(ctx context.Context, min, max time.Duration) *Ticker { func NewTickerContext(ctx context.Context, minTime, maxTime time.Duration) *Ticker {
ticker := &Ticker{ ticker := &Ticker{
C: make(chan time.Time), C: make(chan time.Time),
done: make(chan chan struct{}), done: make(chan chan struct{}),
min: min.Nanoseconds(), min: minTime.Nanoseconds(),
max: max.Nanoseconds(), max: maxTime.Nanoseconds(),
ctx: ctx, ctx: ctx,
} }
go ticker.run() go ticker.run()
@ -38,12 +38,12 @@ func NewTickerContext(ctx context.Context, min, max time.Duration) *Ticker {
// NewTicker returns a pointer to an initialized instance of the Ticker. // NewTicker returns a pointer to an initialized instance of the Ticker.
// Min and max are durations of the shortest and longest allowed // Min and max are durations of the shortest and longest allowed
// ticks. Ticker will run in a goroutine until explicitly stopped. // ticks. Ticker will run in a goroutine until explicitly stopped.
func NewTicker(min, max time.Duration) *Ticker { func NewTicker(minTime, maxTime time.Duration) *Ticker {
ticker := &Ticker{ ticker := &Ticker{
C: make(chan time.Time), C: make(chan time.Time),
done: make(chan chan struct{}), done: make(chan chan struct{}),
min: min.Nanoseconds(), min: minTime.Nanoseconds(),
max: max.Nanoseconds(), max: maxTime.Nanoseconds(),
ctx: context.Background(), ctx: context.Background(),
} }
go ticker.run() go ticker.run()

View File

@ -31,26 +31,26 @@ loop:
func TestTicker(t *testing.T) { func TestTicker(t *testing.T) {
t.Parallel() t.Parallel()
min := time.Duration(10) minTime := time.Duration(10)
max := time.Duration(20) maxTime := time.Duration(20)
// tick can take a little longer since we're not adjusting it to account for // tick can take a little longer since we're not adjusting it to account for
// processing. // processing.
precision := time.Duration(4) precision := time.Duration(4)
rt := NewTicker(min*time.Millisecond, max*time.Millisecond) rt := NewTicker(minTime*time.Millisecond, maxTime*time.Millisecond)
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
t0 := time.Now() t0 := time.Now()
t1 := <-rt.C t1 := <-rt.C
td := t1.Sub(t0) td := t1.Sub(t0)
if td < min*time.Millisecond { if td < minTime*time.Millisecond {
t.Fatalf("tick was shorter than expected: %s", td) t.Fatalf("tick was shorter than expected: %s", td)
} else if td > (max+precision)*time.Millisecond { } else if td > (maxTime+precision)*time.Millisecond {
t.Fatalf("tick was longer than expected: %s", td) t.Fatalf("tick was longer than expected: %s", td)
} }
} }
rt.Stop() rt.Stop()
time.Sleep((max + precision) * time.Millisecond) time.Sleep((maxTime + precision) * time.Millisecond)
select { select {
case v, ok := <-rt.C: case v, ok := <-rt.C:
if ok || !v.IsZero() { if ok || !v.IsZero() {

View File

@ -48,19 +48,19 @@ func Listen(addr string, fn func(string) (net.Listener, error)) (net.Listener, e
// we have a port range // we have a port range
// extract min port // extract min port
min, err := strconv.Atoi(prange[0]) minPort, err := strconv.Atoi(prange[0])
if err != nil { if err != nil {
return nil, errors.New("unable to extract port range") return nil, errors.New("unable to extract port range")
} }
// extract max port // extract max port
max, err := strconv.Atoi(prange[1]) maxPort, err := strconv.Atoi(prange[1])
if err != nil { if err != nil {
return nil, errors.New("unable to extract port range") return nil, errors.New("unable to extract port range")
} }
// range the ports // range the ports
for port := min; port <= max; port++ { for port := minPort; port <= maxPort; port++ {
// try bind to host:port // try bind to host:port
ln, err := fn(HostPort(host, port)) ln, err := fn(HostPort(host, port))
if err == nil { if err == nil {
@ -68,7 +68,7 @@ func Listen(addr string, fn func(string) (net.Listener, error)) (net.Listener, e
} }
// hit max port // hit max port
if port == max { if port == maxPort {
return nil, err return nil, err
} }
} }

View File

@ -155,7 +155,7 @@ func indexFunction(v reflect.Value) func(i int) reflect.Value {
return v.MapIndex(keys[i]) return v.MapIndex(keys[i])
} }
} }
return func(i int) reflect.Value { return reflect.Value{} } return func(_ int) reflect.Value { return reflect.Value{} }
} }
func mergeValue(values []reflect.Value) reflect.Value { func mergeValue(values []reflect.Value) reflect.Value {

View File

@ -130,16 +130,16 @@ func TestMergeString(t *testing.T) {
func TestMergeNested(t *testing.T) { func TestMergeNested(t *testing.T) {
type CallReqNested struct { type CallReqNested struct {
Nested *CallReqNested `json:"nested2"`
StringArgs []string `json:"string_args"` StringArgs []string `json:"string_args"`
Uint64Args []uint64 `json:"uint64_args"` Uint64Args []uint64 `json:"uint64_args"`
Nested *CallReqNested `json:"nested2"`
} }
type CallReq struct { type CallReq struct {
Nested *CallReqNested `json:"nested"`
Name string `json:"name"` Name string `json:"name"`
Req string `json:"req"` Req string `json:"req"`
Arg2 int `json:"arg2"` Arg2 int `json:"arg2"`
Nested *CallReqNested `json:"nested"`
} }
dst := &CallReq{ dst := &CallReq{

View File

@ -109,13 +109,12 @@ func Merge(olist []*register.Service, nlist []*register.Service) []*register.Ser
seen = true seen = true
srv = append(srv, sp) srv = append(srv, sp)
break break
} else { }
sp := &register.Service{} sp := &register.Service{}
// make copy // make copy
*sp = *o *sp = *o
srv = append(srv, sp) srv = append(srv, sp)
} }
}
if !seen { if !seen {
srv = append(srv, Copy([]*register.Service{n})...) srv = append(srv, Copy([]*register.Service{n})...)
} }
@ -153,14 +152,14 @@ func Remove(old, del []*register.Service) []*register.Service {
// WaitService using register wait for service to appear with min/max interval for check and optional timeout. // WaitService using register wait for service to appear with min/max interval for check and optional timeout.
// Timeout can be 0 to wait infinitive. // Timeout can be 0 to wait infinitive.
func WaitService(ctx context.Context, reg register.Register, name string, min time.Duration, max time.Duration, timeout time.Duration, opts ...register.LookupOption) error { func WaitService(ctx context.Context, reg register.Register, name string, minTime time.Duration, maxTime time.Duration, timeout time.Duration, opts ...register.LookupOption) error {
if timeout > 0 { if timeout > 0 {
var cancel context.CancelFunc var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout) ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
} }
ticker := jitter.NewTickerContext(ctx, min, max) ticker := jitter.NewTickerContext(ctx, minTime, maxTime)
defer ticker.Stop() defer ticker.Stop()
for { for {

View File

@ -10,10 +10,11 @@ import (
// Buffer is ring buffer // Buffer is ring buffer
type Buffer struct { type Buffer struct {
sync.RWMutex
streams map[string]*Stream streams map[string]*Stream
vals []*Entry vals []*Entry
size int size int
sync.RWMutex
} }
// Entry is ring buffer data entry // Entry is ring buffer data entry

View File

@ -6,8 +6,8 @@ import (
// Pool holds the socket pool // Pool holds the socket pool
type Pool struct { type Pool struct {
sync.RWMutex
pool map[string]*Socket pool map[string]*Socket
sync.RWMutex
} }
// Get socket from pool // Get socket from pool

View File

@ -20,10 +20,11 @@ type Stream interface {
} }
type stream struct { type stream struct {
sync.RWMutex
Stream Stream
err error err error
request *request request *request
sync.RWMutex
} }
type request struct { type request struct {

View File

@ -10,11 +10,18 @@ import (
type DigitalOceanMetadata struct { type DigitalOceanMetadata struct {
Metadata struct { Metadata struct {
V1 struct { V1 struct {
DropletID int64 `json:"droplet_id"` Features map[string]interface{} `json:"features"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
VendorData string `json:"vendor_data"` VendorData string `json:"vendor_data"`
PublicKeys []string `json:"public_keys"`
Region string `json:"region"` Region string `json:"region"`
PublicKeys []string `json:"public_keys"`
DNS struct {
Nameservers []string `json:"nameservers"`
} `json:"dns"`
Interfaces struct { Interfaces struct {
Private []struct { Private []struct {
IPv4 struct { IPv4 struct {
@ -31,24 +38,23 @@ type DigitalOceanMetadata struct {
Netmask string `json:"netmask"` Netmask string `json:"netmask"`
Gateway string `json:"gateway"` Gateway string `json:"gateway"`
} `json:"ipv4"` } `json:"ipv4"`
IPv6 struct {
Address string `json:"ip_address"`
CIDR int `json:"cidr"`
Gateway string `json:"gateway"`
} `json:"ipv6"`
Mac string `json:"mac"` Mac string `json:"mac"`
Type string `json:"type"` Type string `json:"type"`
IPv6 struct {
Address string `json:"ip_address"`
Gateway string `json:"gateway"`
CIDR int `json:"cidr"`
} `json:"ipv6"`
} `json:"public"` } `json:"public"`
} `json:"interfaces"` } `json:"interfaces"`
DropletID int64 `json:"droplet_id"`
FloatingIP struct { FloatingIP struct {
IPv4 struct { IPv4 struct {
Active bool `json:"active"` Active bool `json:"active"`
} `json:"ipv4"` } `json:"ipv4"`
} `json:"floating_ip"` } `json:"floating_ip"`
DNS struct {
Nameservers []string `json:"nameservers"`
} `json:"dns"`
Features map[string]interface{} `json:"features"`
} `json:"v1"` } `json:"v1"`
} `json:"metadata"` } `json:"metadata"`
} }

View File

@ -2,17 +2,12 @@ package structfs
type EC2Metadata struct { type EC2Metadata struct {
Latest struct { Latest struct {
Userdata string `json:"user-data"`
Metadata struct { Metadata struct {
AMIID int `json:"ami-id"`
AMILaunchIndex int `json:"ami-launch-index"`
AMIManifestPath string `json:"ami-manifest-path"` AMIManifestPath string `json:"ami-manifest-path"`
AncestorAMIIDs []int `json:"ancestor-ami-ids"`
BlockDeviceMapping []string `json:"block-device-mapping"`
InstanceID int `json:"instance-id"`
InstanceType string `json:"instance-type"` InstanceType string `json:"instance-type"`
LocalHostname string `json:"local-hostname"` LocalHostname string `json:"local-hostname"`
LocalIPv4 string `json:"local-ipv4"` LocalIPv4 string `json:"local-ipv4"`
KernelID int `json:"kernel-id"`
Placement string `json:"placement"` Placement string `json:"placement"`
AvailabilityZone string `json:"availability-zone"` AvailabilityZone string `json:"availability-zone"`
ProductCodes string `json:"product-codes"` ProductCodes string `json:"product-codes"`
@ -21,10 +16,15 @@ type EC2Metadata struct {
PublicKeys []struct { PublicKeys []struct {
Key []string `json:"-"` Key []string `json:"-"`
} `json:"public-keys"` } `json:"public-keys"`
AncestorAMIIDs []int `json:"ancestor-ami-ids"`
BlockDeviceMapping []string `json:"block-device-mapping"`
SecurityGroups []string `json:"security-groups"`
RamdiskID int `json:"ramdisk-id"` RamdiskID int `json:"ramdisk-id"`
ReservationID int `json:"reservation-id"` ReservationID int `json:"reservation-id"`
SecurityGroups []string `json:"security-groups"` AMIID int `json:"ami-id"`
AMILaunchIndex int `json:"ami-launch-index"`
KernelID int `json:"kernel-id"`
InstanceID int `json:"instance-id"`
} `json:"meta-data"` } `json:"meta-data"`
Userdata string `json:"user-data"`
} `json:"latest"` } `json:"latest"`
} }

View File

@ -35,22 +35,22 @@ func (fs *fs) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
type fs struct { type fs struct {
modtime time.Time
iface interface{} iface interface{}
tag string tag string
modtime time.Time
} }
type file struct { type file struct {
name string
offset int64
data []byte
modtime time.Time modtime time.Time
name string
data []byte
offset int64
} }
type fileInfo struct { type fileInfo struct {
modtime time.Time
name string name string
size int64 size int64
modtime time.Time
} }
func (fi *fileInfo) Sys() interface{} { func (fi *fileInfo) Sys() interface{} {
@ -105,7 +105,7 @@ func (f *file) Read(b []byte) (int, error) {
return n, err return n, err
} }
func (f *file) Readdir(count int) ([]os.FileInfo, error) { func (f *file) Readdir(_ int) ([]os.FileInfo, error) {
return nil, nil return nil, nil
} }

View File

@ -93,7 +93,7 @@ func TestAll(t *testing.T) {
in string in string
out string out string
}{ }{
{"http://127.0.0.1:8080/metadata/v1/", "droplet_id\nhostname\nvendor_data\npublic_keys\nregion\ninterfaces\nfloating_ip\ndns\nfeatures"}, {"http://127.0.0.1:8080/metadata/v1/", "features\nhostname\nvendor_data\nregion\npublic_keys\ndns\ninterfaces\ndroplet_id\nfloating_ip"},
{"http://127.0.0.1:8080/metadata/v1/droplet_id", "2756294"}, {"http://127.0.0.1:8080/metadata/v1/droplet_id", "2756294"},
{"http://127.0.0.1:8080/metadata/v1/dns/", "nameservers"}, {"http://127.0.0.1:8080/metadata/v1/dns/", "nameservers"},
{"http://127.0.0.1:8080/metadata/v1/dns/nameservers", "2001:4860:4860::8844\n2001:4860:4860::8888\n8.8.8.8"}, {"http://127.0.0.1:8080/metadata/v1/dns/nameservers", "2001:4860:4860::8844\n2001:4860:4860::8888\n8.8.8.8"},

View File

@ -78,8 +78,8 @@ var (
for _, se := range st.Details() { for _, se := range st.Details() {
switch ne := se.(type) { switch ne := se.(type) {
case proto.Message: case proto.Message:
buf, err := testCodec.Marshal(ne) var buf []byte
if err != nil { if buf, err = testCodec.Marshal(ne); err != nil {
return fmt.Errorf("failed to marshal err: %w", err) return fmt.Errorf("failed to marshal err: %w", err)
} }
if err = testCodec.Unmarshal(buf, &testMap); err != nil { if err = testCodec.Unmarshal(buf, &testMap); err != nil {
@ -438,10 +438,10 @@ func Run(ctx context.Context, c client.Client, m sqlmock.Sqlmock, dir string, ex
} }
type Case struct { type Case struct {
dbfiles []string
reqfile string reqfile string
rspfile string rspfile string
errfile string errfile string
dbfiles []string
} }
func GetCases(dir string, exts []string) ([]Case, error) { func GetCases(dir string, exts []string) ([]Case, error) {

View File

@ -1,6 +1,5 @@
package text package text
func DetectEncoding(text string) map[string]int { func DetectEncoding(text string) map[string]int {
charsets := map[string]int{ charsets := map[string]int{
"UTF-8": 0, "UTF-8": 0,
@ -19,7 +18,7 @@ func DetectEncoding(text string) map[string]int {
utfupper := 5 utfupper := 5
lowercase := 3 lowercase := 3
uppercase := 1 uppercase := 1
last_simb := 0 lastSimb := 0
for a := 0; a < len(text); a++ { for a := 0; a < len(text); a++ {
char := int(text[a]) char := int(text[a])
@ -30,10 +29,10 @@ func DetectEncoding(text string) map[string]int {
} }
// UTF-8 // UTF-8
if (last_simb == 208) && ((char > 143 && char < 176) || char == 129) { if (lastSimb == 208) && ((char > 143 && char < 176) || char == 129) {
charsets["UTF-8"] += (utfupper * 2) charsets["UTF-8"] += (utfupper * 2)
} }
if ((last_simb == 208) && ((char > 175 && char < 192) || char == 145)) || (last_simb == 209 && char > 127 && char < 144) { if ((lastSimb == 208) && ((char > 175 && char < 192) || char == 145)) || (lastSimb == 209 && char > 127 && char < 144) {
charsets["UTF-8"] += (utflower * 2) charsets["UTF-8"] += (utflower * 2)
} }
@ -77,7 +76,7 @@ func DetectEncoding(text string) map[string]int {
charsets["MAC"] += uppercase charsets["MAC"] += uppercase
} }
last_simb = char lastSimb = char
} }
return charsets return charsets

View File

@ -2,7 +2,6 @@ package time
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"time" "time"
@ -14,7 +13,7 @@ type Duration int64
func ParseDuration(s string) (time.Duration, error) { func ParseDuration(s string) (time.Duration, error) {
if s == "" { if s == "" {
return 0, errors.New(`time: invalid duration "` + s + `"`) return 0, fmt.Errorf(`time: invalid duration "%s"`, s)
} }
var p int var p int
@ -27,21 +26,21 @@ loop:
case 'h': case 'h':
d, err := strconv.Atoi(s[p:i]) d, err := strconv.Atoi(s[p:i])
if err != nil { if err != nil {
return 0, errors.New("time: invalid duration " + s) return 0, fmt.Errorf(`time: invalid duration "%s"`, s)
} }
hours += d hours += d
p = i + 1 p = i + 1
case 'd': case 'd':
d, err := strconv.Atoi(s[p:i]) d, err := strconv.Atoi(s[p:i])
if err != nil { if err != nil {
return 0, errors.New("time: invalid duration " + s) return 0, fmt.Errorf(`time: invalid duration "%s"`, s)
} }
hours += d * 24 hours += d * 24
p = i + 1 p = i + 1
case 'y': case 'y':
n, err := strconv.Atoi(s[p:i]) n, err := strconv.Atoi(s[p:i])
if err != nil { if err != nil {
return 0, errors.New("time: invalid duration " + s) return 0, fmt.Errorf(`time: invalid duration "%s"`, s)
} }
var d int var d int
for j := n - 1; j >= 0; j-- { for j := n - 1; j >= 0; j-- {