Kontrolowane zatrzymywanie zadań
Poprawnie zatrzymuj zadania
Kontrolowane zatrzymywanie zadań to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.
Uporządkowane zatrzymywanie zadań
Scheduler zatrzymany w trakcie wykonywania zadania może uszkodzić dane albo pozostawić niedokończoną pracę. Łagodne zamykanie oznacza: zaprzestanie przyjmowania nowych uruchomień, pozwolenie na dokończenie zadań będących w toku (do określonego terminu), a następnie zakończenie działania.
Nasłuchiwanie sygnałów
Należy przechwytywać sygnały systemu operacyjnego, takie jak SIGINT (Ctrl+C) i SIGTERM (zatrzymanie przez orkiestrator), aby móc celowo zamknąć aplikację.
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
fmt.Println("shutting down")signal.NotifyContext
Od wersji Go 1.16 dostępna jest wygodna funkcja pomocnicza, która anuluje context po nadejściu sygnału.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
<-ctx.Done()Zatrzymywanie schedulera
W bibliotece robfig/cron wywołanie c.Stop() zwraca context, który zostaje zakończony po ukończeniu wszystkich uruchomionych zadań. Należy na niego zaczekać, aby pozwolić zadaniom się zakończyć.
ctx := c.Stop() // stops scheduling, returns ctx
<-ctx.Done() // wait for running jobs
fmt.Println("all jobs finished")Przekazywanie anulowania do zadań
Do każdego zadania należy przekazać context, aby długo trwająca praca mogła szybko się przerwać po rozpoczęciu zamykania.
func job(ctx context.Context) {
select {
case <-time.After(time.Hour):
case <-ctx.Done():
return // bail out early
}
}Ograniczenie czasu oczekiwania
Nie należy czekać w nieskończoność na zablokowane zadania. Należy użyć contextu z limitem czasu, aby zamykanie zakończyło się nawet wtedy, gdy zadanie się zawiesi.
shutCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()WaitGroup dla własnych schedulerów
Jeśli scheduler jest tworzony samodzielnie za pomocą goroutines, należy śledzić je przy użyciu sync.WaitGroup i wywołać Wait() podczas zamykania.
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done(); doWork() }()
// shutdown:
wg.Wait()Unikanie rozpoczynania nowej pracy
Po rozpoczęciu zamykania ticker lub cron musi przestać generować uruchomienia. Zamknięcie kanału done albo anulowanie contextu gwarantuje, że pętla odbierze sygnał i przestanie planować nowe uruchomienia.
Idempotencja pomaga
Zadania należy projektować tak, aby można je było bezpiecznie uruchamiać ponownie. Jeśli zadanie zostanie przerwane w połowie i ponowione po restarcie, logika idempotentna zapobiegnie powielonym skutkom, takim jak wysłanie podwójnych wiadomości e-mail lub podwójne naliczenie opłat.
Pełny schemat
Po połączeniu wszystkich elementów otrzymujemy context reagujący na sygnał, wywołanie Stop crona zwracające context oczekiwania na zakończenie oraz limitowany czas oczekiwania. Jest to standardowy szkielet łagodnego zamykania usług wykonujących zadania według harmonogramu.
Program do uruchomienia: łagodne zatrzymywanie za pomocą contextu
Ten samodzielny program uruchamia okresowego workera i łagodnie go zatrzymuje przez anulowanie contextu, czekając na zakończenie tyknięcia będącego w toku.
package main
import (
"context"
"fmt"
"sync"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
t := time.NewTicker(5 * time.Millisecond)
defer t.Stop()
for {
select {
case <-t.C:
fmt.Println("working")
case <-ctx.Done():
fmt.Println("stopping cleanly")
return
}
}
}()
time.Sleep(17 * time.Millisecond)
cancel() // signal shutdown
wg.Wait() // wait for worker to finish
fmt.Println("shutdown complete")
}Szybkie sprawdzenie
Proszę sprawdzić zrozumienie łagodnego zamykania zadań.
Podsumowanie
Opanowano łagodne zamykanie zadań:
- Należy przechwytywać SIGINT/SIGTERM, najlepiej za pomocą
signal.NotifyContext cron.Stop()zwraca context, który czeka na zakończenie uruchomionych zadań- Należy przekazywać context do zadań i ograniczać czas oczekiwania za pomocą timeoutu
- Zadania powinny być idempotentne, aby ich ponowienie było bezpieczne
Często zadawane pytania
Czy lekcja „Kontrolowane zatrzymywanie zadań” jest bezpłatna?
Tak — pełny tekst „Kontrolowane zatrzymywanie zadań” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Kontrolowane zatrzymywanie zadań”?
Poprawnie zatrzymuj zadania Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Go Academy?
Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Kontrolowane zatrzymywanie zadań”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?
Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Planowanie oparte na czasie
- Biblioteka robfig/cron
- Tickery do obsługi interwałów
- Kontrolowane zatrzymywanie zadań