Sobes.tech
Middle+

// We have a method for retrieving product information, this method is called very frequently // Are there any problems in this code and how to fix them? PostgreSQL database func (r *ProductRepository) GetProductDetails(ctx context.Context, productIDs []int) []Product { products := make([]Product, 0, len(productIDs)) for _, id := range productIDs { go func(id int) { var p Product query := "SELECT name, price, description FROM products WHERE id = $1" err := r.db.QueryRowContext(ctx, query, id).Scan(&p.Name, &p.Price, &p.Desc) if err != nil { r.logger.Error("error get product", "err", err) return } products = append(products, p) }(id) } return products }

sobes.tech AI

Answer from AI

The provided code has several issues:

  1. Parallel addition to the products slice without synchronization — this can lead to data races and potential slice corruption.
  2. Launching goroutines for each ID without controlling the number of concurrently running goroutines can overload the database.
  3. The method returns the slice immediately, without waiting for goroutines to finish, so the result will always be empty.

How to fix:

  • Use a single SQL query with the IN operator to fetch all products in one call, which is more efficient and simpler.
  • If parallel execution is needed, use sync.WaitGroup and a mutex for safe addition to the slice.

Example of a fixed version with a single query:

func (r *ProductRepository) GetProductDetails(ctx context.Context, productIDs []int) ([]Product, error) {
    query := `SELECT id, name, price, description FROM products WHERE id = ANY($1)`
    rows, err := r.db.QueryContext(ctx, query, pq.Array(productIDs))
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var products []Product
    for rows.Next() {
        var p Product
        if err := rows.Scan(&p.ID, &p.Name, &p.Price, &p.Desc); err != nil {
            return nil, err
        }
        products = append(products, p)
    }
    return products, nil
}

This approach reduces the load on the database and eliminates issues with concurrent access.

// We have a method for retrieving product… - sobes.tech