mirror of
https://github.com/3ybactuk/marketplace-go-service-project.git
synced 2025-10-30 22:13:44 +03:00
[hw-6] add notifier service, kafka
This commit is contained in:
11
loms/internal/domain/repository/outbox/outbox_event.go
Normal file
11
loms/internal/domain/repository/outbox/outbox_event.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package outbox
|
||||
|
||||
import "route256/loms/internal/domain/entity"
|
||||
|
||||
type Event struct {
|
||||
ID int64
|
||||
OrderID entity.ID
|
||||
Topic string
|
||||
Key string
|
||||
Payload []byte
|
||||
}
|
||||
32
loms/internal/domain/repository/outbox/sqlc/db.go
Normal file
32
loms/internal/domain/repository/outbox/sqlc/db.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
5
loms/internal/domain/repository/outbox/sqlc/models.go
Normal file
5
loms/internal/domain/repository/outbox/sqlc/models.go
Normal file
@@ -0,0 +1,5 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
18
loms/internal/domain/repository/outbox/sqlc/querier.go
Normal file
18
loms/internal/domain/repository/outbox/sqlc/querier.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
OutboxInsert(ctx context.Context, arg *OutboxInsertParams) error
|
||||
OutboxMarkError(ctx context.Context, dollar_1 []int64) (int64, error)
|
||||
OutboxMarkSent(ctx context.Context, dollar_1 []int64) (int64, error)
|
||||
OutboxSelectForPublish(ctx context.Context, limit int32) ([]*OutboxSelectForPublishRow, error)
|
||||
}
|
||||
|
||||
var _ Querier = (*Queries)(nil)
|
||||
22
loms/internal/domain/repository/outbox/sqlc/query.sql
Normal file
22
loms/internal/domain/repository/outbox/sqlc/query.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- name: OutboxInsert :exec
|
||||
INSERT INTO outbox (order_id, topic, "key", payload)
|
||||
VALUES ($1, $2, $3, $4::jsonb);
|
||||
|
||||
-- name: OutboxSelectForPublish :many
|
||||
SELECT id, order_id, topic, "key", payload
|
||||
FROM outbox
|
||||
WHERE status = 'new'
|
||||
ORDER BY created_at
|
||||
LIMIT $1
|
||||
FOR UPDATE SKIP LOCKED;
|
||||
|
||||
-- name: OutboxMarkSent :execrows
|
||||
UPDATE outbox
|
||||
SET status = 'sent',
|
||||
sent_at = now()
|
||||
WHERE id = ANY($1::bigint[]);
|
||||
|
||||
-- name: OutboxMarkError :execrows
|
||||
UPDATE outbox
|
||||
SET status = 'error'
|
||||
WHERE id = ANY($1::bigint[]);
|
||||
104
loms/internal/domain/repository/outbox/sqlc/query.sql.go
Normal file
104
loms/internal/domain/repository/outbox/sqlc/query.sql.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.29.0
|
||||
// source: query.sql
|
||||
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const outboxInsert = `-- name: OutboxInsert :exec
|
||||
INSERT INTO outbox (order_id, topic, "key", payload)
|
||||
VALUES ($1, $2, $3, $4::jsonb)
|
||||
`
|
||||
|
||||
type OutboxInsertParams struct {
|
||||
OrderID int64
|
||||
Topic string
|
||||
Key *string
|
||||
Column4 []byte
|
||||
}
|
||||
|
||||
func (q *Queries) OutboxInsert(ctx context.Context, arg *OutboxInsertParams) error {
|
||||
_, err := q.db.Exec(ctx, outboxInsert,
|
||||
arg.OrderID,
|
||||
arg.Topic,
|
||||
arg.Key,
|
||||
arg.Column4,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const outboxMarkError = `-- name: OutboxMarkError :execrows
|
||||
UPDATE outbox
|
||||
SET status = 'error'
|
||||
WHERE id = ANY($1::bigint[])
|
||||
`
|
||||
|
||||
func (q *Queries) OutboxMarkError(ctx context.Context, dollar_1 []int64) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, outboxMarkError, dollar_1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
|
||||
const outboxMarkSent = `-- name: OutboxMarkSent :execrows
|
||||
UPDATE outbox
|
||||
SET status = 'sent',
|
||||
sent_at = now()
|
||||
WHERE id = ANY($1::bigint[])
|
||||
`
|
||||
|
||||
func (q *Queries) OutboxMarkSent(ctx context.Context, dollar_1 []int64) (int64, error) {
|
||||
result, err := q.db.Exec(ctx, outboxMarkSent, dollar_1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.RowsAffected(), nil
|
||||
}
|
||||
|
||||
const outboxSelectForPublish = `-- name: OutboxSelectForPublish :many
|
||||
SELECT id, order_id, topic, "key", payload
|
||||
FROM outbox
|
||||
WHERE status = 'new'
|
||||
ORDER BY created_at
|
||||
LIMIT $1
|
||||
FOR UPDATE SKIP LOCKED
|
||||
`
|
||||
|
||||
type OutboxSelectForPublishRow struct {
|
||||
ID int64
|
||||
OrderID int64
|
||||
Topic string
|
||||
Key *string
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (q *Queries) OutboxSelectForPublish(ctx context.Context, limit int32) ([]*OutboxSelectForPublishRow, error) {
|
||||
rows, err := q.db.Query(ctx, outboxSelectForPublish, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []*OutboxSelectForPublishRow
|
||||
for rows.Next() {
|
||||
var i OutboxSelectForPublishRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.OrderID,
|
||||
&i.Topic,
|
||||
&i.Key,
|
||||
&i.Payload,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, &i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
85
loms/internal/domain/repository/outbox/sqlc/repository.go
Normal file
85
loms/internal/domain/repository/outbox/sqlc/repository.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package sqlc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"route256/loms/internal/domain/entity"
|
||||
"route256/loms/internal/domain/repository/outbox"
|
||||
"route256/loms/internal/infra/postgres"
|
||||
)
|
||||
|
||||
type outboxRepo struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewOutboxRepository(masterPool *pgxpool.Pool) *outboxRepo {
|
||||
return &outboxRepo{
|
||||
db: masterPool,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *outboxRepo) GetQuerier(ctx context.Context) *Queries {
|
||||
tx, ok := postgres.TxFromCtx(ctx)
|
||||
if ok {
|
||||
return New(tx)
|
||||
}
|
||||
|
||||
return New(r.db)
|
||||
}
|
||||
|
||||
func (r *outboxRepo) AddEvent(ctx context.Context, evt outbox.Event) error {
|
||||
querier := r.GetQuerier(ctx)
|
||||
|
||||
return querier.OutboxInsert(ctx, &OutboxInsertParams{
|
||||
OrderID: int64(evt.OrderID),
|
||||
Topic: evt.Topic,
|
||||
Key: &evt.Key,
|
||||
Column4: evt.Payload,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *outboxRepo) WithNewEvents(ctx context.Context, limit int32, handler func(context.Context, outbox.Event) error) error {
|
||||
querier := r.GetQuerier(ctx)
|
||||
|
||||
rows, err := querier.OutboxSelectForPublish(ctx, int32(limit))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var sentIDs, errIDs []int64
|
||||
|
||||
for _, row := range rows {
|
||||
ev := outbox.Event{
|
||||
ID: row.ID,
|
||||
OrderID: entity.ID(row.OrderID),
|
||||
Topic: row.Topic,
|
||||
Key: *row.Key,
|
||||
Payload: row.Payload,
|
||||
}
|
||||
|
||||
if err := handler(ctx, ev); err != nil {
|
||||
errIDs = append(errIDs, row.ID)
|
||||
} else {
|
||||
sentIDs = append(sentIDs, row.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if len(sentIDs) > 0 {
|
||||
if _, err := querier.OutboxMarkSent(ctx, sentIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(errIDs) > 0 {
|
||||
if _, err := querier.OutboxMarkError(ctx, errIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user