mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 04:23:40 +00:00
sdk comments
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
import { HealthStatus } from "../../../base/lib/types"
|
||||
|
||||
/**
|
||||
* Input state provided to trigger functions.
|
||||
* Contains information about the health check's current state
|
||||
* that triggers can use to adjust their timing behavior.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const myTrigger: Trigger = (getInput) => {
|
||||
* return (async function* () {
|
||||
* while (true) {
|
||||
* const input: TriggerInput = getInput()
|
||||
* // Check more frequently if last result was failure
|
||||
* const delay = input.lastResult === 'failure' ? 1000 : 30000
|
||||
* await new Promise(r => setTimeout(r, delay))
|
||||
* yield
|
||||
* }
|
||||
* })()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export type TriggerInput = {
|
||||
/** The result of the most recent health check execution, if any */
|
||||
lastResult?: HealthStatus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
import { Trigger } from "./index"
|
||||
|
||||
/**
|
||||
* Creates a trigger that uses different timing before and after the first successful health check.
|
||||
*
|
||||
* This is useful for services that need frequent checks during startup (to quickly report
|
||||
* when they become healthy) but can reduce check frequency once they're running stably.
|
||||
*
|
||||
* The trigger switches permanently to `afterFirstSuccess` timing once a success is seen.
|
||||
* It does NOT switch back even if the service later becomes unhealthy.
|
||||
*
|
||||
* @param o.beforeFirstSuccess - Trigger to use until the first successful health check
|
||||
* @param o.afterFirstSuccess - Trigger to use after the first successful health check
|
||||
* @returns A composite trigger that switches behavior after first success
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Check every second while starting, every 30 seconds once healthy
|
||||
* const trigger = changeOnFirstSuccess({
|
||||
* beforeFirstSuccess: cooldownTrigger(1000), // 1s while starting
|
||||
* afterFirstSuccess: cooldownTrigger(30000) // 30s after healthy
|
||||
* })
|
||||
*
|
||||
* // Use in a health check
|
||||
* daemons.addHealthCheck({
|
||||
* id: 'main',
|
||||
* name: 'Main Health',
|
||||
* trigger,
|
||||
* fn: checkServiceHealth
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function changeOnFirstSuccess(o: {
|
||||
beforeFirstSuccess: Trigger
|
||||
afterFirstSuccess: Trigger
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/**
|
||||
* Creates a simple timer-based trigger that fires at regular intervals.
|
||||
* This is the most basic trigger type - it just waits the specified
|
||||
* time between each health check.
|
||||
*
|
||||
* @param timeMs - Interval between health checks in milliseconds
|
||||
* @returns A trigger factory function
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Check health every 5 seconds
|
||||
* const trigger = cooldownTrigger(5000)
|
||||
*
|
||||
* // Use in a health check
|
||||
* daemons.addHealthCheck({
|
||||
* id: 'main',
|
||||
* name: 'Main Check',
|
||||
* trigger: cooldownTrigger(10000), // Every 10 seconds
|
||||
* fn: async () => ({ result: 'success', message: 'OK' })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function cooldownTrigger(timeMs: number) {
|
||||
return async function* () {
|
||||
while (true) {
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
import { cooldownTrigger } from "./cooldownTrigger"
|
||||
import { changeOnFirstSuccess } from "./changeOnFirstSuccess"
|
||||
|
||||
/**
|
||||
* The default trigger used when no custom trigger is specified for a health check.
|
||||
*
|
||||
* Provides sensible defaults for most services:
|
||||
* - **Before first success**: Checks every 1 second (rapid during startup)
|
||||
* - **After first success**: Checks every 30 seconds (stable once healthy)
|
||||
*
|
||||
* This trigger is automatically used by `Daemons.addDaemon()` and `Daemons.addHealthCheck()`
|
||||
* when no `trigger` option is provided.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // These are equivalent - both use defaultTrigger
|
||||
* daemons.addHealthCheck({
|
||||
* id: 'main',
|
||||
* name: 'Main',
|
||||
* fn: checkHealth
|
||||
* // trigger: defaultTrigger // implicit
|
||||
* })
|
||||
*
|
||||
* // Custom trigger overrides the default
|
||||
* daemons.addHealthCheck({
|
||||
* id: 'main',
|
||||
* name: 'Main',
|
||||
* trigger: cooldownTrigger(5000), // Check every 5s instead
|
||||
* fn: checkHealth
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export const defaultTrigger = changeOnFirstSuccess({
|
||||
beforeFirstSuccess: cooldownTrigger(1000),
|
||||
afterFirstSuccess: cooldownTrigger(30000),
|
||||
|
||||
@@ -1,7 +1,57 @@
|
||||
/**
|
||||
* @module trigger
|
||||
*
|
||||
* Triggers control when health checks are executed. They are async generators
|
||||
* that yield when a health check should run. This allows fine-grained control
|
||||
* over check frequency based on the service's current state.
|
||||
*
|
||||
* Built-in triggers:
|
||||
* - `cooldownTrigger(ms)` - Simple timer-based trigger
|
||||
* - `changeOnFirstSuccess` - Different timing before/after first successful check
|
||||
* - `successFailure` - Different timing based on success/failure state
|
||||
* - `lastStatus` - Configurable timing per health status
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Check every 5 seconds
|
||||
* const trigger = cooldownTrigger(5000)
|
||||
*
|
||||
* // Fast checks until healthy, then slow down
|
||||
* const adaptiveTrigger = changeOnFirstSuccess({
|
||||
* beforeFirstSuccess: cooldownTrigger(1000), // 1s while starting
|
||||
* afterFirstSuccess: cooldownTrigger(30000) // 30s once healthy
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
import { TriggerInput } from "./TriggerInput"
|
||||
export { changeOnFirstSuccess } from "./changeOnFirstSuccess"
|
||||
export { cooldownTrigger } from "./cooldownTrigger"
|
||||
|
||||
/**
|
||||
* A trigger function that controls when health checks execute.
|
||||
*
|
||||
* Triggers are async generator factories. Given a function to get the current
|
||||
* input state (e.g., last health result), they return an async iterator that
|
||||
* yields when a health check should run.
|
||||
*
|
||||
* @param getInput - Function returning the current trigger input state
|
||||
* @returns An async iterator that yields when a check should run
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Custom trigger that checks every 10s during success, 2s during failure
|
||||
* const myTrigger: Trigger = (getInput) => {
|
||||
* return (async function* () {
|
||||
* while (true) {
|
||||
* const { lastResult } = getInput()
|
||||
* const delay = lastResult === 'success' ? 10000 : 2000
|
||||
* await new Promise(r => setTimeout(r, delay))
|
||||
* yield
|
||||
* }
|
||||
* })()
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export type Trigger = (
|
||||
getInput: () => TriggerInput,
|
||||
) => AsyncIterator<unknown, unknown, never>
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
import { Trigger } from "."
|
||||
import { HealthStatus } from "../../../base/lib/types"
|
||||
|
||||
/**
|
||||
* Configuration for status-based trigger selection.
|
||||
* Maps health statuses to triggers, with a required default fallback.
|
||||
*/
|
||||
export type LastStatusTriggerParams = { [k in HealthStatus]?: Trigger } & {
|
||||
/** Trigger to use when no status-specific trigger is defined */
|
||||
default: Trigger
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a trigger that dynamically selects timing based on the last health check result.
|
||||
*
|
||||
* This allows different check frequencies for each health status:
|
||||
* - `success` - When the service is healthy
|
||||
* - `failure` - When the service is unhealthy
|
||||
* - `starting` - When the service is still starting up
|
||||
*
|
||||
* Uses the `default` trigger for any status not explicitly configured.
|
||||
*
|
||||
* @param o - Map of health statuses to triggers, plus a required default
|
||||
* @returns A composite trigger that adapts to the current health status
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Check frequently during failure, rarely during success
|
||||
* const adaptiveTrigger = lastStatus({
|
||||
* success: cooldownTrigger(60000), // 60s when healthy
|
||||
* failure: cooldownTrigger(5000), // 5s when unhealthy
|
||||
* starting: cooldownTrigger(2000), // 2s while starting
|
||||
* default: cooldownTrigger(10000) // 10s fallback
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function lastStatus(o: LastStatusTriggerParams): Trigger {
|
||||
return async function* (getInput) {
|
||||
let trigger = o.default(getInput)
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
import { Trigger } from "."
|
||||
import { lastStatus } from "./lastStatus"
|
||||
|
||||
/**
|
||||
* Creates a trigger with different timing for success vs failure/starting states.
|
||||
*
|
||||
* This is a simplified wrapper around `lastStatus` for the common case
|
||||
* where you want one timing during healthy operation and another during
|
||||
* any error condition (failure or starting).
|
||||
*
|
||||
* @param o.duringSuccess - Trigger to use when the last check succeeded
|
||||
* @param o.duringError - Trigger to use for failure, starting, or unknown states
|
||||
* @returns A composite trigger that adapts to success/failure state
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Check every minute when healthy, every 5 seconds when unhealthy
|
||||
* const trigger = successFailure({
|
||||
* duringSuccess: cooldownTrigger(60000), // 1 minute
|
||||
* duringError: cooldownTrigger(5000) // 5 seconds
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export const successFailure = (o: {
|
||||
duringSuccess: Trigger
|
||||
duringError: Trigger
|
||||
|
||||
Reference in New Issue
Block a user