|
root / stub / src / supervisor.reef
supervisor.reef Reef 63 lines 2.1 KB
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// supervisor.reef — Service lifecycle management
//
// Handles starting, stopping, and restarting services using process
// contracts. Implements restart policies (always, on-failure, never).

import config.{ServiceDef, ServiceType, RestartPolicy, StopMethod}
import contract.{Contract, setup_template, get_latest_contract, kill_contract}

// Runtime state of a service
enum ServiceState {
    Disabled,       // not enabled
    Waiting,        // waiting for dependencies
    Starting,       // exec'd, waiting for confirmation
    Running,        // running (has contract)
    Stopping,       // stop signal sent, waiting for exit
    Stopped,        // cleanly stopped
    Failed,         // exited with error
    Maintenance,    // exceeded max retries
}

// Runtime info for a managed service
struct ServiceRuntime {
    def: ServiceDef,
    state: ServiceState,
    contract: Option<Contract>,
    pid: Option<i32>,
    restart_count: i32,
    last_exit_code: Option<i32>,
    last_start_time: i64,     // unix timestamp
}

// Start a service — fork, set up contract, exec
fn start_service(svc: ServiceDef) -> Result<ServiceRuntime, String> {
    // TODO: implement
    // 1. setup_template() for contract
    // 2. fork()
    // 3. In child: setsid(), exec(svc.start_cmd)
    // 4. In parent: get_latest_contract(), ct_tmpl_clear()
    // 5. Return ServiceRuntime with Running state
    Err("not yet implemented")
}

// Stop a service
fn stop_service(rt: ServiceRuntime) -> Result<ServiceRuntime, String> {
    // TODO: implement
    // Based on svc.stop_method:
    //   Contract: kill_contract(contract_id, signal)
    //   Exec: fork/exec the stop command
    // Wait up to stop_timeout, then SIGKILL
    Err("not yet implemented")
}

// Handle a contract event (service exited)
fn handle_exit(rt: ServiceRuntime, exit_code: i32) -> ServiceRuntime {
    // TODO: implement
    // Based on restart_policy:
    //   Always: schedule restart after delay
    //   OnFailure: restart only if exit_code != 0
    //   Never: mark as Stopped
    // Check max_retries — enter Maintenance if exceeded
    rt
}