Skip to content

Commit 74e8951

Browse files
authored
common: common ping w/ backoff, use in aggregator/verifier/indexer (#507)
* common: common ping w/ backoff, use in aggregator/verifier/indexer * lint
1 parent d0e8dde commit 74e8951

File tree

4 files changed

+48
-29
lines changed

4 files changed

+48
-29
lines changed

aggregator/pkg/storage/factory.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/common"
1111
"github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model"
1212
"github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/storage/postgres"
13+
ccvcommon "github.com/smartcontractkit/chainlink-ccv/common"
1314
"github.com/smartcontractkit/chainlink-common/pkg/logger"
1415

1516
_ "github.com/lib/pq" // PostgreSQL driver
@@ -93,7 +94,7 @@ func (f *Factory) createPostgreSQLStorage(config *model.StorageConfig) (CommitVe
9394
"connMaxIdleTime", connMaxIdleTime,
9495
)
9596

96-
if err := db.Ping(); err != nil {
97+
if err := ccvcommon.EnsureDBConnection(f.logger, db); err != nil {
9798
return nil, fmt.Errorf("failed to ping PostgreSQL database: %w", err)
9899
}
99100

cmd/verifier/committee/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"go.uber.org/zap/zapcore"
1818

1919
cmd "github.com/smartcontractkit/chainlink-ccv/cmd/verifier"
20+
ccvcommon "github.com/smartcontractkit/chainlink-ccv/common"
2021
"github.com/smartcontractkit/chainlink-ccv/integration/storageaccess"
2122
"github.com/smartcontractkit/chainlink-ccv/protocol"
2223
"github.com/smartcontractkit/chainlink-ccv/protocol/common/hmac"
@@ -333,7 +334,7 @@ func createChainStatusManager(lggr logger.Logger) (protocol.ChainStatusManager,
333334
db.SetConnMaxLifetime(time.Duration(connMaxLifetime) * time.Second)
334335
db.SetConnMaxIdleTime(time.Duration(connMaxIdleTime) * time.Second)
335336

336-
if err := db.Ping(); err != nil {
337+
if err := ccvcommon.EnsureDBConnection(lggr, db); err != nil {
337338
_ = db.Close()
338339
return nil, nil, fmt.Errorf("failed to ping postgres database: %w", err)
339340
}

common/db_utils.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package common
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/smartcontractkit/chainlink-common/pkg/logger"
9+
)
10+
11+
const (
12+
maxRetries = 10
13+
timeout = 1 * time.Second
14+
retryInterval = 3 * time.Second
15+
)
16+
17+
// Pingable is implemented by servers that support pings.
18+
type Pingable interface {
19+
// PingContext pings the server and returns an error if the ping is unsuccessful.
20+
PingContext(ctx context.Context) error
21+
}
22+
23+
// EnsureDBConnection ensures that the database is up and running by pinging it.
24+
func EnsureDBConnection(lggr logger.Logger, db Pingable) error {
25+
pingFn := func() error {
26+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
27+
defer cancel()
28+
return db.PingContext(ctx)
29+
}
30+
for range maxRetries {
31+
err := pingFn()
32+
if err == nil {
33+
return nil
34+
}
35+
lggr.Warnw("failed to connect to database, retrying after sleeping",
36+
"err", err,
37+
"retryInterval", retryInterval.String(),
38+
"maxRetries", maxRetries)
39+
time.Sleep(retryInterval)
40+
}
41+
return fmt.Errorf("failed to connect to database after %d retries", maxRetries)
42+
}

indexer/cmd/main.go

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/pressly/goose/v3"
1313
"go.uber.org/zap/zapcore"
1414

15+
ccvcommon "github.com/smartcontractkit/chainlink-ccv/common"
1516
"github.com/smartcontractkit/chainlink-ccv/indexer/pkg/api"
1617
"github.com/smartcontractkit/chainlink-ccv/indexer/pkg/common"
1718
"github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config"
@@ -287,32 +288,6 @@ func createPostgresStorage(ctx context.Context, lggr logger.Logger, cfg *config.
287288
return dbStore
288289
}
289290

290-
// ensureDBConnection ensures that the database is up and running by pinging it.
291-
func ensureDBConnection(lggr logger.Logger, db *sql.DB) error {
292-
const (
293-
maxRetries = 10
294-
timeout = 1 * time.Second
295-
retryInterval = 3 * time.Second
296-
)
297-
pingFn := func() error {
298-
ctx, cancel := context.WithTimeout(context.Background(), timeout)
299-
defer cancel()
300-
return db.PingContext(ctx)
301-
}
302-
for range maxRetries {
303-
err := pingFn()
304-
if err == nil {
305-
return nil
306-
}
307-
lggr.Warnw("failed to connect to database, retrying after sleeping",
308-
"err", err,
309-
"retryInterval", retryInterval.String(),
310-
"maxRetries", maxRetries)
311-
time.Sleep(retryInterval)
312-
}
313-
return fmt.Errorf("failed to connect to database after %d retries", maxRetries)
314-
}
315-
316291
// runMigrations runs all pending database migrations using goose.
317292
func runMigrations(lggr logger.Logger, dbURI, migrationsDir string) error {
318293
// Open a connection to the database for migrations
@@ -321,7 +296,7 @@ func runMigrations(lggr logger.Logger, dbURI, migrationsDir string) error {
321296
return err
322297
}
323298

324-
err = ensureDBConnection(lggr, db)
299+
err = ccvcommon.EnsureDBConnection(lggr, db)
325300
if err != nil {
326301
return fmt.Errorf("could not connect to database: %w", err)
327302
}

0 commit comments

Comments
 (0)