Вопрос проверяет умение проектировать потокобезопасные API и корректный shutdown.
Метод Close должен быть идемпотентным и потокобезопасным. Обычно используется sync.Once, mutex или atomic флаг. Это гарантирует, что ресурс будет закрыт только один раз. Остальные вызовы Close не должны приводить к ошибкам.
Компоненты в конкурентных системах часто закрываются из разных частей программы.
Определение:
Идемпотентный Close — это метод, который можно вызывать несколько раз без побочных эффектов.
Компонент должен:
Закрываться только один раз.
Не вызывать panic.
Освобождать ресурсы корректно.
Самый распространенный вариант:
type Worker struct {
once sync.Once
}
func (w *Worker) Close() {
w.once.Do(func() {
// освобождение ресурсов
})
}
Подходит для простых случаев:
if atomic.CompareAndSwapInt32(&closed, 0, 1) {
// закрытие
}
Используется, если логика сложнее:
Проверка состояния.
Закрытие.
Изменение флага.
Часто добавляют:
Context cancellation.
Канал завершения.
WaitGroup.
Безопасный Close строится вокруг идемпотентности и синхронизации, чтобы гарантировать корректное освобождение ресурсов даже при параллельных вызовах.