0Pricing
Go Academy · Lección

Cierre ordenado

Detenga los workers correctamente

Cierre ordenado es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.

Por qué realizar un apagado ordenado

Debe indicarse a las goroutines de larga duración cuándo detenerse. El apagado ordenado permite que los workers terminen el trabajo actual, liberen recursos y salgan sin fugas ni pérdida de datos.

  • No hay fugas de goroutines
  • No hay escrituras a medio terminar
  • Salida limpia del proceso

El patrón del canal done

Un enfoque clásico es usar un canal done. Al cerrarlo, se difunde una señal de detención a todas las goroutines que lo escuchan, porque un canal cerrado devuelve inmediatamente al recibir.

done := make(chan struct{})
// ... later
close(done)

select para señales de detención

Un worker usa select para procesar un trabajo o detectar el canal done. Cuando done se cierra, se ejecuta ese caso y el worker retorna.

for {
    select {
    case <-done:
        return
    case j := <-jobs:
        process(j)
    }
}

context.Context

La herramienta moderna e idiomática es context. context.WithCancel le proporciona un contexto y una función de cancelación. Al llamar a cancel, se cierra el canal Done de los contextos.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Escuchar en ctx.Done()

Los workers hacen select sobre ctx.Done(). Cuando se llama a cancel o vence un plazo, el canal se cierra y el worker sale.

select {
case <-ctx.Done():
    return ctx.Err()
case j := <-jobs:
    process(j)
}

Esperar a los workers

Enviar la señal de detención no es suficiente; debe esperar a que los workers terminen realmente. Un sync.WaitGroup realiza su seguimiento para que main pueda bloquearse hasta que el contador llegue a cero.

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    runWorker(ctx)
}()
// ... later
cancel()
wg.Wait()

Tiempos de espera con context

context.WithTimeout cancela automáticamente después de un periodo determinado. Esto limita cuánto puede durar el apagado antes de forzar la salida.

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

Un apagado ordenado completo

Este programa ejecuta dos workers, cancela el contexto y espera a que ambos salgan correctamente antes de imprimir done.

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func worker(ctx context.Context, id int, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        select {
        case <-ctx.Done():
            fmt.Printf("worker %d stopping\n", id)
            return
        case <-time.After(50 * time.Millisecond):
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    var wg sync.WaitGroup
    for i := 1; i <= 2; i++ {
        wg.Add(1)
        go worker(ctx, i, &wg)
    }
    time.Sleep(120 * time.Millisecond)
    cancel()
    wg.Wait()
    fmt.Println("all workers stopped")
}

Agotar el trabajo en curso

Durante el apagado, a menudo querrá que los workers terminen lo que ya han comenzado. Lea los trabajos restantes en un bucle final o deje de aceptar trabajos nuevos mientras permite que terminen los actuales.

Capturar señales del sistema operativo

En servidores reales, signal.NotifyContext vincula la cancelación a SIGINT y SIGTERM. Al pulsar Ctrl+C, se activa la misma ruta de apagado ordenado que con una cancelación manual.

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

Nunca olvide cancel()

Use siempre defer cancel(), incluso al utilizar WithTimeout. Si no llama a cancel, la goroutine interna y el temporizador del contexto permanecen activos hasta que vence el plazo.

Comprobación rápida

Compruebe cuánto sabe sobre el apagado.

Recapitulación

Ha aprendido sobre el apagado ordenado:

  • Use context.WithCancel o un canal done para indicar la detención
  • Los workers hacen select sobre ctx.Done()
  • WaitGroup garantiza que todos los workers salgan realmente
  • Vincule la cancelación a las señales del sistema operativo en servidores reales
  • Use siempre defer cancel()

Preguntas frecuentes

¿La lección «Cierre ordenado» es gratis?

Sí — el texto completo de «Cierre ordenado» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Cierre ordenado»?

Detenga los workers correctamente Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Go Academy?

No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Cierre ordenado»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Go Academy?

Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Patrón de grupo de trabajadores
  2. Fan-Out y Fan-In
  3. Etapas de pipeline
  4. Cierre ordenado
← Volver a Go Academy