@@ -62,6 +62,8 @@ type Storage[T object] interface {
62
62
// Save store the provided object in the storage
63
63
// the provided object should at least be able to return a non-null and unique Identifier (via the GetIdentifier() method)
64
64
Save (ctx context.Context , obj T ) error
65
+ // HealthCheck verifies if the storage is connected and usable
66
+ HealthCheck (ctx context.Context , hydrationSample func () T ) bool
65
67
}
66
68
67
69
type storageImpl [T object ] struct {
@@ -149,6 +151,24 @@ func (s *storageImpl[T]) Save(ctx context.Context, obj T) error {
149
151
return txn .Commit ()
150
152
}
151
153
154
+ // HealthCheck verifies if the storage is connected and usable
155
+ func (s * storageImpl [T ]) HealthCheck (ctx context.Context , hydrationSample func () T ) bool {
156
+ if s .db == nil {
157
+ log .Ctx (ctx ).Error ().Msg ("Storage healthcheck failed: db is nil" )
158
+ return false
159
+ }
160
+ if s .db .IsClosed () {
161
+ log .Ctx (ctx ).Error ().Msg ("Storage healthcheck failed: db is closed" )
162
+ return false
163
+ }
164
+ if err := s .Hydrate (ctx , hydrationSample ()); err != nil {
165
+ log .Ctx (ctx ).Error ().Err (err ).Msg ("Storage healthcheck failed: could not hydrate sample" )
166
+ return false
167
+ }
168
+
169
+ return true
170
+ }
171
+
152
172
// NullStorage is a dummy object honoring the Storage interface, and can be used in unit tests
153
173
// as a drop-in replacement in the dependencies if the test don't actually care about storage actions.
154
174
type NullStorage [T object ] struct {}
@@ -168,3 +188,7 @@ func (s NullStorage[T]) Hydrate(context.Context, T) error {
168
188
func (s NullStorage [T ]) Save (context.Context , T ) error {
169
189
return nil
170
190
}
191
+
192
+ func (s NullStorage [T ]) HealthCheck (context.Context , func () T ) bool {
193
+ return true
194
+ }
0 commit comments