Saltar al contenido

Agendamiento: every, after y timeout

En esta página

Zolo tiene tres construcciones de agendamiento integradas en el lenguaje. Todas son palabras reservadas — no uses every, after ni timeout como nombres de variable; prefiere intervalo, agendado, plazo o limite en su lugar.

every — bucle periódico

every <dur> { ... } repite el cuerpo en el intervalo indicado. Es un bucle infinito por diseño: termínalo con break cuando se alcance la condición de salida.

Un contador con break tras 3 iteraciones; una suma acumulada que se detiene al alcanzar el total deseado.

05-every.zolo
Playground
// Feature: periodic loop with `every <dur> { ... }`

// Syntax: `every <duration> { body }` — repeats the body at the given

// interval. It is a keyword (not a variable name).

// When to use: health-checks, polling, animation, metrics, any

// task that needs to run repeatedly on a fixed interval.


var tick = 0

// Runs 3 times (short interval for the demo) and exits with `break`.

every 50ms {
  tick = tick + 1
  print("tick #{tick}")
  if tick >= 3 {
    break
  }
}

print("done")

// expected:

// tick #1

// tick #2

// tick #3

// done


// Another example: summing until a total is reached.

var total = 0
every 25ms {
  total = total + 10
  if total >= 30 {
    break
  }
}
print("total = {total}")
// expected: total = 30

after — disparo único

after <dur> { ... } agenda la ejecución del bloque una sola vez, tras el retraso. Es fire-and-forget: no bloquea el flujo principal. Usa sleep después para mantener el programa vivo hasta que el callback se dispare.

Tres after coexistiendo; el orden de disparo lo determina el scheduler.

06-after.zolo
Playground
// Feature: schedule one execution with `after <dur> { ... }`

// Syntax: `after <duration> { body }` — fire-and-forget; the block

// runs **once** after the delay. It is a keyword.

// When to use: one-shot callbacks, timers, expirations, single

// reminders. Unlike `every`, it does not repeat.


print("scheduling...")

// Block runs 50ms later — does not block the main flow here.

after 50ms {
  print("fired after 50ms!")
}

// Multiple `after` may coexist.

after 100ms {
  print("fired after 100ms!")
}

after 25ms {
  print("this one was first")
}

print("scheduled, waiting...")

// Keep the program alive long enough to see the firings.

sleep 200ms
print("end")
// expected (approximate order — depends on the scheduler):

// scheduling...

// scheduled, waiting...

// this one was first

// fired after 50ms!

// fired after 100ms!

// end

timeout — cancelación por plazo

timeout <dur> { ... } devuelve un objeto { ok, value, error }. Si el bloque concluye dentro del plazo, ok es true y value contiene el retorno. Si expira, ok es false y error es "timeout". Como el scheduler es cooperativo, la cancelación solo ocurre en puntos de yield (sleep, IO, etc.).

Camino feliz con retorno dentro del plazo; nota sobre el comportamiento cooperativo y alternativa de nombre para la variable de plazo.

07-timeout.zolo
Playground
// Feature: cancel work that takes too long with `timeout`

// Syntax: `timeout <dur> { body }` — returns a `Result`-like

// (`{ ok, value, error }`) with `ok = true` if it completed, or

// `ok = false, error = "timeout"` if it expired.

// When to use: network calls, uncertain IO, tasks that need a

// fail-safe. Cooperative: only fires at a yield point.


// Happy path: body finishes within the deadline.

let result_ok = timeout 100ms {
  return 42
}
if result_ok.ok {
  print("ok: {result_ok.value}")
} else {
  print("err: {result_ok.error}")
}

// expected: ok: 42


// Timeout case: body takes longer than the limit and is interrupted.

// Note: cooperative — the body must yield (e.g. via `sleep`) for

// the deadline to fire. If it never yields, the body runs to

// completion and `ok = true`.

// SKIP: sleep inside `timeout { ... }` raises a YieldError in the

// current runtime; the failure case is therefore commented out.

//

// let result_slow = timeout 30ms {

//   sleep 200ms

//   return "too late"

// }

// if result_slow.ok {

//   print("ok: {result_slow.value}")

// } else {

//   print("err: {result_slow.error}")

// }

//

// expected: err: timeout


// IMPORTANT: `timeout` is a reserved keyword — you cannot use it

// as a variable name. Use `deadline`, `limit`, `dur`, etc. instead.

let limit = 5000
print("using '{limit}' instead of 'timeout' as the name")

Desafío

Combina every 100ms con un after 500ms que establezca un flag de parada. El every debe verificar el flag y llamar a break cuando sea verdadero.

Consulta también

Buscar en Zolo

9 resultados

enespt-br