1

I don’t understand why this is happening. I’m using the Go database package to connect to a PostgreSQL database. I loop through fullmsg (88 messages), but after processing about 27 messages, UpdateSyncId stops returning anything and my code hangs

sampleservice.go

func (s *SampleService) SomeFunction(
    ctx context.Context,
    userId uuid.UUID,

) error {

    for _, msg := range fullMsgs {
        /*
        some operations here
    */
    
        syncId := strconv.FormatUint(msg.SyncId, 10)
    if err := s.UserService.UpdateSyncId(ctx, userId, syncId); err != nil {
        return fmt.Errorf("failed to update syncid: %v", msg.ID, err)
    }
    }
    return nil
    }

userservice.go:

func (s *Userservice) UpdateSyncId(ctx context.Context, userID uuid.UUID, syncId string) error {
    return s.UserRepo.UpdateSyncId(ctx, userID, syncId)
}

userrepo.go


func (r *userRepo) UpdateSyncId(ctx context.Context, userID uuid.UUID, maxHistoryId string) error {
    // The table structure is assumed to be a 'users' table or a dedicated 'sync_state' table.
    // We will assume a 'users' table which has a column for the last processed SyncId.
    query := `
        UPDATE 
            users
        SET 
            sync_id = $1
        WHERE 
            id = $2
    `

    // Execute the update query
    result, err := r.DB.ExecContext(ctx, query, maxHistoryId, userID)
    if err != nil {
        return fmt.Errorf("failed to execute update for user sync id: %w", err)
    }

    // Optional: Check if exactly one row was updated
    rowsAffected, err := result.RowsAffected()
    if err != nil {
        return fmt.Errorf("could not retrieve rows affected after sync id update: %w", err)
    }

    if rowsAffected == 0 {
        return fmt.Errorf("theres no user with that id %s", err)
    }

    return nil
}

i dont know why it is happening, i've created custom interface for db operation, but i dont think that is the cause.
here's my custom interface implementation for sql/db operations that i use.

type IPsqlDb interface {
    
QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
    
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
    

ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
    
QueryRow(query string, args ...interface{}) *sql.Row
    
Query(query string, args ...interface{}) (*sql.Rows, error)
    
Exec(query string, args ...interface{}) (sql.Result, error)
}


var (
    _ IPsqlDb = (*sql.DB)(nil)
    _ IPsqlDb = (*sql.Tx)(nil)
)
4
  • 2
    What is the state of the hanging backend in pg_stat_activity? Any wait_event? Commented Nov 16 at 11:05
  • 1
    @Laurenz Albe man thanks, you save my life, when i checked pg_stat_activity I saw a bunch of queries waiting for result, but actual reason for that i use db.QueryRow() in insert statement instead of db.Exec() Since the INSERT wasn’t supposed to return a row, QueryRow() caused the query to wait indefinitely, which led to the blocking. Switching to db.Exec() fixed the problem. Commented Nov 16 at 11:28
  • 1
    @Laurenz Albe i mean it wasnt caused by UpdateSyncId function, it was caused by another Insert function inside for loop which I didn’t include in the code above. Commented Nov 16 at 11:34
  • 2
    You could write an answer to your own question; that might help others. Commented Nov 16 at 17:03

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.