Sobes.tech
Назад к вопросам
Middle+
4

Live coding: добавить таймаут в функцию — если выполнение превышает 1 секунду, вернуть ошибку. Использование select, time.After, context.

Компании, где спрашивали
Веро Трейс

Ответ от нейросети

sobes.tech AI

Для добавления таймаута в функцию в Go можно использовать конструкцию с select и time.After. Также можно использовать context.WithTimeout для более гибкого управления таймаутом.

Пример с select и time.After:

package main

import (
    "errors"
    "fmt"
    "time"
)

func doWork() error {
    // Имитация длительной работы
    time.Sleep(2 * time.Second)
    return nil
}

func doWorkWithTimeout() error {
    done := make(chan error, 1)
    go func() {
        done <- doWork()
    }()

    select {
    case err := <-done:
        return err
    case <-time.After(1 * time.Second):
        return errors.New("timeout: выполнение превысило 1 секунду")
    }
}

func main() {
    err := doWorkWithTimeout()
    if err != nil {
        fmt.Println("Ошибка:", err)
    } else {
        fmt.Println("Успешно")
    }
}

Пример с использованием context.WithTimeout:

package main

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

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

func doWorkWithTimeout() error {
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()

    err := doWork(ctx)
    if err != nil {
        if errors.Is(err, context.DeadlineExceeded) {
            return errors.New("timeout: выполнение превысило 1 секунду")
        }
        return err
    }
    return nil
}

func main() {
    err := doWorkWithTimeout()
    if err != nil {
        fmt.Println("Ошибка:", err)
    } else {
        fmt.Println("Успешно")
    }
}

Оба варианта позволяют прервать выполнение функции, если оно длится дольше 1 секунды.