0

High Speed #1: El Arte de No Hacer Nada (Rápido): Wait Strategies

Imagina que eres un guardia de seguridad esperando que llegue un camión. Tienes dos opciones:

  1. Sentarte en una silla y pedir que te llamen al móvil cuando llegue el camión (Blocking). Duermes un poco, ahorras energía, pero tardas en despertarte.
  2. Quedarte de pie, pegado a la valla, mirando fijamente la carretera sin parpadear ni un segundo (Busy Spinning). Estás agotado a los 10 minutos, pero reaccionas en nanosegundos.

En .NET, elegir la estrategia correcta define cuánta CPU vas a «quemar» a cambio de velocidad pura.

Configurando el «Modo Bestia» en C#

El Disruptor nos permite elegir qué tan agresivos queremos ser. Aquí te muestro cómo configurar las tres estrategias principales de la librería Disruptor-net.

1. BlockingWaitStrategy (La «Eco-Friendly»)

Es la opción por defecto. Usa locks y condiciones del sistema operativo. Es amable con tu CPU, pero introduce pausas cuando el hilo se «despierta».

  • Ideal para: Aplicaciones donde el ahorro de energía y recursos es más importante que la latencia extrema.
var strategy = new BlockingWaitStrategy(); 

2. YieldingWaitStrategy (La «Educada»)

Esta estrategia usa un bucle que hace Thread.Yield(). Básicamente dice: «No tengo nada que hacer, si alguien más necesita la CPU, adelante; si no, sigo mirando».

  • Ideal para: Un equilibrio entre rendimiento y no dejar tu servidor al 100% de uso constante.
var strategy = new YieldingWaitStrategy();

3. BusySpinWaitStrategy (La «Psicópata»)

Aquí no hay piedad. El hilo se queda en un bucle while(true) chequeando la secuencia del Ring Buffer. No cede el paso, no duerme, consume un núcleo de CPU al 100%.

  • Ideal para: Sistemas de trading, juegos de alta velocidad o telemetría en tiempo real donde un microsegundo de demora es inaceptable.
var strategy = new BusySpinWaitStrategy(); 

Encadenando Handlers: El Efecto Dominó

En el artículo anterior vimos un solo handler. Pero la verdadera potencia del Disruptor es el procesamiento en paralelo y en serie sin usar colas intermedias.

// Definimos los trabajadores
var validador = new ValidadorHandler();
var logger = new JournalerHandler(); // Guarda en disco
var replicador = new ReplicationHandler(); // Envía a otro servidor

disruptor
    .HandleEventsWith(validador, logger) // Se ejecutan EN PARALELO
    .Then(replicador);                   // Solo inicia cuando los dos anteriores terminan

var ringBuffer = disruptor.Start();

¿Por qué esto es superior?

Porque el replicador no necesita que el validador le pase un objeto. Solo necesita saber que la «Secuencia 123» ya fue marcada como lista por sus predecesores. Es coordinación sin comunicación.

El Veredicto

  • La Trampa del BusySpin: Muchos desarrolladores junior ponen BusySpinWaitStrategy pensando que todo irá más rápido. Error. Si tienes más hilos «girando» que núcleos físicos en tu CPU, el sistema operativo empezará a intercambiar contextos y tu rendimiento caerá al subsuelo.
  • La Realidad de .NET: C# es sorprendentemente bueno en esto, pero recuerda que el Garbage Collector sigue ahí. Si tus eventos dentro del Ring Buffer crean nuevos objetos (como new String() o new List()), el Disruptor pierde su propósito. Mantén tus eventos planos y reutilizables.

Conclusión con Reto Final Dominar las Wait Strategies es como aprender a usar el embrague en un coche de carreras: requiere tacto. Si usas Blocking, eres un ciudadano responsable. Si usas

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *