0Pricing
Go Academy · Lekcja

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

  1. Planowanie oparte na czasie
  2. Biblioteka robfig/cron
  3. Tickery do obsługi interwałów
  4. Kontrolowane zatrzymywanie zadań
← Powrót do Go Academy