Concurrencia sin caos
Superpone el trabajo que espera dejando explícitos quién es dueño de qué, los límites y la cancelación.
AL TERMINAR, PODRÁS
- Distinguir concurrencia de ejecución en paralelo
- Identificar condiciones de carrera y concurrencia acotada
- Tratar la cancelación y la limpieza como parte del contrato
Descripción del diagrama: fetch A: 0–4; fetch B: 0.5–5; fetch C: 1–4 espera, 4–7; fetch D: 2–5 espera, 5–8 cancelado; 8: plazo
Superponer no es lo mismo que ejecutar al mismo tiempo
Concurrencia significa que varias tareas pueden avanzar durante periodos que se superponen.
Paralelismo significa que el trabajo se ejecuta simultáneamente. La E/S asíncrona (async I/O) puede superponer con eficiencia las esperas en sockets sin hacer más rápido el código Python que usa mucha CPU. Los threads (hilos) sirven para algunas E/S bloqueantes; los procesos pueden dar paralelismo de CPU con aislamiento y costos de comunicación.
El comportamiento exacto de los hilos en Python depende del intérprete y de cómo fue compilado, incluido si está activo el bloqueo global del intérprete (GIL). Elige según la carga de trabajo y el comportamiento de las bibliotecas, en lugar de suponer que agregar async o hilos siempre mejora la tasa de procesamiento (throughput).
El estado compartido crea preguntas de orden
Una condición de carrera (race condition) ocurre cuando la corrección depende de un orden no controlado de las operaciones.
En código asíncrono, una tarea puede ceder el control en un await y dejar que otra observe o cambie el estado compartido. Una secuencia de leer, esperar y luego escribir no es una operación atómica. Un lock (candado) puede proteger una sección crítica dentro de su alcance, pero un candado local a un proceso no coordina réplicas independientes de un servicio.
A menudo es más simple que un solo componente sea dueño de una cola mutable y que los demás se comuniquen con mensajes. Mantén pequeñas las regiones protegidas y evita bloqueos innecesarios dentro de ellas.
Acota el trabajo que inicias
Iniciar una tarea por cada trabajo que llega puede agotar la memoria, las conexiones o la capacidad de una dependencia.
Usa una cola acotada y una cantidad fija de workers, o un semáforo con una política de admisión acotada. La cancelación es una petición para detenerse, no una evidencia de que un efecto externo no ocurrió. La limpieza debe liberar recursos y dejar el trabajo en un estado recuperable.
Los ciclos de vida estructurados de las tareas ayudan a asegurar que el trabajo lanzado termine o se cancele antes de que acabe el alcance que lo creó. Define cómo deja Relay de aceptar trabajo, cómo vacía las tareas activas y cómo maneja los trabajos reservados (claimed) que quedaron sin terminar.
ERROR FRECUENTE
Un semáforo puede limitar las llamadas activas mientras una cantidad ilimitada de tareas en espera sigue consumiendo memoria. Acota también la admisión.
INTÉNTALO TÚ
Bosqueja un pool de workers con cuatro manejadores activos y una cola con capacidad de veinte. Define qué ve el envío número veinticinco que espera y cómo trata el apagado al trabajo activo.
Decide en el laboratorio.
El checkpoint de dos preguntas, tus notas y tu progreso guardado están en el laboratorio. Gratis y sin cuenta.
Abrir en el laboratorio ↗CONÉCTALO CON RELAY
Dale a Relay un pool de workers acotado y una secuencia de apagado documentada. Prueba la cancelación mientras un trabajo espera y mientras se ejecuta.