Контекст с таймаутом

К задачам
Средняя
Concurrency

Условие задачи

Реализуй долгую задачу (например, time.Sleep на 5 секунд). Оберни её в контекст с таймаутом 2 секунды. Если задача не успеет завершиться, выведи "Timeout!" — иначе "Completed".

package main

import (
    "context"
    "fmt"
    "time"
)

func doSomething(ctx context.Context) error {
    // TODO: эмулируй долгую задачу и возвращай ошибку при таймауте
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    err := doSomething(ctx)
    if err != nil {
        fmt.Println("Timeout!")
    } else {
        fmt.Println("Completed")
    }
}
package main

import (
    "context"
    "fmt"
    "time"
)

func doSomething(ctx context.Context) error {
    // TODO: эмулируй долгую задачу и возвращай ошибку при таймауте
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    err := doSomething(ctx)
    if err != nil {
        fmt.Println("Timeout!")
    } else {
        fmt.Println("Completed")
    }
}

Подсказка

- Используй select с <-ctx.Done() и таймером через time.After или time.Sleep. - После таймаута ctx.Err() вернёт context.DeadlineExceeded.

Решение

Контекст с таймаутом — мощный инструмент ограничения по времени. Он позволяет избегать зависаний и таймаутов в API/БД/сетевых вызовах.

package main

import (
    "context"
    "fmt"
    "time"
)

func doSomething(ctx context.Context) error {
    select {
    case <-time.After(5 * time.Second):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    err := doSomething(ctx)
    if err != nil {
        fmt.Println("Timeout!")
    } else {
        fmt.Println("Completed")
    }
}
package main

import (
    "context"
    "fmt"
    "time"
)

func doSomething(ctx context.Context) error {
    select {
    case <-time.After(5 * time.Second):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    err := doSomething(ctx)
    if err != nil {
        fmt.Println("Timeout!")
    } else {
        fmt.Println("Completed")
    }
}