Changeset 645 in code


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

Set hard timeouts on DB transactions

Location:
trunk
Files:
2 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
  • trunk/db_sqlite.go

    r620 r645  
    22
    33import (
     4        "context"
    45        "database/sql"
    56        "fmt"
     
    1112        _ "github.com/mattn/go-sqlite3"
    1213)
     14
     15const sqliteQueryTimeout = 5 * time.Second
    1316
    1417const sqliteSchema = `
     
    210213        defer db.lock.RUnlock()
    211214
     215        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     216        defer cancel()
     217
    212218        var stats DatabaseStats
    213         row := db.db.QueryRow(`SELECT
     219        row := db.db.QueryRowContext(ctx, `SELECT
    214220                (SELECT COUNT(*) FROM User) AS users,
    215221                (SELECT COUNT(*) FROM Network) AS networks,
     
    233239        defer db.lock.RUnlock()
    234240
    235         rows, err := db.db.Query("SELECT id, username, password, admin, realname FROM User")
     241        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     242        defer cancel()
     243
     244        rows, err := db.db.QueryContext(ctx,
     245                "SELECT id, username, password, admin, realname FROM User")
    236246        if err != nil {
    237247                return nil, err
     
    261271        defer db.lock.RUnlock()
    262272
     273        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     274        defer cancel()
     275
    263276        user := &User{Username: username}
    264277
    265278        var password, realname sql.NullString
    266         row := db.db.QueryRow("SELECT id, password, admin, realname FROM User WHERE username = ?", username)
     279        row := db.db.QueryRowContext(ctx,
     280                "SELECT id, password, admin, realname FROM User WHERE username = ?",
     281                username)
    267282        if err := row.Scan(&user.ID, &password, &user.Admin, &realname); err != nil {
    268283                return nil, err
     
    276291        db.lock.Lock()
    277292        defer db.lock.Unlock()
     293
     294        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     295        defer cancel()
    278296
    279297        args := []interface{}{
     
    286304        var err error
    287305        if user.ID != 0 {
    288                 _, err = db.db.Exec("UPDATE User SET password = :password, admin = :admin, realname = :realname WHERE username = :username", args...)
     306                _, err = db.db.ExecContext(ctx, `
     307                        UPDATE User SET password = :password, admin = :admin,
     308                                realname = :realname WHERE username = :username`,
     309                        args...)
    289310        } else {
    290311                var res sql.Result
    291                 res, err = db.db.Exec("INSERT INTO User(username, password, admin, realname) VALUES (:username, :password, :admin, :realname)", args...)
     312                res, err = db.db.ExecContext(ctx, `
     313                        INSERT INTO
     314                        User(username, password, admin, realname)
     315                        VALUES (:username, :password, :admin, :realname)`,
     316                        args...)
    292317                if err != nil {
    293318                        return err
     
    303328        defer db.lock.Unlock()
    304329
     330        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     331        defer cancel()
     332
    305333        tx, err := db.db.Begin()
    306334        if err != nil {
     
    309337        defer tx.Rollback()
    310338
    311         _, err = tx.Exec(`DELETE FROM DeliveryReceipt
     339        _, err = tx.ExecContext(ctx, `DELETE FROM DeliveryReceipt
    312340                WHERE id IN (
    313341                        SELECT DeliveryReceipt.id
     
    320348        }
    321349
    322         _, err = tx.Exec(`DELETE FROM Channel
     350        _, err = tx.ExecContext(ctx, `DELETE FROM Channel
    323351                WHERE id IN (
    324352                        SELECT Channel.id
     
    331359        }
    332360
    333         _, err = tx.Exec("DELETE FROM Network WHERE user = ?", id)
    334         if err != nil {
    335                 return err
    336         }
    337 
    338         _, err = tx.Exec("DELETE FROM User WHERE id = ?", id)
     361        _, err = tx.ExecContext(ctx, "DELETE FROM Network WHERE user = ?", id)
     362        if err != nil {
     363                return err
     364        }
     365
     366        _, err = tx.ExecContext(ctx, "DELETE FROM User WHERE id = ?", id)
    339367        if err != nil {
    340368                return err
     
    348376        defer db.lock.RUnlock()
    349377
    350         rows, err := db.db.Query(`SELECT id, name, addr, nick, username, realname, pass,
     378        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     379        defer cancel()
     380
     381        rows, err := db.db.QueryContext(ctx, `
     382                SELECT id, name, addr, nick, username, realname, pass,
    351383                        connect_commands, sasl_mechanism, sasl_plain_username, sasl_plain_password,
    352384                        sasl_external_cert, sasl_external_key, enabled
     
    392424        db.lock.Lock()
    393425        defer db.lock.Unlock()
     426
     427        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     428        defer cancel()
    394429
    395430        var saslMechanism, saslPlainUsername, saslPlainPassword sql.NullString
     
    430465        var err error
    431466        if network.ID != 0 {
    432                 _, err = db.db.Exec(`
     467                _, err = db.db.ExecContext(ctx, `
    433468                        UPDATE Network
    434469                        SET name = :name, addr = :addr, nick = :nick, username = :username,
     
    440475        } else {
    441476                var res sql.Result
    442                 res, err = db.db.Exec(`
     477                res, err = db.db.ExecContext(ctx, `
    443478                        INSERT INTO Network(user, name, addr, nick, username, realname, pass,
    444479                                connect_commands, sasl_mechanism, sasl_plain_username,
     
    460495        defer db.lock.Unlock()
    461496
     497        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     498        defer cancel()
     499
    462500        tx, err := db.db.Begin()
    463501        if err != nil {
     
    466504        defer tx.Rollback()
    467505
    468         _, err = tx.Exec("DELETE FROM DeliveryReceipt WHERE network = ?", id)
    469         if err != nil {
    470                 return err
    471         }
    472 
    473         _, err = tx.Exec("DELETE FROM Channel WHERE network = ?", id)
    474         if err != nil {
    475                 return err
    476         }
    477 
    478         _, err = tx.Exec("DELETE FROM Network WHERE id = ?", id)
     506        _, err = tx.ExecContext(ctx, "DELETE FROM DeliveryReceipt WHERE network = ?", id)
     507        if err != nil {
     508                return err
     509        }
     510
     511        _, err = tx.ExecContext(ctx, "DELETE FROM Channel WHERE network = ?", id)
     512        if err != nil {
     513                return err
     514        }
     515
     516        _, err = tx.ExecContext(ctx, "DELETE FROM Network WHERE id = ?", id)
    479517        if err != nil {
    480518                return err
     
    488526        defer db.lock.RUnlock()
    489527
    490         rows, err := db.db.Query(`SELECT
     528        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     529        defer cancel()
     530
     531        rows, err := db.db.QueryContext(ctx, `SELECT
    491532                        id, name, key, detached, detached_internal_msgid,
    492533                        relay_detached, reattach_on, detach_after, detach_on
     
    521562        db.lock.Lock()
    522563        defer db.lock.Unlock()
     564
     565        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     566        defer cancel()
    523567
    524568        args := []interface{}{
     
    538582        var err error
    539583        if ch.ID != 0 {
    540                 _, err = db.db.Exec(`UPDATE Channel
     584                _, err = db.db.ExecContext(ctx, `UPDATE Channel
    541585                        SET network = :network, name = :name, key = :key, detached = :detached,
    542586                                detached_internal_msgid = :detached_internal_msgid, relay_detached = :relay_detached,
     
    545589        } else {
    546590                var res sql.Result
    547                 res, err = db.db.Exec(`INSERT INTO Channel(network, name, key, detached, detached_internal_msgid, relay_detached, reattach_on, detach_after, detach_on)
     591                res, err = db.db.ExecContext(ctx, `INSERT INTO Channel(network, name, key, detached, detached_internal_msgid, relay_detached, reattach_on, detach_after, detach_on)
    548592                        VALUES (:network, :name, :key, :detached, :detached_internal_msgid, :relay_detached, :reattach_on, :detach_after, :detach_on)`, args...)
    549593                if err != nil {
     
    559603        defer db.lock.Unlock()
    560604
    561         _, err := db.db.Exec("DELETE FROM Channel WHERE id = ?", id)
     605        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     606        defer cancel()
     607
     608        _, err := db.db.ExecContext(ctx, "DELETE FROM Channel WHERE id = ?", id)
    562609        return err
    563610}
     
    567614        defer db.lock.RUnlock()
    568615
    569         rows, err := db.db.Query(`SELECT id, target, client, internal_msgid
     616        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     617        defer cancel()
     618
     619        rows, err := db.db.QueryContext(ctx, `
     620                SELECT id, target, client, internal_msgid
    570621                FROM DeliveryReceipt
    571622                WHERE network = ?`, networkID)
     
    596647        defer db.lock.Unlock()
    597648
     649        ctx, cancel := context.WithTimeout(context.TODO(), sqliteQueryTimeout)
     650        defer cancel()
     651
    598652        tx, err := db.db.Begin()
    599653        if err != nil {
     
    602656        defer tx.Rollback()
    603657
    604         _, err = tx.Exec("DELETE FROM DeliveryReceipt WHERE network = ? AND client IS ?",
     658        _, err = tx.ExecContext(ctx, "DELETE FROM DeliveryReceipt WHERE network = ? AND client IS ?",
    605659                networkID, toNullString(client))
    606660        if err != nil {
     
    611665                rcpt := &receipts[i]
    612666
    613                 res, err := tx.Exec(`INSERT INTO DeliveryReceipt(network, target, client, internal_msgid)
     667                res, err := tx.ExecContext(ctx, `
     668                        INSERT INTO DeliveryReceipt(network, target, client, internal_msgid)
    614669                        VALUES (:network, :target, :client, :internal_msgid)`,
    615670                        sql.Named("network", networkID),
Note: See TracChangeset for help on using the changeset viewer.