Compare commits
No commits in common. "v3" and "v3.10.99" have entirely different histories.
@ -8,7 +8,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"go.unistack.org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"go.unistack.org/micro/v3/semconv"
|
"go.unistack.org/micro/v3/semconv"
|
||||||
@ -32,27 +31,6 @@ var (
|
|||||||
fatalValue = slog.StringValue("fatal")
|
fatalValue = slog.StringValue("fatal")
|
||||||
)
|
)
|
||||||
|
|
||||||
type wrapper struct {
|
|
||||||
h slog.Handler
|
|
||||||
level atomic.Int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *wrapper) Enabled(ctx context.Context, level slog.Level) bool {
|
|
||||||
return level >= slog.Level(int(h.level.Load()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *wrapper) Handle(ctx context.Context, rec slog.Record) error {
|
|
||||||
return h.h.Handle(ctx, rec)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *wrapper) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
||||||
return h.WithAttrs(attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *wrapper) WithGroup(name string) slog.Handler {
|
|
||||||
return h.WithGroup(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *slogLogger) renameAttr(_ []string, a slog.Attr) slog.Attr {
|
func (s *slogLogger) renameAttr(_ []string, a slog.Attr) slog.Attr {
|
||||||
switch a.Key {
|
switch a.Key {
|
||||||
case slog.SourceKey:
|
case slog.SourceKey:
|
||||||
@ -90,7 +68,7 @@ func (s *slogLogger) renameAttr(_ []string, a slog.Attr) slog.Attr {
|
|||||||
|
|
||||||
type slogLogger struct {
|
type slogLogger struct {
|
||||||
leveler *slog.LevelVar
|
leveler *slog.LevelVar
|
||||||
handler *wrapper
|
handler slog.Handler
|
||||||
opts logger.Options
|
opts logger.Options
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
@ -104,52 +82,51 @@ func (s *slogLogger) Clone(opts ...logger.Option) logger.Logger {
|
|||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(options.ContextAttrFuncs) == 0 {
|
l := &slogLogger{
|
||||||
options.ContextAttrFuncs = logger.DefaultContextAttrFuncs
|
opts: options,
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs, _ := s.argsAttrs(options.Fields)
|
l.leveler = new(slog.LevelVar)
|
||||||
l := &slogLogger{
|
handleOpt := &slog.HandlerOptions{
|
||||||
handler: &wrapper{h: s.handler.h.WithAttrs(attrs)},
|
ReplaceAttr: l.renameAttr,
|
||||||
opts: options,
|
Level: l.leveler,
|
||||||
|
AddSource: l.opts.AddSource,
|
||||||
}
|
}
|
||||||
l.handler.level.Store(int64(loggerToSlogLevel(options.Level)))
|
l.leveler.Set(loggerToSlogLevel(l.opts.Level))
|
||||||
|
l.handler = slog.New(slog.NewJSONHandler(options.Out, handleOpt)).With(options.Fields...).Handler()
|
||||||
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *slogLogger) V(level logger.Level) bool {
|
func (s *slogLogger) V(level logger.Level) bool {
|
||||||
s.mu.Lock()
|
return s.opts.Level.Enabled(level)
|
||||||
v := s.opts.Level.Enabled(level)
|
|
||||||
s.mu.Unlock()
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *slogLogger) Level(level logger.Level) {
|
func (s *slogLogger) Level(level logger.Level) {
|
||||||
s.mu.Lock()
|
s.leveler.Set(loggerToSlogLevel(level))
|
||||||
s.opts.Level = level
|
|
||||||
s.handler.level.Store(int64(loggerToSlogLevel(level)))
|
|
||||||
s.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *slogLogger) Options() logger.Options {
|
func (s *slogLogger) Options() logger.Options {
|
||||||
return s.opts
|
return s.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *slogLogger) Fields(fields ...interface{}) logger.Logger {
|
func (s *slogLogger) Fields(attrs ...interface{}) logger.Logger {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
|
level := s.leveler.Level()
|
||||||
options := s.opts
|
options := s.opts
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
|
|
||||||
l := &slogLogger{opts: options}
|
l := &slogLogger{opts: options}
|
||||||
|
l.leveler = new(slog.LevelVar)
|
||||||
|
l.leveler.Set(level)
|
||||||
|
|
||||||
if len(options.ContextAttrFuncs) == 0 {
|
handleOpt := &slog.HandlerOptions{
|
||||||
options.ContextAttrFuncs = logger.DefaultContextAttrFuncs
|
ReplaceAttr: l.renameAttr,
|
||||||
|
Level: l.leveler,
|
||||||
|
AddSource: l.opts.AddSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs, _ := s.argsAttrs(fields)
|
l.handler = slog.New(slog.NewJSONHandler(l.opts.Out, handleOpt)).With(attrs...).Handler()
|
||||||
l.handler = &wrapper{h: s.handler.h.WithAttrs(attrs)}
|
|
||||||
l.handler.level.Store(int64(loggerToSlogLevel(l.opts.Level)))
|
|
||||||
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
@ -157,23 +134,22 @@ func (s *slogLogger) Fields(fields ...interface{}) logger.Logger {
|
|||||||
func (s *slogLogger) Init(opts ...logger.Option) error {
|
func (s *slogLogger) Init(opts ...logger.Option) error {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
|
||||||
for _, o := range opts {
|
|
||||||
o(&s.opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(s.opts.ContextAttrFuncs) == 0 {
|
if len(s.opts.ContextAttrFuncs) == 0 {
|
||||||
s.opts.ContextAttrFuncs = logger.DefaultContextAttrFuncs
|
s.opts.ContextAttrFuncs = logger.DefaultContextAttrFuncs
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpt := &slog.HandlerOptions{
|
for _, o := range opts {
|
||||||
ReplaceAttr: s.renameAttr,
|
o(&s.opts)
|
||||||
Level: loggerToSlogLevel(logger.TraceLevel),
|
|
||||||
AddSource: s.opts.AddSource,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs, _ := s.argsAttrs(s.opts.Fields)
|
s.leveler = new(slog.LevelVar)
|
||||||
s.handler = &wrapper{h: slog.NewJSONHandler(s.opts.Out, handleOpt).WithAttrs(attrs)}
|
handleOpt := &slog.HandlerOptions{
|
||||||
s.handler.level.Store(int64(loggerToSlogLevel(s.opts.Level)))
|
ReplaceAttr: s.renameAttr,
|
||||||
|
Level: s.leveler,
|
||||||
|
AddSource: s.opts.AddSource,
|
||||||
|
}
|
||||||
|
s.leveler.Set(loggerToSlogLevel(s.opts.Level))
|
||||||
|
s.handler = slog.New(slog.NewJSONHandler(s.opts.Out, handleOpt)).With(s.opts.Fields...).Handler()
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -15,56 +15,6 @@ import (
|
|||||||
"go.unistack.org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMultipleFieldsWithLevel(t *testing.T) {
|
|
||||||
ctx := context.TODO()
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
l := NewLogger(logger.WithLevel(logger.InfoLevel), logger.WithOutput(buf))
|
|
||||||
if err := l.Init(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l = l.Fields("key", "val")
|
|
||||||
|
|
||||||
l.Info(ctx, "msg1")
|
|
||||||
nl := l.Clone(logger.WithLevel(logger.DebugLevel))
|
|
||||||
nl.Debug(ctx, "msg2")
|
|
||||||
l.Debug(ctx, "msg3")
|
|
||||||
if !bytes.Contains(buf.Bytes(), []byte(`"key":"val"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
if !bytes.Contains(buf.Bytes(), []byte(`"msg1"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
if !bytes.Contains(buf.Bytes(), []byte(`"msg2"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
if bytes.Contains(buf.Bytes(), []byte(`"msg3"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultipleFields(t *testing.T) {
|
|
||||||
ctx := context.TODO()
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
l := NewLogger(logger.WithLevel(logger.InfoLevel), logger.WithOutput(buf))
|
|
||||||
if err := l.Init(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l = l.Fields("key", "val")
|
|
||||||
|
|
||||||
l = l.Fields("key1", "val1")
|
|
||||||
|
|
||||||
l.Info(ctx, "msg")
|
|
||||||
|
|
||||||
if !bytes.Contains(buf.Bytes(), []byte(`"key":"val"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
if !bytes.Contains(buf.Bytes(), []byte(`"key1":"val1"`)) {
|
|
||||||
t.Fatalf("logger error not works, buf contains: %s", buf.Bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestError(t *testing.T) {
|
func TestError(t *testing.T) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
@ -284,11 +234,4 @@ func Test_WithContextAttrFunc(t *testing.T) {
|
|||||||
if !(bytes.Contains(buf.Bytes(), []byte(`"source-service":"Test-System"`))) {
|
if !(bytes.Contains(buf.Bytes(), []byte(`"source-service":"Test-System"`))) {
|
||||||
t.Fatalf("logger info, buf %s", buf.Bytes())
|
t.Fatalf("logger info, buf %s", buf.Bytes())
|
||||||
}
|
}
|
||||||
buf.Reset()
|
|
||||||
imd, _ := metadata.FromIncomingContext(ctx)
|
|
||||||
l.Info(ctx, "test message1")
|
|
||||||
imd.Set("Source-Service", "Test-System2")
|
|
||||||
l.Info(ctx, "test message2")
|
|
||||||
|
|
||||||
// t.Logf("xxx %s", buf.Bytes())
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/KimMachineGun/automemlimit/memlimit"
|
"github.com/KimMachineGun/automemlimit/memlimit"
|
||||||
"go.uber.org/automaxprocs/maxprocs"
|
_ "go.uber.org/automaxprocs"
|
||||||
"go.unistack.org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"go.unistack.org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"go.unistack.org/micro/v3/config"
|
"go.unistack.org/micro/v3/config"
|
||||||
@ -20,7 +20,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
maxprocs.Set()
|
|
||||||
memlimit.SetGoMemLimitWithOpts(
|
memlimit.SetGoMemLimitWithOpts(
|
||||||
memlimit.WithRatio(0.9),
|
memlimit.WithRatio(0.9),
|
||||||
memlimit.WithProvider(
|
memlimit.WithProvider(
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cache "github.com/patrickmn/go-cache"
|
cache "github.com/patrickmn/go-cache"
|
||||||
@ -21,10 +20,7 @@ func NewStore(opts ...store.Option) store.Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Connect(ctx context.Context) error {
|
func (m *memoryStore) Connect(ctx context.Context) error {
|
||||||
if m.opts.LazyConnect {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return m.connect(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Disconnect(ctx context.Context) error {
|
func (m *memoryStore) Disconnect(ctx context.Context) error {
|
||||||
@ -33,14 +29,13 @@ func (m *memoryStore) Disconnect(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type memoryStore struct {
|
type memoryStore struct {
|
||||||
funcRead store.FuncRead
|
funcRead store.FuncRead
|
||||||
funcWrite store.FuncWrite
|
funcWrite store.FuncWrite
|
||||||
funcExists store.FuncExists
|
funcExists store.FuncExists
|
||||||
funcList store.FuncList
|
funcList store.FuncList
|
||||||
funcDelete store.FuncDelete
|
funcDelete store.FuncDelete
|
||||||
store *cache.Cache
|
store *cache.Cache
|
||||||
opts store.Options
|
opts store.Options
|
||||||
isConnected atomic.Int32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) key(prefix, key string) string {
|
func (m *memoryStore) key(prefix, key string) string {
|
||||||
@ -150,11 +145,6 @@ func (m *memoryStore) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Exists(ctx context.Context, key string, opts ...store.ExistsOption) error {
|
func (m *memoryStore) Exists(ctx context.Context, key string, opts ...store.ExistsOption) error {
|
||||||
if m.opts.LazyConnect {
|
|
||||||
if err := m.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.funcExists(ctx, key, opts...)
|
return m.funcExists(ctx, key, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,11 +157,6 @@ func (m *memoryStore) fnExists(ctx context.Context, key string, opts ...store.Ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Read(ctx context.Context, key string, val interface{}, opts ...store.ReadOption) error {
|
func (m *memoryStore) Read(ctx context.Context, key string, val interface{}, opts ...store.ReadOption) error {
|
||||||
if m.opts.LazyConnect {
|
|
||||||
if err := m.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.funcRead(ctx, key, val, opts...)
|
return m.funcRead(ctx, key, val, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,11 +169,6 @@ func (m *memoryStore) fnRead(ctx context.Context, key string, val interface{}, o
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Write(ctx context.Context, key string, val interface{}, opts ...store.WriteOption) error {
|
func (m *memoryStore) Write(ctx context.Context, key string, val interface{}, opts ...store.WriteOption) error {
|
||||||
if m.opts.LazyConnect {
|
|
||||||
if err := m.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.funcWrite(ctx, key, val, opts...)
|
return m.funcWrite(ctx, key, val, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,11 +193,6 @@ func (m *memoryStore) fnWrite(ctx context.Context, key string, val interface{},
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) Delete(ctx context.Context, key string, opts ...store.DeleteOption) error {
|
func (m *memoryStore) Delete(ctx context.Context, key string, opts ...store.DeleteOption) error {
|
||||||
if m.opts.LazyConnect {
|
|
||||||
if err := m.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.funcDelete(ctx, key, opts...)
|
return m.funcDelete(ctx, key, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,11 +211,6 @@ func (m *memoryStore) Options() store.Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) List(ctx context.Context, opts ...store.ListOption) ([]string, error) {
|
func (m *memoryStore) List(ctx context.Context, opts ...store.ListOption) ([]string, error) {
|
||||||
if m.opts.LazyConnect {
|
|
||||||
if err := m.connect(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m.funcList(ctx, opts...)
|
return m.funcList(ctx, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,8 +244,3 @@ func (m *memoryStore) fnList(ctx context.Context, opts ...store.ListOption) ([]s
|
|||||||
|
|
||||||
return keys, nil
|
return keys, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryStore) connect(ctx context.Context) error {
|
|
||||||
m.isConnected.CompareAndSwap(0, 1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,6 @@ package store
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"go.unistack.org/micro/v3/options"
|
"go.unistack.org/micro/v3/options"
|
||||||
)
|
)
|
||||||
@ -10,13 +9,12 @@ import (
|
|||||||
var _ Store = (*noopStore)(nil)
|
var _ Store = (*noopStore)(nil)
|
||||||
|
|
||||||
type noopStore struct {
|
type noopStore struct {
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStore(opts ...Option) *noopStore {
|
func NewStore(opts ...Option) *noopStore {
|
||||||
@ -54,10 +52,12 @@ func (n *noopStore) Init(opts ...Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Connect(ctx context.Context) error {
|
func (n *noopStore) Connect(ctx context.Context) error {
|
||||||
if n.opts.LazyConnect {
|
select {
|
||||||
return nil
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
return n.connect(ctx)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Disconnect(ctx context.Context) error {
|
func (n *noopStore) Disconnect(ctx context.Context) error {
|
||||||
@ -70,11 +70,6 @@ func (n *noopStore) Disconnect(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Read(ctx context.Context, key string, val interface{}, opts ...ReadOption) error {
|
func (n *noopStore) Read(ctx context.Context, key string, val interface{}, opts ...ReadOption) error {
|
||||||
if n.opts.LazyConnect {
|
|
||||||
if err := n.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n.funcRead(ctx, key, val, opts...)
|
return n.funcRead(ctx, key, val, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,11 +83,6 @@ func (n *noopStore) fnRead(ctx context.Context, key string, val interface{}, opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Delete(ctx context.Context, key string, opts ...DeleteOption) error {
|
func (n *noopStore) Delete(ctx context.Context, key string, opts ...DeleteOption) error {
|
||||||
if n.opts.LazyConnect {
|
|
||||||
if err := n.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n.funcDelete(ctx, key, opts...)
|
return n.funcDelete(ctx, key, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,11 +96,6 @@ func (n *noopStore) fnDelete(ctx context.Context, key string, opts ...DeleteOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Exists(ctx context.Context, key string, opts ...ExistsOption) error {
|
func (n *noopStore) Exists(ctx context.Context, key string, opts ...ExistsOption) error {
|
||||||
if n.opts.LazyConnect {
|
|
||||||
if err := n.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n.funcExists(ctx, key, opts...)
|
return n.funcExists(ctx, key, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +109,6 @@ func (n *noopStore) fnExists(ctx context.Context, key string, opts ...ExistsOpti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) Write(ctx context.Context, key string, val interface{}, opts ...WriteOption) error {
|
func (n *noopStore) Write(ctx context.Context, key string, val interface{}, opts ...WriteOption) error {
|
||||||
if n.opts.LazyConnect {
|
|
||||||
if err := n.connect(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n.funcWrite(ctx, key, val, opts...)
|
return n.funcWrite(ctx, key, val, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,11 +122,6 @@ func (n *noopStore) fnWrite(ctx context.Context, key string, val interface{}, op
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) List(ctx context.Context, opts ...ListOption) ([]string, error) {
|
func (n *noopStore) List(ctx context.Context, opts ...ListOption) ([]string, error) {
|
||||||
if n.opts.LazyConnect {
|
|
||||||
if err := n.connect(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n.funcList(ctx, opts...)
|
return n.funcList(ctx, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,15 +145,3 @@ func (n *noopStore) String() string {
|
|||||||
func (n *noopStore) Options() Options {
|
func (n *noopStore) Options() Options {
|
||||||
return n.opts
|
return n.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *noopStore) connect(ctx context.Context) error {
|
|
||||||
if n.isConnected.CompareAndSwap(0, 1) {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -41,8 +41,6 @@ type Options struct {
|
|||||||
Timeout time.Duration
|
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
|
||||||
// LazyConnect creates a connection when using store
|
|
||||||
LazyConnect bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOptions creates options struct
|
// NewOptions creates options struct
|
||||||
@ -134,13 +132,6 @@ func Timeout(td time.Duration) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LazyConnect initialize connection only when needed
|
|
||||||
func LazyConnect(b bool) Option {
|
|
||||||
return func(o *Options) {
|
|
||||||
o.LazyConnect = b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Addrs contains the addresses or other connection information of the backing storage.
|
// Addrs contains the addresses or other connection information of the backing storage.
|
||||||
// For example, an etcd implementation would contain the nodes of the cluster.
|
// For example, an etcd implementation would contain the nodes of the cluster.
|
||||||
// A SQL implementation could contain one or more connection strings.
|
// A SQL implementation could contain one or more connection strings.
|
||||||
|
@ -6,8 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Duration int64
|
type Duration int64
|
||||||
@ -55,31 +53,6 @@ loop:
|
|||||||
return time.ParseDuration(fmt.Sprintf("%dh%s", hours, s[p:]))
|
return time.ParseDuration(fmt.Sprintf("%dh%s", hours, s[p:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Duration) MarshalYAML() (interface{}, error) {
|
|
||||||
return time.Duration(d).String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Duration) UnmarshalYAML(n *yaml.Node) error {
|
|
||||||
var v interface{}
|
|
||||||
if err := yaml.Unmarshal([]byte(n.Value), &v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch value := v.(type) {
|
|
||||||
case float64:
|
|
||||||
*d = Duration(time.Duration(value))
|
|
||||||
return nil
|
|
||||||
case string:
|
|
||||||
dv, err := ParseDuration(value)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*d = Duration(dv)
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("invalid duration")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Duration) MarshalJSON() ([]byte, error) {
|
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(time.Duration(d).String())
|
return json.Marshal(time.Duration(d).String())
|
||||||
}
|
}
|
||||||
|
@ -5,44 +5,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMarshalYAML(t *testing.T) {
|
|
||||||
d := Duration(10000000)
|
|
||||||
buf, err := yaml.Marshal(d)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(buf, []byte(`10ms
|
|
||||||
`)) {
|
|
||||||
t.Fatalf("invalid duration: %s != %s", buf, `10ms`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnmarshalYAML(t *testing.T) {
|
|
||||||
type str struct {
|
|
||||||
TTL Duration `yaml:"ttl"`
|
|
||||||
}
|
|
||||||
v := &str{}
|
|
||||||
var err error
|
|
||||||
|
|
||||||
err = yaml.Unmarshal([]byte(`{"ttl":"10ms"}`), v)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v.TTL != 10000000 {
|
|
||||||
t.Fatalf("invalid duration %v != 10000000", v.TTL)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = yaml.Unmarshal([]byte(`{"ttl":"1y"}`), v)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v.TTL != 31622400000000000 {
|
|
||||||
t.Fatalf("invalid duration %v != 31622400000000000", v.TTL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMarshalJSON(t *testing.T) {
|
func TestMarshalJSON(t *testing.T) {
|
||||||
d := Duration(10000000)
|
d := Duration(10000000)
|
||||||
buf, err := json.Marshal(d)
|
buf, err := json.Marshal(d)
|
||||||
|
Loading…
Reference in New Issue
Block a user