-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the Stater interface instead of pgxpool.Pool structure #28
Conversation
Hey @inebritov, thanks for the PR! Would you be able to provide an example of how you would use this new |
Hi! Using interfaces in Go is a common practice as it simplifies injecting different implementations. For example, when writing a test for the Please feel free to ask for any clarifications or modifications to this PR. I will do my best to contribute effectively! |
@inebritov please provide an example where and how one would use this interface. I do not understand why one would have a stat collector on a mocked pool for tests. |
Sure. I am looking to integrate the library into an existing project. The project has the following interface: type Pool interface {
Exec(ctx context.Context, sql string, arguments ...interface{}) (pgconn.CommandTag, error)
Close()
Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
BeginTx(ctx context.Context, sql pgx.TxOptions) (pgx.Tx, error)
} And the following routine for application initialization: func (s *DB) Init(ctx context.Context, cfgInt interface{}) error {
//...
var pool Pool
pool, err = pgxpool.ConnectConfig(ctx, poolCFG)
if err != nil {
return fmt.Errorf("could not initialize pgx pool: %w", err)
}
s.Pool = pool // type of s.Pool: Pool interface
return nil
} Creating the pool in this context means that s.Pool = NewPgxPoolStatsCollector(pool) At first glance, it seems easier to change the When using a mock library, it typically generates dummy structures for each method: type Pool struct {
mock.Mock
}
func (p *Pool) Exec(ctx context.Context, sql string, arguments ...interface{}) (pgconn.CommandTag, error) {
args := p.Called(sql, arguments)
return args.Get(0).(pgconn.CommandTag), args.Error(1)
}
func (p *Pool) Close(_ context.Context) {
args := c.Called()
}
//... Integration tests in this scenario will call the |
I see |
A few things here, this library targets pgxpool v5, your example is using s.Pool = NewPgxPoolStatsCollector(pool) I am assuming that pgxpool-prometheus/collector.go Line 30 in c94a268
which returns a Instead, it should be used like so to register the collector to a Prometheus registry. pgxpool-prometheus/_example/example.go Lines 21 to 28 in c94a268
so in your example, it would look like: func (s *DB) Init(ctx context.Context, cfgInt interface{}) error {
//...
var pool Pool
pool, err = pgxpool.ConnectConfig(ctx, poolCFG)
if err != nil {
return fmt.Errorf("could not initialize pgx pool: %w", err)
}
// register pool with prometheus
prometheus.MustRegister(pgxpool_prometheus.NewPgxPoolStatsCollector(pool, "database"))
s.Pool = pool // type of s.Pool: Pool interface
return nil
} Regarding the |
This pull request refactors the
cmackenzie1/pgxpool-prometheus
library to use theStater
interface instead of directly using thepgxpool.Pool
struct. This change aims to improve the flexibility and testability of the code by allowing different implementations of theStat
method. This change promotes better abstraction and separation of concerns, making the codebase cleaner and more modular. The usage is not changed.