Sobes.tech
Senior

// η υπηρεσία χρησιμοποιεί εξωτερικό API για την κατασκευή διαδρομών, // εντός της τιμής έχουμε περιορισμό RPS. // Πρέπει να σχεδιάσουμε έναν rate limiter. // 100 rps type RouteClient struct { limiter } func (rc *RouteClient) Get(req string) string { // πρέπει να γίνει return rc.get(req) }

sobes.tech AI

Απάντηση από AI

Для реализации rate limiter с ограничением 100 RPS (requests per second) можно использовать токен-бакет или счетчик с таймером. В Go удобно использовать канал или библиотеку golang.org/x/time/rate.

Пример с использованием rate.Limiter из стандартной библиотеки:

import (
    "golang.org/x/time/rate"
    "time"
)

type RouteClient struct {
    limiter *rate.Limiter
}

func NewRouteClient() *RouteClient {
    // 100 запросов в секунду
    limiter := rate.NewLimiter(100, 100) // burst равен 100
    return &RouteClient{limiter: limiter}
}

func (rc *RouteClient) Get(req string) string {
    // Ждем разрешения на запрос
    err := rc.limiter.Wait(context.Background())
    if err != nil {
        // обработка ошибки, например, таймаут
        return "error: rate limit"
    }
    return rc.get(req)
}

func (rc *RouteClient) get(req string) string {
    // Вызов внешнего API
    return "response"
}

Такой лимитер гарантирует, что не будет превышено 100 запросов в секунду, при этом позволяет делать кратковременные всплески (burst) до 100 запросов.