ProgrammazioneSviluppatore Go

Cosa devi sapere su come lavorare con time.Timer e time.Ticker in Go? Quali sono le differenze chiave, le caratteristiche di un uso corretto e gli errori comuni durante il loro stop/reset?

Supera i colloqui con l'assistente IA Hintsage

Risposta

Il pacchetto time fornisce due strumenti utili: Timer e Ticker.

  • Timer è usato per un ritardo singolo (si attiva una sola volta dopo un certo tempo).
  • Ticker — per eventi periodici regolari (intervallo).

Differenze chiave:

  • Timer dopo l'attivazione "si spegne", deve essere ripristinato (Reset) per essere utilizzato di nuovo.
  • Ticker genera eventi finché non viene esplicitamente fermato con il metodo Stop().

Caratteristiche d’uso:

  • Chiama sempre Stop() su Timer/Ticker al termine dell'uso per evitare perdite di risorse.
  • Dopo aver chiamato Stop() su un Timer, potrebbe essere necessario "svuotare" il canale: se il timer è scattato prima di Stop(), è obbligatorio leggere dal canale.

Esempio di utilizzo corretto di Timer:

t := time.NewTimer(2 * time.Second) defer t.Stop() // obbligatorio! select { case <-t.C: fmt.Println("Il tempo è scaduto!") case <-otherDone: if !t.Stop() { <-t.C // svuota il canale se necessario } }

Domanda trabocchetto

È possibile riutilizzare immediatamente un Timer dopo aver ricevuto un valore dal canale t.C? Cosa succede se non si chiama t.Stop()?

Risposta: Il timer non deve essere immediatamente ripristinato senza aver chiamato Stop() e senza aver potenzialmente letto dal canale. Se non si chiama t.Stop(), potrebbe rimanere una goroutine "morta" o un trigger imprevisto nel ciclo successivo (il canale non è stato svuotato). Utilizzo corretto: chiama Stop(), e se Stop() restituisce false — assicurati di svuotare il canale leggendo da t.C.

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature del tema


Storia

Nel servizio di notifiche di una startup, i timer venivano utilizzati per ripristinare i tentativi di consegna. Dopo l'attivazione, venivano immediatamente ripristinati senza essere fermati — risultato: il numero di goroutine aumentava, il processo "perdeva" memoria e il sistema si bloccava a causa di carenza di memoria.

Storia

In un grande progetto e-commerce veniva utilizzato un Ticker per gli aggiornamenti periodici del prodotto, che non veniva arrestato al termine dell'handler. L'handler "rimaneva" anche dopo che l'utente era stato rimosso, continuando a consumare CPU.

Storia

Nei test non veniva chiamato Stop() per il timer — i test si bloccavano in modo casuale perché il canale del timer non veniva liberato, si aspettava un secondo "ping" dal timer, che non arrivava mai.