Changeset 645 in code for trunk/db_postgres.go


Ignore:
Timestamp:
Oct 15, 2021, 8:39:14 PM (4 years ago)
Author:
hubert
Message:

Set hard timeouts on DB transactions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/db_postgres.go

    r640 r645  
    22
    33import (
     4        "context"
    45        "database/sql"
    56        "errors"
     
    1112        _ "github.com/lib/pq"
    1213)
     14
     15const postgresQueryTimeout = 5 * time.Second
    1316
    1417const postgresConfigSchema = `
     
    146149
    147150func (db *PostgresDB) Stats() (*DatabaseStats, error) {
     151        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     152        defer cancel()
     153
    148154        var stats DatabaseStats
    149         row := db.db.QueryRow(`SELECT
     155        row := db.db.QueryRowContext(ctx, `SELECT
    150156                (SELECT COUNT(*) FROM "User") AS users,
    151157                (SELECT COUNT(*) FROM "Network") AS networks,
     
    159165
    160166func (db *PostgresDB) ListUsers() ([]User, error) {
    161         rows, err := db.db.Query(`SELECT id, username, password, admin, realname FROM "User"`)
     167        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     168        defer cancel()
     169
     170        rows, err := db.db.QueryContext(ctx,
     171                `SELECT id, username, password, admin, realname FROM "User"`)
    162172        if err != nil {
    163173                return nil, err
     
    184194
    185195func (db *PostgresDB) GetUser(username string) (*User, error) {
     196        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     197        defer cancel()
     198
    186199        user := &User{Username: username}
    187200
    188201        var password, realname sql.NullString
    189         row := db.db.QueryRow(
     202        row := db.db.QueryRowContext(ctx,
    190203                `SELECT id, password, admin, realname FROM "User" WHERE username = $1`,
    191204                username)
     
    199212
    200213func (db *PostgresDB) StoreUser(user *User) error {
     214        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     215        defer cancel()
     216
    201217        password := toNullString(user.Password)
    202218        realname := toNullString(user.Realname)
     
    204220        var err error
    205221        if user.ID == 0 {
    206                 err = db.db.QueryRow(`
     222                err = db.db.QueryRowContext(ctx, `
    207223                        INSERT INTO "User" (username, password, admin, realname)
    208224                        VALUES ($1, $2, $3, $4)
     
    210226                        user.Username, password, user.Admin, realname).Scan(&user.ID)
    211227        } else {
    212                 _, err = db.db.Exec(`
     228                _, err = db.db.ExecContext(ctx, `
    213229                        UPDATE "User"
    214230                        SET password = $1, admin = $2, realname = $3
     
    220236
    221237func (db *PostgresDB) DeleteUser(id int64) error {
    222         _, err := db.db.Exec(`DELETE FROM "User" WHERE id = $1`, id)
     238        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     239        defer cancel()
     240
     241        _, err := db.db.ExecContext(ctx, `DELETE FROM "User" WHERE id = $1`, id)
    223242        return err
    224243}
    225244
    226245func (db *PostgresDB) ListNetworks(userID int64) ([]Network, error) {
    227         rows, err := db.db.Query(`
     246        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     247        defer cancel()
     248
     249        rows, err := db.db.QueryContext(ctx, `
    228250                SELECT id, name, addr, nick, username, realname, pass, connect_commands, sasl_mechanism,
    229251                        sasl_plain_username, sasl_plain_password, sasl_external_cert, sasl_external_key, enabled
     
    266288
    267289func (db *PostgresDB) StoreNetwork(userID int64, network *Network) error {
     290        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     291        defer cancel()
     292
    268293        netName := toNullString(network.Name)
    269294        netUsername := toNullString(network.Username)
     
    290315        var err error
    291316        if network.ID == 0 {
    292                 err = db.db.QueryRow(`
     317                err = db.db.QueryRowContext(ctx, `
    293318                        INSERT INTO "Network" ("user", name, addr, nick, username, realname, pass, connect_commands,
    294319                                sasl_mechanism, sasl_plain_username, sasl_plain_password, sasl_external_cert,
     
    300325                        network.SASL.External.PrivKeyBlob, network.Enabled).Scan(&network.ID)
    301326        } else {
    302                 _, err = db.db.Exec(`
     327                _, err = db.db.ExecContext(ctx, `
    303328                        UPDATE "Network"
    304329                        SET name = $2, addr = $3, nick = $4, username = $5, realname = $6, pass = $7,
     
    315340
    316341func (db *PostgresDB) DeleteNetwork(id int64) error {
    317         _, err := db.db.Exec(`DELETE FROM "Network" WHERE id = $1`, id)
     342        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     343        defer cancel()
     344
     345        _, err := db.db.ExecContext(ctx, `DELETE FROM "Network" WHERE id = $1`, id)
    318346        return err
    319347}
    320348
    321349func (db *PostgresDB) ListChannels(networkID int64) ([]Channel, error) {
    322         rows, err := db.db.Query(`
     350        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     351        defer cancel()
     352
     353        rows, err := db.db.QueryContext(ctx, `
    323354                SELECT id, name, key, detached, detached_internal_msgid, relay_detached, reattach_on, detach_after,
    324355                        detach_on
     
    351382
    352383func (db *PostgresDB) StoreChannel(networkID int64, ch *Channel) error {
     384        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     385        defer cancel()
     386
    353387        key := toNullString(ch.Key)
    354388        detachAfter := int64(math.Ceil(ch.DetachAfter.Seconds()))
     
    356390        var err error
    357391        if ch.ID == 0 {
    358                 err = db.db.QueryRow(`
     392                err = db.db.QueryRowContext(ctx, `
    359393                        INSERT INTO "Channel" (network, name, key, detached, detached_internal_msgid, relay_detached, reattach_on,
    360394                                detach_after, detach_on)
     
    364398                        ch.RelayDetached, ch.ReattachOn, detachAfter, ch.DetachOn).Scan(&ch.ID)
    365399        } else {
    366                 _, err = db.db.Exec(`
     400                _, err = db.db.ExecContext(ctx, `
    367401                        UPDATE "Channel"
    368402                        SET name = $2, key = $3, detached = $4, detached_internal_msgid = $5,
     
    376410
    377411func (db *PostgresDB) DeleteChannel(id int64) error {
    378         _, err := db.db.Exec(`DELETE FROM "Channel" WHERE id = $1`, id)
     412        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     413        defer cancel()
     414
     415        _, err := db.db.ExecContext(ctx, `DELETE FROM "Channel" WHERE id = $1`, id)
    379416        return err
    380417}
    381418
    382419func (db *PostgresDB) ListDeliveryReceipts(networkID int64) ([]DeliveryReceipt, error) {
    383         rows, err := db.db.Query(`
     420        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     421        defer cancel()
     422
     423        rows, err := db.db.QueryContext(ctx, `
    384424                SELECT id, target, client, internal_msgid
    385425                FROM "DeliveryReceipt"
     
    406446
    407447func (db *PostgresDB) StoreClientDeliveryReceipts(networkID int64, client string, receipts []DeliveryReceipt) error {
     448        ctx, cancel := context.WithTimeout(context.TODO(), postgresQueryTimeout)
     449        defer cancel()
     450
    408451        tx, err := db.db.Begin()
    409452        if err != nil {
     
    412455        defer tx.Rollback()
    413456
    414         _, err = tx.Exec(`DELETE FROM "DeliveryReceipt" WHERE network = $1 AND client = $2`,
     457        _, err = tx.ExecContext(ctx,
     458                `DELETE FROM "DeliveryReceipt" WHERE network = $1 AND client = $2`,
    415459                networkID, client)
    416460        if err != nil {
     
    418462        }
    419463
    420         stmt, err := tx.Prepare(`
     464        stmt, err := tx.PrepareContext(ctx, `
    421465                INSERT INTO "DeliveryReceipt" (network, target, client, internal_msgid)
    422466                VALUES ($1, $2, $3, $4)
     
    429473        for i := range receipts {
    430474                rcpt := &receipts[i]
    431                 err := stmt.QueryRow(networkID, rcpt.Target, client, rcpt.InternalMsgID).Scan(&rcpt.ID)
     475                err := stmt.
     476                        QueryRowContext(ctx, networkID, rcpt.Target, client, rcpt.InternalMsgID).
     477                        Scan(&rcpt.ID)
    432478                if err != nil {
    433479                        return err
Note: See TracChangeset for help on using the changeset viewer.