@@ -18,9 +18,13 @@ import (
1818 "github.com/tarantool/go-storage/watch"
1919)
2020
21- // Client defines the minimal interface needed for etcd operations.
21+ // Client defines the minimal interface needed for etcd operations. It
22+ // is compatible with etcdclientv3.Client.
23+ //
2224// This allows for easier testing and mock implementations.
2325type Client interface {
26+ Watcher
27+
2428 // Txn creates a new transaction.
2529 Txn (ctx context.Context ) etcd.Txn
2630}
@@ -34,17 +38,10 @@ type Watcher interface {
3438 Close () error
3539}
3640
37- // WatcherFactory creates new watchers from a client.
38- type WatcherFactory interface {
39- // NewWatcher creates a new watcher.
40- NewWatcher (client Client ) Watcher
41- }
42-
4341// Driver is an etcd implementation of the storage driver interface.
4442// It uses etcd as the underlying key-value storage backend.
4543type Driver struct {
4644 client Client // etcd client interface.
47- watcherFactory WatcherFactory // factory for creating watchers.
4845}
4946
5047var (
@@ -59,63 +56,11 @@ var (
5956 errUnsupportedOperationType = errors .New ("unsupported operation type" )
6057)
6158
62- // etcdClientAdapter wraps etcd.Client to implement our Client interface.
63- type etcdClientAdapter struct {
64- client * etcd.Client
65- }
66-
67- func (a * etcdClientAdapter ) Txn (ctx context.Context ) etcd.Txn {
68- return a .client .Txn (ctx )
69- }
70-
71- // etcdWatcherAdapter wraps etcd.Watcher to implement our Watcher interface.
72- type etcdWatcherAdapter struct {
73- watcher etcd.Watcher
74- }
75-
76- func (a * etcdWatcherAdapter ) Watch (ctx context.Context , key string , opts ... etcd.OpOption ) etcd.WatchChan {
77- return a .watcher .Watch (ctx , key , opts ... )
78- }
79-
80- func (a * etcdWatcherAdapter ) Close () error {
81- return fmt .Errorf ("failed to close: %w" , a .watcher .Close ())
82- }
83-
84- // etcdWatcherFactory implements WatcherFactory for etcd clients.
85- type etcdWatcherFactory struct {}
86-
87- func (f * etcdWatcherFactory ) NewWatcher (client Client ) Watcher {
88- // For etcd clients, we need access to the underlying client.
89- if adapter , ok := client .(* etcdClientAdapter ); ok {
90- return & etcdWatcherAdapter {
91- watcher : etcd .NewWatcher (adapter .client ),
92- }
93- }
94-
95- // For other implementations, return a no-op watcher.
96- return & noopWatcher {}
97- }
98-
99- // noopWatcher is a no-op implementation of Watcher for non-etcd clients.
100- type noopWatcher struct {}
101-
102- func (w * noopWatcher ) Watch (_ context.Context , _ string , _ ... etcd.OpOption ) etcd.WatchChan {
103- ch := make (chan etcd.WatchResponse )
104- close (ch )
105-
106- return ch
107- }
108-
109- func (w * noopWatcher ) Close () error {
110- return nil
111- }
112-
11359// New creates a new etcd driver instance using an existing etcd client.
11460// The client should be properly configured and connected to an etcd cluster.
115- func New (client * etcd. Client ) * Driver {
61+ func New (client Client ) * Driver {
11662 return & Driver {
117- client : & etcdClientAdapter {client : client },
118- watcherFactory : & etcdWatcherFactory {},
63+ client : client ,
11964 }
12065}
12166
@@ -167,14 +112,12 @@ const (
167112func (d Driver ) Watch (ctx context.Context , key []byte , _ ... watch.Option ) (<- chan watch.Event , func (), error ) {
168113 eventCh := make (chan watch.Event , eventChannelSize )
169114
170- parentWatcher := d .watcherFactory .NewWatcher (d .client )
171-
172115 var opts []etcd.OpOption
173116 if bytes .HasSuffix (key , []byte ("/" )) {
174117 opts = append (opts , etcd .WithPrefix ())
175118 }
176119
177- watchChan := parentWatcher .Watch (ctx , string (key ), opts ... )
120+ watchChan := d . client .Watch (ctx , string (key ), opts ... )
178121
179122 go func () {
180123 defer close (eventCh )
@@ -206,7 +149,7 @@ func (d Driver) Watch(ctx context.Context, key []byte, _ ...watch.Option) (<-cha
206149 }()
207150
208151 return eventCh , func () {
209- _ = parentWatcher .Close ()
152+ d . client .Close ()
210153 }, nil
211154}
212155
0 commit comments