mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 12:21:57 +00:00
feat: Utils to do bindLan and have ipv4 and ipv6 if need be
This commit is contained in:
@@ -1,43 +1,43 @@
|
||||
import { InterfaceReceipt } from "../mainFn/interfaceReceipt";
|
||||
import { Daemon, Effects } from "../types";
|
||||
import { CheckResult } from "./checkFns/CheckResult";
|
||||
import { HealthReceipt } from "./HealthReceipt";
|
||||
import { Trigger } from "./trigger";
|
||||
import { TriggerInput } from "./trigger/TriggerInput";
|
||||
import { defaultTrigger } from "./trigger/defaultTrigger";
|
||||
import { InterfaceReceipt } from "../mainFn/interfaceReceipt"
|
||||
import { Daemon, Effects } from "../types"
|
||||
import { CheckResult } from "./checkFns/CheckResult"
|
||||
import { HealthReceipt } from "./HealthReceipt"
|
||||
import { Trigger } from "./trigger"
|
||||
import { TriggerInput } from "./trigger/TriggerInput"
|
||||
import { defaultTrigger } from "./trigger/defaultTrigger"
|
||||
|
||||
export function healthCheck(o: {
|
||||
effects: Effects;
|
||||
name: string;
|
||||
trigger?: Trigger;
|
||||
fn(): Promise<CheckResult> | CheckResult;
|
||||
onFirstSuccess?: () => () => Promise<unknown> | unknown;
|
||||
effects: Effects
|
||||
name: string
|
||||
trigger?: Trigger
|
||||
fn(): Promise<CheckResult> | CheckResult
|
||||
onFirstSuccess?: () => () => Promise<unknown> | unknown
|
||||
}) {
|
||||
new Promise(async () => {
|
||||
let currentValue: TriggerInput = {
|
||||
lastResult: null,
|
||||
hadSuccess: false,
|
||||
};
|
||||
const getCurrentValue = () => currentValue;
|
||||
const trigger = (o.trigger ?? defaultTrigger)(getCurrentValue);
|
||||
}
|
||||
const getCurrentValue = () => currentValue
|
||||
const trigger = (o.trigger ?? defaultTrigger)(getCurrentValue)
|
||||
for (
|
||||
let res = await trigger.next();
|
||||
!res.done;
|
||||
res = await trigger.next()
|
||||
) {
|
||||
try {
|
||||
const { status, message } = await o.fn();
|
||||
const { status, message } = await o.fn()
|
||||
await o.effects.setHealth({
|
||||
name: o.name,
|
||||
status,
|
||||
message,
|
||||
});
|
||||
currentValue.hadSuccess = true;
|
||||
currentValue.lastResult = "success";
|
||||
})
|
||||
currentValue.hadSuccess = true
|
||||
currentValue.lastResult = "success"
|
||||
} catch (_) {
|
||||
currentValue.lastResult = "failure";
|
||||
currentValue.lastResult = "failure"
|
||||
}
|
||||
}
|
||||
});
|
||||
return {} as HealthReceipt;
|
||||
})
|
||||
return {} as HealthReceipt
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
declare const HealthProof: unique symbol;
|
||||
declare const HealthProof: unique symbol
|
||||
export type HealthReceipt = {
|
||||
[HealthProof]: never;
|
||||
};
|
||||
[HealthProof]: never
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { HealthStatus } from "../../types";
|
||||
import { HealthStatus } from "../../types"
|
||||
|
||||
export type CheckResult = {
|
||||
status: HealthStatus;
|
||||
message?: string;
|
||||
};
|
||||
status: HealthStatus
|
||||
message?: string
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Effects } from "../../types";
|
||||
import { CheckResult } from "./CheckResult";
|
||||
import { Effects } from "../../types"
|
||||
import { CheckResult } from "./CheckResult"
|
||||
export function containsAddress(x: string, port: number) {
|
||||
const readPorts = x
|
||||
.split("\n")
|
||||
@@ -8,8 +8,8 @@ export function containsAddress(x: string, port: number) {
|
||||
.map((x) => x.split(" ").filter(Boolean)[1]?.split(":")?.[1])
|
||||
.filter(Boolean)
|
||||
.map((x) => Number.parseInt(x, 16))
|
||||
.filter(Number.isFinite);
|
||||
return readPorts.indexOf(port) >= 0;
|
||||
.filter(Number.isFinite)
|
||||
return readPorts.indexOf(port) >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,12 +26,12 @@ export async function checkPortListening(
|
||||
): Promise<CheckResult> {
|
||||
const hasAddress =
|
||||
containsAddress(await effects.runCommand(`cat /proc/net/tcp`), port) ||
|
||||
containsAddress(await effects.runCommand("cat /proc/net/udp"), port);
|
||||
containsAddress(await effects.runCommand("cat /proc/net/udp"), port)
|
||||
if (hasAddress) {
|
||||
return { status: "passing", message };
|
||||
return { status: "passing", message }
|
||||
}
|
||||
return {
|
||||
status: "failing",
|
||||
message: error,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Effects } from "../../types";
|
||||
import { CheckResult } from "./CheckResult";
|
||||
import { timeoutPromise } from "./index";
|
||||
import { Effects } from "../../types"
|
||||
import { CheckResult } from "./CheckResult"
|
||||
import { timeoutPromise } from "./index"
|
||||
|
||||
/**
|
||||
* This is a helper function to check if a web url is reachable.
|
||||
@@ -23,9 +23,9 @@ export const checkWebUrl = async (
|
||||
message: successMessage,
|
||||
}))
|
||||
.catch((e) => {
|
||||
effects.warn(`Error while fetching URL: ${url}`);
|
||||
effects.error(JSON.stringify(e));
|
||||
effects.error(e.toString());
|
||||
return { status: "failing" as const, message: errorMessage };
|
||||
});
|
||||
};
|
||||
effects.console.warn(`Error while fetching URL: ${url}`)
|
||||
effects.console.error(JSON.stringify(e))
|
||||
effects.console.error(e.toString())
|
||||
return { status: "failing" as const, message: errorMessage }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { runHealthScript } from "./runHealthScript";
|
||||
export { checkPortListening } from "./checkPortListening";
|
||||
export { CheckResult } from "./CheckResult";
|
||||
export { checkWebUrl } from "./checkWebUrl";
|
||||
import { runHealthScript } from "./runHealthScript"
|
||||
export { checkPortListening } from "./checkPortListening"
|
||||
export { CheckResult } from "./CheckResult"
|
||||
export { checkWebUrl } from "./checkWebUrl"
|
||||
|
||||
export function timeoutPromise(ms: number, { message = "Timed out" } = {}) {
|
||||
return new Promise<never>((resolve, reject) =>
|
||||
setTimeout(() => reject(new Error(message)), ms),
|
||||
);
|
||||
)
|
||||
}
|
||||
export { runHealthScript };
|
||||
export { runHealthScript }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommandType, Effects } from "../../types";
|
||||
import { CheckResult } from "./CheckResult";
|
||||
import { timeoutPromise } from "./index";
|
||||
import { CommandType, Effects } from "../../types"
|
||||
import { CheckResult } from "./CheckResult"
|
||||
import { timeoutPromise } from "./index"
|
||||
|
||||
/**
|
||||
* Running a health script, is used when we want to have a simple
|
||||
@@ -23,13 +23,13 @@ export const runHealthScript = async <A extends string>(
|
||||
effects.runCommand(runCommand, { timeoutMillis: timeout }),
|
||||
timeoutPromise(timeout),
|
||||
]).catch((e) => {
|
||||
effects.warn(errorMessage);
|
||||
effects.warn(JSON.stringify(e));
|
||||
effects.warn(e.toString());
|
||||
throw { status: "failing", message: errorMessage } as CheckResult;
|
||||
});
|
||||
effects.console.warn(errorMessage)
|
||||
effects.console.warn(JSON.stringify(e))
|
||||
effects.console.warn(e.toString())
|
||||
throw { status: "failing", message: errorMessage } as CheckResult
|
||||
})
|
||||
return {
|
||||
status: "passing",
|
||||
message: message(res),
|
||||
} as CheckResult;
|
||||
};
|
||||
} as CheckResult
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export * as checkFns from "./checkFns";
|
||||
export * as trigger from "./trigger";
|
||||
export * as checkFns from "./checkFns"
|
||||
export * as trigger from "./trigger"
|
||||
|
||||
export { TriggerInput } from "./trigger/TriggerInput";
|
||||
export { HealthReceipt } from "./HealthReceipt";
|
||||
export { ReadyProof } from "../mainFn/ReadyProof";
|
||||
export { TriggerInput } from "./trigger/TriggerInput"
|
||||
export { HealthReceipt } from "./HealthReceipt"
|
||||
export { ReadyProof } from "../mainFn/ReadyProof"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type TriggerInput = {
|
||||
lastResult?: "success" | "failure" | null;
|
||||
hadSuccess?: boolean;
|
||||
};
|
||||
lastResult?: "success" | "failure" | null
|
||||
hadSuccess?: boolean
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import { TriggerInput } from "./TriggerInput";
|
||||
import { Trigger } from "./index";
|
||||
import { TriggerInput } from "./TriggerInput"
|
||||
import { Trigger } from "./index"
|
||||
|
||||
export function changeOnFirstSuccess(o: {
|
||||
beforeFirstSuccess: Trigger;
|
||||
afterFirstSuccess: Trigger;
|
||||
beforeFirstSuccess: Trigger
|
||||
afterFirstSuccess: Trigger
|
||||
}): Trigger {
|
||||
return async function* (getInput) {
|
||||
const beforeFirstSuccess = o.beforeFirstSuccess(getInput);
|
||||
yield;
|
||||
let currentValue = getInput();
|
||||
beforeFirstSuccess.next();
|
||||
const beforeFirstSuccess = o.beforeFirstSuccess(getInput)
|
||||
yield
|
||||
let currentValue = getInput()
|
||||
beforeFirstSuccess.next()
|
||||
for (
|
||||
let res = await beforeFirstSuccess.next();
|
||||
currentValue?.lastResult !== "success" && !res.done;
|
||||
res = await beforeFirstSuccess.next()
|
||||
) {
|
||||
yield;
|
||||
currentValue = getInput();
|
||||
yield
|
||||
currentValue = getInput()
|
||||
}
|
||||
const afterFirstSuccess = o.afterFirstSuccess(getInput);
|
||||
const afterFirstSuccess = o.afterFirstSuccess(getInput)
|
||||
for (
|
||||
let res = await afterFirstSuccess.next();
|
||||
!res.done;
|
||||
res = await afterFirstSuccess.next()
|
||||
) {
|
||||
yield;
|
||||
currentValue = getInput();
|
||||
yield
|
||||
currentValue = getInput()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export function cooldownTrigger(timeMs: number) {
|
||||
return async function* () {
|
||||
while (true) {
|
||||
await new Promise((resolve) => setTimeout(resolve, timeMs));
|
||||
yield;
|
||||
await new Promise((resolve) => setTimeout(resolve, timeMs))
|
||||
yield
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cooldownTrigger } from "./cooldownTrigger";
|
||||
import { changeOnFirstSuccess } from "./changeOnFirstSuccess";
|
||||
import { cooldownTrigger } from "./cooldownTrigger"
|
||||
import { changeOnFirstSuccess } from "./changeOnFirstSuccess"
|
||||
|
||||
export const defaultTrigger = changeOnFirstSuccess({
|
||||
beforeFirstSuccess: cooldownTrigger(0),
|
||||
afterFirstSuccess: cooldownTrigger(30000),
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TriggerInput } from "./TriggerInput";
|
||||
export { changeOnFirstSuccess } from "./changeOnFirstSuccess";
|
||||
export { cooldownTrigger } from "./cooldownTrigger";
|
||||
import { TriggerInput } from "./TriggerInput"
|
||||
export { changeOnFirstSuccess } from "./changeOnFirstSuccess"
|
||||
export { cooldownTrigger } from "./cooldownTrigger"
|
||||
|
||||
export type Trigger = (
|
||||
getInput: () => TriggerInput,
|
||||
) => AsyncIterator<unknown, unknown, never>;
|
||||
) => AsyncIterator<unknown, unknown, never>
|
||||
|
||||
Reference in New Issue
Block a user