Skip to content

Commit

Permalink
#296: split off the services, health and middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
petermasking committed Aug 28, 2024
1 parent e0b8813 commit 037ca36
Show file tree
Hide file tree
Showing 48 changed files with 1,677 additions and 4 deletions.
49 changes: 46 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/execution/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# Jitar Configuration
# Jitar Execution

This package contains the components for the execution of procedures from [Jitar](https://jitar.dev) applications.

Expand Down
4 changes: 4 additions & 0 deletions packages/health/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# Changelog

This package doesn't keep a changelog. See the changelog in the [github repository](https://github.com/MaskingTechnology/jitar/blob/main/CHANGELOG.md)
9 changes: 9 additions & 0 deletions packages/health/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Jitar Health

This package contains the components for health monitoring of the [Jitar](https://jitar.dev) runtime.

For more information about Jitar:

* [Visit our website](https://jitar.dev)
* [Read the documentation](https://docs.jitar.dev).
44 changes: 44 additions & 0 deletions packages/health/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@jitar/health",
"version": "0.7.4",
"description": "Health library for the Jitar runtime.",
"author": "Masking Technology <[email protected]> (https://jitar.dev)",
"license": "MIT",
"type": "module",
"types": "dist/index.d.ts",
"exports": {
".": "./dist/index.js"
},
"files": [
"CHANGELOG.md",
"README.md",
"dist"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "vitest run",
"test-coverage": "vitest run --coverage",
"lint": "eslint . --ext .ts",
"build": "tsc -p tsconfig.json",
"clean": "rm -rf dist",
"prepublishOnly": "npm run clean && npm run build"
},
"dependencies": {
"@jitar/errors": "*",
"@jitar/sourcing": "*"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MaskingTechnology/jitar.git"
},
"bugs": {
"url": "https://github.com/MaskingTechnology/jitar/issues"
},
"homepage": "https://jitar.dev",
"keywords": [
"configuration",
"jitar"
]
}
98 changes: 98 additions & 0 deletions packages/health/src/HealthManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

import { SourcingManager } from '@jitar/sourcing';

import InvalidHealthCheck from './errors/InvalidHealthCheck';
import HealthCheck from './interfaces/HealthCheck';

export default class HealthManager
{
#sourcingManager: SourcingManager;
#healthChecks: Map<string, HealthCheck> = new Map();

constructor(sourcingManager: SourcingManager)
{
this.#sourcingManager = sourcingManager;
}

async importHealthCheck(filename: string): Promise<void>
{
const module = await this.#sourcingManager.import(filename);
const healthCheck = module.default as HealthCheck;

if (healthCheck?.isHealthy === undefined)
{
throw new InvalidHealthCheck(filename);
}

this.addHealthCheck(healthCheck as HealthCheck);
}

addHealthCheck(healthCheck: HealthCheck): void
{
this.#healthChecks.set(healthCheck.name, healthCheck);
}

clearHealthChecks(): void
{
this.#healthChecks.clear();
}

async isHealthy(): Promise<boolean>
{
const promises: Promise<boolean>[] = [];

for (const healthCheck of this.#healthChecks.values())
{
const promise = this.#executeHealthCheck(healthCheck);

promises.push(promise);
}

return Promise.all(promises)
.then(results => results.every(result => result))
.catch(() => false);
}

async getHealth(): Promise<Map<string, boolean>>
{
const promises: Promise<{ name: string, isHealthy: boolean }>[] = [];

for (const [name, healthCheck] of this.#healthChecks)
{
const promise = this.#executeHealthCheck(healthCheck)
.then(result => ({ name, isHealthy: result }))
.catch(() => ({ name, isHealthy: false }));

promises.push(promise);
}

const healthChecks = new Map<string, boolean>();

return Promise.allSettled(promises)
.then(results => results.forEach(result =>
{
result.status === 'fulfilled'
? healthChecks.set(result.value.name, result.value.isHealthy)
: healthChecks.set(result.reason.name, false);
}))
.then(() => healthChecks);
}

async #executeHealthCheck(healthCheck: HealthCheck): Promise<boolean>
{
const health = healthCheck.isHealthy();
const milliseconds = healthCheck.timeout;

if (milliseconds === undefined)
{
return health;
}

const timeout = new Promise((resolve) =>
{
setTimeout(resolve, milliseconds);
}).then(() => false);

return Promise.race([timeout, health]);
}
}
19 changes: 19 additions & 0 deletions packages/health/src/errors/InvalidHealthCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

import { ServerError } from '@jitar/errors';
import { Loadable } from '@jitar/serialization';

export default class InvalidHealthCheck extends ServerError
{
#url: string;

constructor(url: string)
{
super(`Module '${url}' does not export a valid health check`);

this.#url = url;
}

get url() { return this.#url; }
}

(InvalidHealthCheck as Loadable).source = 'RUNTIME_ERROR_LOCATION';
4 changes: 4 additions & 0 deletions packages/health/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

export { default as HealthCheck } from './interfaces/HealthCheck';

export { default as HealthManager } from './HealthManager';
11 changes: 11 additions & 0 deletions packages/health/src/interfaces/HealthCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

interface HealthCheck
{
get name(): string;

get timeout(): number | undefined;

isHealthy(): Promise<boolean>;
}

export default HealthCheck;
21 changes: 21 additions & 0 deletions packages/health/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"rootDir": "./src/",
"moduleResolution": "node",
"declaration": true,
"outDir": "./dist",
"removeComments": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"exclude": [
"vite.config.ts",
"node_modules",
"dist",
"test"
]
}
10 changes: 10 additions & 0 deletions packages/health/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// vite.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
coverage: {
provider: 'v8'
},
},
});
4 changes: 4 additions & 0 deletions packages/middleware/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# Changelog

This package doesn't keep a changelog. See the changelog in the [github repository](https://github.com/MaskingTechnology/jitar/blob/main/CHANGELOG.md)
9 changes: 9 additions & 0 deletions packages/middleware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Jitar Middleware

This package contains the components for middleware support for the [Jitar](https://jitar.dev) runtime.

For more information about Jitar:

* [Visit our website](https://jitar.dev)
* [Read the documentation](https://docs.jitar.dev).
45 changes: 45 additions & 0 deletions packages/middleware/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@jitar/middleware",
"version": "0.7.4",
"description": "Middleware library for the Jitar runtime.",
"author": "Masking Technology <[email protected]> (https://jitar.dev)",
"license": "MIT",
"type": "module",
"types": "dist/index.d.ts",
"exports": {
".": "./dist/index.js"
},
"files": [
"CHANGELOG.md",
"README.md",
"dist"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "vitest run",
"test-coverage": "vitest run --coverage",
"lint": "eslint . --ext .ts",
"build": "tsc -p tsconfig.json",
"clean": "rm -rf dist",
"prepublishOnly": "npm run clean && npm run build"
},
"dependencies": {
"@jitar/errors": "*",
"@jitar/execution": "*",
"@jitar/sourcing": "*"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MaskingTechnology/jitar.git"
},
"bugs": {
"url": "https://github.com/MaskingTechnology/jitar/issues"
},
"homepage": "https://jitar.dev",
"keywords": [
"configuration",
"jitar"
]
}
Loading

0 comments on commit 037ca36

Please sign in to comment.