Sobes.tech
Middle — Senior

Как да реализираме логиката за автоматично отхвърляне на обаждания при повече от 10 обаждания за 15 минути от потребител?

sobes.tech AI

Отговор от AI

За реализиране на логиката за автоматично отхвърляне на обаждания, когато има повече от 10 обаждания за 15 минути от един потребител, може да се използва движещо се времево окно и брояч на обажданията. Основната идея е да се съхранят времевите марки на обажданията на потребителя и при ново обаждане да се проверява колко обаждания е имало през последните 15 минути.

Пример на Go:

package main

import (
    "fmt"
    "sync"
    "time"
)

type CallTracker struct {
    mu       sync.Mutex
    callsMap map[string][]time.Time // ключ — ID на потребителя, стойност — срез от времеви марки на обаждания
}

func NewCallTracker() *CallTracker {
    return &CallTracker{
        callsMap: make(map[string][]time.Time),
    }
}

func (ct *CallTracker) RegisterCall(userID string) bool {
    ct.mu.Lock()
    defer ct.mu.Unlock()

    now := time.Now()
    windowStart := now.Add(-15 * time.Minute)

    calls := ct.callsMap[userID]
    // Оставяме само обаждания в прозореца от 15 минути
    var recentCalls []time.Time
    for _, t := range calls {
        if t.After(windowStart) {
            recentCalls = append(recentCalls, t)
        }
    }

    if len(recentCalls) >= 10 {
        // Автоматично отхвърляне
        return false
    }

    // Добавяме текущото обаждане
    recentCalls = append(recentCalls, now)
    ct.callsMap[userID] = recentCalls
    return true
}

func main() {
    tracker := NewCallTracker()
    userID := "user123"

    for i := 0; i < 12; i++ {
        allowed := tracker.RegisterCall(userID)
        if allowed {
            fmt.Println("Обаждането е прието")
        } else {
            fmt.Println("Обаждането е отказано")
        }
        time.Sleep(1 * time.Minute)
    }
}