feat(admin): authorize batch purchase starts
This commit is contained in:
@@ -13,21 +13,27 @@ const sqliteWriteTimeout = 2 * time.Second
|
||||
type Store interface {
|
||||
CreateDraft(context.Context, Draft) (Draft, error)
|
||||
ListDrafts(context.Context) ([]Draft, error)
|
||||
ListTasks(context.Context, TaskFilter) ([]TaskRow, error)
|
||||
StartPurchases(context.Context, StartCommand, string) (StartResult, error)
|
||||
}
|
||||
type SQLiteStore struct {
|
||||
database *sql.DB
|
||||
now func() time.Time
|
||||
createGate chan struct{}
|
||||
database *sql.DB
|
||||
now func() time.Time
|
||||
writeGate chan struct{}
|
||||
policy StartPolicy
|
||||
}
|
||||
|
||||
func NewSQLiteStore(database *sql.DB) (*SQLiteStore, error) {
|
||||
if database == nil {
|
||||
return nil, errors.New("database is required")
|
||||
}
|
||||
if _, err := database.Exec("SELECT 1 FROM tasks LIMIT 1"); err != nil {
|
||||
if _, err := database.Exec("SELECT task_version, start_key, total_price_cap FROM order_authorizations LIMIT 1"); err != nil {
|
||||
return nil, fmt.Errorf("tasks migration is not available: %w", err)
|
||||
}
|
||||
return &SQLiteStore{database: database, now: time.Now, createGate: make(chan struct{}, 1)}, nil
|
||||
if _, err := database.Exec("SELECT 1 FROM purchase_attempts LIMIT 1"); err != nil {
|
||||
return nil, fmt.Errorf("single-pass migration is not available: %w", err)
|
||||
}
|
||||
return &SQLiteStore{database: database, now: time.Now, writeGate: make(chan struct{}, 1)}, nil
|
||||
}
|
||||
|
||||
func (store *SQLiteStore) CreateDraft(ctx context.Context, draft Draft) (Draft, error) {
|
||||
@@ -36,8 +42,8 @@ func (store *SQLiteStore) CreateDraft(ctx context.Context, draft Draft) (Draft,
|
||||
// SQLite permits one writer at a time. Serializing this store's short create
|
||||
// transaction prevents concurrent retries of one create key from surfacing as busy.
|
||||
select {
|
||||
case store.createGate <- struct{}{}:
|
||||
defer func() { <-store.createGate }()
|
||||
case store.writeGate <- struct{}{}:
|
||||
defer func() { <-store.writeGate }()
|
||||
case <-writeContext.Done():
|
||||
return Draft{}, writeContext.Err()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user