From 2a6ce6d4da7305aecf6fa56b83ceb1944052fcb2 Mon Sep 17 00:00:00 2001 From: Evstigneev Denis Date: Tue, 26 Nov 2024 12:18:17 +0300 Subject: [PATCH] add using lazy connect (#361) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #357 Co-authored-by: Василий Толстов Reviewed-on: https://git.unistack.org/unistack-org/micro/pulls/361 Reviewed-by: Василий Толстов Co-authored-by: Evstigneev Denis Co-committed-by: Evstigneev Denis --- store/memory/memory.go | 51 ++++++++++++++++++++++++++++++------ store/noop.go | 59 ++++++++++++++++++++++++++++++++++-------- store/options.go | 2 ++ 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/store/memory/memory.go b/store/memory/memory.go index 7f012fab..11b41046 100644 --- a/store/memory/memory.go +++ b/store/memory/memory.go @@ -4,6 +4,7 @@ import ( "context" "sort" "strings" + "sync/atomic" "time" cache "github.com/patrickmn/go-cache" @@ -20,7 +21,10 @@ func NewStore(opts ...store.Option) store.Store { } func (m *memoryStore) Connect(ctx context.Context) error { - return nil + if m.opts.LazyConnect { + return nil + } + return m.connect(ctx) } func (m *memoryStore) Disconnect(ctx context.Context) error { @@ -29,13 +33,14 @@ func (m *memoryStore) Disconnect(ctx context.Context) error { } type memoryStore struct { - funcRead store.FuncRead - funcWrite store.FuncWrite - funcExists store.FuncExists - funcList store.FuncList - funcDelete store.FuncDelete - store *cache.Cache - opts store.Options + funcRead store.FuncRead + funcWrite store.FuncWrite + funcExists store.FuncExists + funcList store.FuncList + funcDelete store.FuncDelete + store *cache.Cache + opts store.Options + isConnected atomic.Int32 } func (m *memoryStore) key(prefix, key string) string { @@ -145,6 +150,11 @@ func (m *memoryStore) Name() string { } 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...) } @@ -157,6 +167,11 @@ 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 { + if m.opts.LazyConnect { + if err := m.connect(ctx); err != nil { + return err + } + } return m.funcRead(ctx, key, val, opts...) } @@ -169,6 +184,11 @@ 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 { + if m.opts.LazyConnect { + if err := m.connect(ctx); err != nil { + return err + } + } return m.funcWrite(ctx, key, val, opts...) } @@ -193,6 +213,11 @@ func (m *memoryStore) fnWrite(ctx context.Context, key string, val interface{}, } 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...) } @@ -211,6 +236,11 @@ func (m *memoryStore) Options() store.Options { } 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...) } @@ -244,3 +274,8 @@ func (m *memoryStore) fnList(ctx context.Context, opts ...store.ListOption) ([]s return keys, nil } + +func (m *memoryStore) connect(ctx context.Context) error { + m.isConnected.CompareAndSwap(0, 1) + return nil +} diff --git a/store/noop.go b/store/noop.go index c7e2922d..7b113dfa 100644 --- a/store/noop.go +++ b/store/noop.go @@ -2,6 +2,7 @@ package store import ( "context" + "sync/atomic" "go.unistack.org/micro/v3/options" ) @@ -9,12 +10,13 @@ import ( var _ Store = (*noopStore)(nil) type noopStore struct { - funcRead FuncRead - funcWrite FuncWrite - funcExists FuncExists - funcList FuncList - funcDelete FuncDelete - opts Options + funcRead FuncRead + funcWrite FuncWrite + funcExists FuncExists + funcList FuncList + funcDelete FuncDelete + opts Options + isConnected atomic.Int32 } func NewStore(opts ...Option) *noopStore { @@ -52,12 +54,10 @@ func (n *noopStore) Init(opts ...Option) error { } func (n *noopStore) Connect(ctx context.Context) error { - select { - case <-ctx.Done(): - return ctx.Err() - default: + if n.opts.LazyConnect { + return nil } - return nil + return n.connect(ctx) } func (n *noopStore) Disconnect(ctx context.Context) error { @@ -70,6 +70,11 @@ func (n *noopStore) Disconnect(ctx context.Context) 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...) } @@ -83,6 +88,11 @@ func (n *noopStore) fnRead(ctx context.Context, key string, val interface{}, opt } 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...) } @@ -96,6 +106,11 @@ func (n *noopStore) fnDelete(ctx context.Context, key string, opts ...DeleteOpti } 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...) } @@ -109,6 +124,11 @@ 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 { + if n.opts.LazyConnect { + if err := n.connect(ctx); err != nil { + return err + } + } return n.funcWrite(ctx, key, val, opts...) } @@ -122,6 +142,11 @@ func (n *noopStore) fnWrite(ctx context.Context, key string, val interface{}, op } 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...) } @@ -145,3 +170,15 @@ func (n *noopStore) String() string { func (n *noopStore) Options() Options { 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 +} diff --git a/store/options.go b/store/options.go index 438b745c..ffcafdd5 100644 --- a/store/options.go +++ b/store/options.go @@ -41,6 +41,8 @@ type Options struct { Timeout time.Duration // Hooks can be run before/after store Read/List/Write/Exists/Delete Hooks options.Hooks + // LazyConnect creates a connection when using store + LazyConnect bool } // NewOptions creates options struct