Module: Tina4::Background

Defined in:
lib/tina4/background.rb

Overview

Periodic background task registry.

Matches Python’s ‘tina4_python.core.server.background(fn, interval)` and PHP’s ‘$app->background($callback, $interval)` — a callback that runs periodically alongside the server lifecycle.

Ruby has no asyncio event loop, so each task runs in its own thread. The GIL keeps it cooperative-enough for the periodic work this is meant for (queue draining, health checks, simulators). Errors in the callback are caught and logged so they don’t kill the thread.

Class Method Summary collapse

Class Method Details

.register(callback = nil, interval: 1.0, &block) ⇒ Hash

Register a periodic callback.

Parameters:

  • callback (#call, nil) (defaults to: nil)

    Object responding to ‘call` with no args.

  • interval (Float) (defaults to: 1.0)

    Seconds between invocations (default 1.0).

  • block (Proc)

    Optional block (used if callback is nil).

Returns:

  • (Hash)

    The registered task descriptor.

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
# File 'lib/tina4/background.rb', line 22

def register(callback = nil, interval: 1.0, &block)
  cb = callback || block
  raise ArgumentError, "background requires a callback or block" if cb.nil?
  raise ArgumentError, "callback must respond to :call" unless cb.respond_to?(:call)

  task = { callback: cb, interval: interval.to_f, thread: nil, running: false }
  mutex.synchronize { tasks << task }
  start_task(task)
  task
end

.stop_all(timeout: 2.0) ⇒ Object

Stop and join every running task. Called on graceful shutdown.



39
40
41
42
43
# File 'lib/tina4/background.rb', line 39

def stop_all(timeout: 2.0)
  snapshot = mutex.synchronize { tasks.dup }
  snapshot.each { |task| stop_task(task, timeout: timeout) }
  mutex.synchronize { tasks.clear }
end

.stop_task(task, timeout: 2.0) ⇒ Object

Stop a single task. Used by tests that register, fire, then stop.



46
47
48
49
50
51
52
53
# File 'lib/tina4/background.rb', line 46

def stop_task(task, timeout: 2.0)
  task[:running] = false
  thread = task[:thread]
  return unless thread

  thread.join(timeout) || thread.kill
  task[:thread] = nil
end

.tasksObject

All registered task descriptors. Tests use this for introspection.



34
35
36
# File 'lib/tina4/background.rb', line 34

def tasks
  @tasks ||= []
end