Вопрос охватывает методы корректного завершения работы приложения с сохранением состояния.
Для graceful shutdown используют:
context.Context для отмены операций.
sync.WaitGroup для ожидания завершения горутин.
Обработку сигналов ОС (os.Interrupt).
Шаги реализации:
Перехват сигналов:
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
cancel() // Отмена контекста при сигнале
}()Ожидание горутин:
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
<-ctx.Done() // Ждём отмены
// Завершаем работу
}()
wg.Wait()Освобождение ресурсов:
defer db.Close() // Закрытие БД и т.п.Пример:
package main
import (
"context"
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func worker(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Println("Завершение работы")
return
default:
time.Sleep(1 * time.Second)
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var wg sync.WaitGroup
wg.Add(1)
go worker(ctx, &wg)
// Ожидание SIGINT (Ctrl+C)
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT)
<-sig
cancel() // Отмена контекста
wg.Wait() // Ожидаем завершения
}Вывод:
Graceful shutdown предотвращает потерю данных и корректно освобождает ресурсы.