Skip to content

Commit

Permalink
postgres: refactor status setters
Browse files Browse the repository at this point in the history
Signed-off-by: Hank Donnay <hdonnay@redhat.com>
  • Loading branch information
hdonnay committed Feb 22, 2022
1 parent fb1c023 commit 149ec35
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 174 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/google/go-containerregistry v0.6.0
github.com/google/uuid v1.2.0
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/jackc/pgconn v1.10.0
github.com/jackc/pgx/v4 v4.13.0
github.com/klauspost/compress v1.13.6
github.com/ldelossa/responserecorder v1.0.2-0.20210711162258-40bec93a9325
Expand Down
115 changes: 115 additions & 0 deletions notifier/postgres/set_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package postgres

import (
"context"

"github.com/google/uuid"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

clairerror "github.com/quay/clair/v4/clair-error"
)

var (
setDeletedCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdeleted_total",
Help: "Total number of database queries issued in the setDeleted method",
},
[]string{"query", "error"},
)
setDeletedDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdeleted_duration_seconds",
Help: "Duration of all queries issued in the setDeleted method",
},
[]string{"query", "error"},
)
setDeliveredCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdelivered_total",
Help: "Total number of database queries issued in the setDelivered method",
},
[]string{"query", "error"},
)
setDeliveredDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdelivered_duration_seconds",
Help: "Duration of all queries issued in the setDelivered method",
},
[]string{"query", "error"},
)
setDeliveryFailedCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdeliveryfailed_total",
Help: "Total number of database queries issued in the setDeliveryFailed method",
},
[]string{"query", "error"},
)
setDeliveryFailedDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "clair",
Subsystem: "notifier",
Name: "setdeliveryfailed_duration_seconds",
Help: "Duration of all queries issued in the setDeliveryFailed method",
},
[]string{"query", "error"},
)
)

func (s *Store) setStatus(ctx context.Context, id uuid.UUID, status string, m statusMetrics) error {
const query = `UPDATE receipt SET status = $1::receiptstatus, ts = CURRENT_TIMESTAMP WHERE notification_id = $2::uuid;`
return s.pool.AcquireFunc(ctx, func(c *pgxpool.Conn) error {
var err error
var tag pgconn.CommandTag
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
m.dur.WithLabelValues(`query`, errLabel(err)).Observe(v)
}))
defer timer.ObserveDuration()
tag, err = c.Exec(ctx, query, status, id)
m.counter.WithLabelValues(`query`, errLabel(err)).Add(1)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return &clairerror.ErrNoReceipt{NotificationID: id}
}
return nil
})
}

// SetDelivered marks the provided notification id as delivered
func (s *Store) SetDelivered(ctx context.Context, id uuid.UUID) error {
return s.setStatus(ctx, id, `delivered`, statusMetrics{
counter: setDeliveredCounter,
dur: setDeliveredDuration,
})
}

// SetDeliveryFailed marks the provided notification id failed to be delivere
func (s *Store) SetDeliveryFailed(ctx context.Context, id uuid.UUID) error {
return s.setStatus(ctx, id, `delivery_failed`, statusMetrics{
counter: setDeliveryFailedCounter,
dur: setDeliveryFailedDuration,
})
}

// SetDeleted marks the provided notification id as deleted
func (s *Store) SetDeleted(ctx context.Context, id uuid.UUID) error {
return s.setStatus(ctx, id, `deleted`, statusMetrics{
counter: setDeletedCounter,
dur: setDeletedDuration,
})
}
55 changes: 0 additions & 55 deletions notifier/postgres/setdeleted.go

This file was deleted.

55 changes: 0 additions & 55 deletions notifier/postgres/setdelivered.go

This file was deleted.

55 changes: 0 additions & 55 deletions notifier/postgres/setdeliveryfailed.go

This file was deleted.

41 changes: 32 additions & 9 deletions notifier/postgres/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"context"

"github.com/google/uuid"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/prometheus/client_golang/prometheus"

"github.com/quay/clair/v4/notifier"
)
Expand Down Expand Up @@ -78,17 +81,37 @@ func (s *Store) Deleted(ctx context.Context) ([]uuid.UUID, error) {
return deleted(ctx, s.pool)
}

// SetDelivered marks the provided notification id as delivered
func (s *Store) SetDelivered(ctx context.Context, id uuid.UUID) error {
return setDelivered(ctx, s.pool, id)
func errLabel(e error) string {
if e == nil {
return `false`
}
return `true`
}

// SetDeliveryFailed marks the provided notification id failed to be delivere
func (s *Store) SetDeliveryFailed(ctx context.Context, id uuid.UUID) error {
return setDeliveryFailed(ctx, s.pool, id)
type statusMetrics struct {
counter *prometheus.CounterVec
affected *prometheus.CounterVec
dur *prometheus.HistogramVec
}

// SetDeleted marks the provided notification id as deleted
func (s *Store) SetDeleted(ctx context.Context, id uuid.UUID) error {
return setDeleted(ctx, s.pool, id)
// TxExec runs the passed query in the provided transaction, recording it as
// "name" with the metrics passed in "m".
//
// This is highly specific to how metrics are used in this package, and will
// panic if there are more than two labels unpopulated. It's expected that
// they're "query" and "error", respectively.
func txExec(ctx context.Context, m statusMetrics, tx pgx.Tx, name, query string, args []interface{}) error {
var err error
var tag pgconn.CommandTag
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
m.dur.WithLabelValues(name, errLabel(err)).Observe(v)
}))
defer timer.ObserveDuration()
tag, err = tx.Exec(ctx, query, args...)
m.counter.WithLabelValues(name, errLabel(err)).Add(1)
m.affected.WithLabelValues(name, errLabel(err)).Add(float64(tag.RowsAffected()))
if err != nil {
return err
}
return nil
}

0 comments on commit 149ec35

Please sign in to comment.