UNPKG

@sha1n/fungus

Version:

A dependency based service graph controller library

80 lines (66 loc) 2.23 kB
import { retryAround, simpleRetryPolicy, TimeUnit } from '@sha1n/about-time'; import http from 'http'; import { RuntimeContext, Service } from '../..'; import { createLogger, Logger } from '../../lib/logger'; import startEchoServer from './echoServer'; type HttpServiceMetadata = { id: string; scheme: string; host: string; port: number; url: string; toString: () => string; }; class EchoService implements Service { private logger: Logger; private stopHttpServer: () => Promise<void>; constructor(readonly id: string) { this.logger = createLogger(this.id); } async start(ctx: RuntimeContext): Promise<HttpServiceMetadata> { this.logger.info(`start called with context of env: ${ctx.name}`); this.logger.info(`available services: ${Array.from(ctx.catalog.values()).join(', ')}`); this.logger.info(`staring ${this.id}...`); const { stop, scheme, address, port } = await startEchoServer(); this.stopHttpServer = stop; const url = `${scheme}://${address}:${port}`; this.logger.info(`checking whether '${url}' is alive`); await retryAround(() => this.isAlive(url), simpleRetryPolicy(3, 1, { units: TimeUnit.Seconds })); return { id: this.id, scheme, host: address, port: port, url, toString: () => { return `[${this.id} -> ${url}]`; } }; } async stop(ctx: RuntimeContext): Promise<void> { this.logger.info(`stop called with context of env: ${ctx.name}`); if (this.stopHttpServer) { this.logger.info(`stopping ${this.id}...`); await this.stopHttpServer(); } } async isAlive(url: string): Promise<boolean> { return new Promise((resolve, reject) => { const request = http.get(url, res => { if (!res.statusCode && res.statusCode !== 200) { reject(new Error(`Server returned status ${res.statusCode}`)); } resolve(true); }); request.on('error', reject); request.setTimeout(100, () => { reject(new Error('Timeout')); }); }); } } function createEchoService(id: string): Service { return new EchoService(id); } export { createEchoService, HttpServiceMetadata }; export default createEchoService;