1 | /// <reference types="node" />
|
2 |
|
3 | /**
|
4 | * contains all of your service's dependencies and provides scheduling
|
5 | * options for checking those dependencies
|
6 | */
|
7 | interface Copacetic extends NodeJS.EventEmitter {
|
8 | /**
|
9 | * The name of your service. This is output in the express
|
10 | * middleware when verbose is true
|
11 | */
|
12 | name: string,
|
13 |
|
14 | /**
|
15 | * Whether dependencies are currently being polled
|
16 | */
|
17 |
|
18 | isPolling: boolean,
|
19 |
|
20 | /**
|
21 | * True when there are no hard dependency failures
|
22 | */
|
23 | isHealthy: boolean,
|
24 |
|
25 | /**
|
26 | * Health information on all registered services
|
27 | */
|
28 | healthInfo: Array<copacetic.Health>,
|
29 |
|
30 | /**
|
31 | * Returns a registered dependency
|
32 | * Examples:
|
33 | *
|
34 | * // With a name
|
35 | * copacetic.getDependency('database')
|
36 | *
|
37 | * // With a dependency
|
38 | * copacetic.getDependency(dep)
|
39 | */
|
40 | getDependency (dependency: copacetic.Dependency|string): copacetic.Dependency,
|
41 |
|
42 | /**
|
43 | * Checks if a dependency exists
|
44 | * Examples:
|
45 | *
|
46 | * // With a name
|
47 | * copacetic.isDependencyRegistered('database')
|
48 | *
|
49 | * // With a dependency
|
50 | * copacetic.isDependencyRegistered(dep)
|
51 | */
|
52 | isDependencyRegistered (dependency: copacetic.Dependency|string): copacetic.Dependency,
|
53 |
|
54 | /**
|
55 | * Adds a dependency to a copacetic instance
|
56 | * Examples:
|
57 | *
|
58 | * copacetic.registerDependency({ name: 'database', url: 'memes.com' })
|
59 | *
|
60 | * copacetic.registerDependency({ name: 'cache', strategy: { type: 'redis' } })
|
61 | *
|
62 | * copacetic
|
63 | * .registerDependency
|
64 | * ({ name: 'service', strategy: { type: 'redis', adapter } })
|
65 | */
|
66 | registerDependency (options: copacetic.DependencyOptions): Copacetic,
|
67 |
|
68 | /**
|
69 | * Removes a dependency from a copacetic instance
|
70 | * Examples:
|
71 | *
|
72 | * // With a name
|
73 | * copacetic.deregisterDependency('database')
|
74 | *
|
75 | * // With a dependency
|
76 | * copacetic.deregisterDependency(dep)
|
77 | */
|
78 | deregisterDependency (dependency: copacetic.Dependency|string): Copacetic,
|
79 |
|
80 | /**
|
81 | * Polls the health of all registered dependencies
|
82 | */
|
83 | pollAll (options: {
|
84 | /**
|
85 | * The rate at which dependencies will be polled, of the format
|
86 | * '5 seconds', '1m minute 20 seconds' etc.
|
87 | */
|
88 | interval?: string,
|
89 | /**
|
90 | * check the health of dependencies in sequence, or parallel
|
91 | */
|
92 | parallel?: boolean,
|
93 | /**
|
94 | * schedule the next check as soon as a poll starts, or wait
|
95 | */
|
96 | schedule?: string
|
97 | }): Copacetic,
|
98 |
|
99 | /**
|
100 | * Polls the health of a set of dependencies
|
101 | * Example:
|
102 | *
|
103 | * copacetic.poll({
|
104 | * dependencies: [
|
105 | * { name: 'database', retries: 2 },
|
106 | * { name: 'cache' }
|
107 | * ],
|
108 | * interval: '1 minute 30 seconds'
|
109 | * parallel: false
|
110 | * })
|
111 | */
|
112 | poll (options: {
|
113 | /**
|
114 | * An explicit set of dependencies to be health checked
|
115 | */
|
116 | dependencies: Array<
|
117 | {
|
118 | /** the name used when registering the dependency **/
|
119 | name: string,
|
120 | /** the number of times to retry a health check, before marking as unhealthy **/
|
121 | retries?: number
|
122 | }
|
123 | >,
|
124 | /**
|
125 | * The rate at which dependencies will be polled, of the format
|
126 | * '5 seconds', '1m minute 20 seconds' etc.
|
127 | */
|
128 | interval: string,
|
129 | /**
|
130 | * check the health of dependencies in sequence, or parallel
|
131 | */
|
132 | parallel?: boolean,
|
133 | /**
|
134 | * schedule the next check as soon as a poll starts, or wait
|
135 | */
|
136 | schedule?: string
|
137 | }): Copacetic,
|
138 |
|
139 | /**
|
140 | * stops polling dependencies
|
141 | */
|
142 | stop (): void,
|
143 |
|
144 | /**
|
145 | * Checks the health of all registered dependencies
|
146 | * Example:
|
147 | *
|
148 | * copacetic.checkAll(false)
|
149 | */
|
150 | checkAll (parallel: boolean): Copacetic,
|
151 |
|
152 | /**
|
153 | * Checks the health of a single dependency
|
154 | * Example:
|
155 | *
|
156 | * copacetic.check({ name: 'database' })
|
157 | * copacetic.check({ name: 'cache', retries: 2 })
|
158 | */
|
159 | check(options: {
|
160 | name: string,
|
161 | retries?: number
|
162 | }): Copacetic
|
163 |
|
164 | /**
|
165 | * Checks the health of a set of dependencies
|
166 | * Example:
|
167 | *
|
168 | * copacetic.check({
|
169 | * dependencies: [
|
170 | * { name: 'database', retries: 2 },
|
171 | * { name: 'cache' }
|
172 | * ],
|
173 | * parallel: false
|
174 | * })
|
175 | *
|
176 | */
|
177 | check(options: {
|
178 | dependencies: Array<{ name: string, retries?: number }> ,
|
179 | retries?: number
|
180 | parallel?: boolean
|
181 | }): Copacetic
|
182 | }
|
183 |
|
184 |
|
185 | declare function copacetic(
|
186 | /**
|
187 | * The name of your service. This is output in the express
|
188 | * middleware when verbose is true
|
189 | */
|
190 | name?: string,
|
191 | ): Copacetic
|
192 |
|
193 | declare namespace copacetic {
|
194 | /**
|
195 | * holds information about the health of a dependency, and executes strategies for
|
196 | * checking a dependency's health
|
197 | */
|
198 | interface Dependency {
|
199 | /**
|
200 | * The identifier used for the dependency
|
201 | */
|
202 | name: string,
|
203 |
|
204 | /**
|
205 | * The relationship between a service and dependency
|
206 | */
|
207 | level: dependencyLevel,
|
208 |
|
209 | /**
|
210 | * Whether the dependency passed a health check
|
211 | */
|
212 | healthy: boolean,
|
213 |
|
214 | /**
|
215 | * The method used for checking a dependencies health
|
216 | */
|
217 | healthStrategy: HealthStrategy,
|
218 |
|
219 | /**
|
220 | * How a health strategy will delay itself before executing again
|
221 | */
|
222 | backoffStrategy: BackoffStrategy,
|
223 |
|
224 | /**
|
225 | * The description of a dependency's health
|
226 | */
|
227 | healthSummary: Health,
|
228 |
|
229 | /**
|
230 | * sets a dependency's status to healthy
|
231 | */
|
232 | onHealthy (): void,
|
233 |
|
234 | /**
|
235 | * sets a dependency's status to unhealthy
|
236 | */
|
237 | onUnhealthy (): void,
|
238 |
|
239 | /**
|
240 | * performs any cleanup needed
|
241 | */
|
242 | cleanup (): void,
|
243 |
|
244 | check (
|
245 | /**
|
246 | * The number of times a dependency's health will be checked
|
247 | * before giving up
|
248 | */
|
249 | retries?: number
|
250 | ): Promise<Health>,
|
251 | }
|
252 |
|
253 | /**
|
254 | * The description of a dependency's health
|
255 | */
|
256 | export interface Health {
|
257 | /**
|
258 | * The name of the dependency that this health report belongs to
|
259 | */
|
260 | name: string,
|
261 | /**
|
262 | * Whether the dependency passed a health check
|
263 | */
|
264 | healthy: boolean,
|
265 | /**
|
266 | * The relationship between a service and dependency
|
267 | */
|
268 | level: dependencyLevel,
|
269 | /**
|
270 | * The last time the dependency was health checked
|
271 | */
|
272 | lastChecked: Date
|
273 | }
|
274 |
|
275 | /**
|
276 | * A method for checking a dependencies health
|
277 | */
|
278 | export interface HealthStrategy {
|
279 | new (
|
280 | /**
|
281 | * How long to wait until giving up. of the format
|
282 | * '5 seconds', '1m minute 20 seconds' etc.
|
283 | */
|
284 | timeout: string
|
285 | ) : HealthStrategy
|
286 |
|
287 | /**
|
288 | * Check a dependency's health
|
289 | * Example:
|
290 | *
|
291 | * dependency
|
292 | * .check('my-resource', '5 seconds')
|
293 | * .then(() => { ... do something now it's healthy })
|
294 | * .then(() => { ... handle degraded state })
|
295 | */
|
296 | check (
|
297 | /**
|
298 | * The resource accessed when checking the health of a dependency
|
299 | */
|
300 | url: string,
|
301 | /**
|
302 | * How long to wait until giving up. of the format
|
303 | * '5 seconds', '1m minute 20 seconds' etc.
|
304 | */
|
305 | timeout: string
|
306 | ) : Promise<boolean>
|
307 |
|
308 | /**
|
309 | * Perform any cleanup operation, if needed, when a dependency
|
310 | * is no longer in used
|
311 | * Example:
|
312 | *
|
313 | * dependency
|
314 | * .cleanup()
|
315 | * .then(() => { ... cleanup went OK })
|
316 | * .then(() => { ... cleanup failed })
|
317 | */
|
318 | cleanup (...args: any[]) : Promise<boolean>
|
319 | }
|
320 |
|
321 | /**
|
322 | * Some function that returns a promise
|
323 | */
|
324 | export interface BackOffCallable {
|
325 | () : Promise<boolean>
|
326 | }
|
327 |
|
328 | /**
|
329 | * A way of delaying some callable. Returns a promise after X
|
330 | * retries
|
331 | */
|
332 | export interface BackoffStrategy {
|
333 | new(
|
334 | /** the number of times execute will try the callable before giving up **/
|
335 | maxRetries: number
|
336 | ) : BackoffStrategy
|
337 |
|
338 | /**
|
339 | * execute some function, retrying some set number of times before failing
|
340 | */
|
341 | execute (callable: BackOffCallable) : Promise<boolean>
|
342 | }
|
343 |
|
344 | /**
|
345 | * Options used for creating a health strategy via the
|
346 | * HealthStrategy factory
|
347 | */
|
348 | export interface HealthStrategyOptions {
|
349 | /**
|
350 | * The type of health strategy to use, i.e. http, mongodb, redis
|
351 | */
|
352 | type: string,
|
353 | /**
|
354 | * The configuration options for the type of strategy you want to use
|
355 | * i.e. timeout
|
356 | */
|
357 | opts?: object,
|
358 | /**
|
359 | * A custom adapter to use for a health strategy, i.e. you may want to use some
|
360 | * library/database driver copacetic doesn't support out of the box
|
361 | */
|
362 | adapter?: Function
|
363 | }
|
364 |
|
365 | /**
|
366 | * Options used for registering a new dependency
|
367 | */
|
368 | export interface DependencyOptions {
|
369 | /**
|
370 | * Configuration options for a health strategy
|
371 | */
|
372 | strategy?: HealthStrategyOptions,
|
373 | /**
|
374 | * The relationship between a service and dependency
|
375 | */
|
376 | level?: dependencyLevel,
|
377 | /**
|
378 | * The identifier used for a dependency
|
379 | */
|
380 | name: string,
|
381 | /**
|
382 | * The resource accessed when checking the health of a dependency
|
383 | */
|
384 | url: string
|
385 | }
|
386 |
|
387 | /**
|
388 | * Options for using the express middleware
|
389 | */
|
390 | export interface MiddlewareOptions {
|
391 | /**
|
392 | * The instance of copacetic that will serve health information
|
393 | */
|
394 | copacetic: Copacetic,
|
395 | /**
|
396 | * The rate at which dependencies will be polled, of the format
|
397 | * '5 seconds', '1m minute 20 seconds' etc.
|
398 | */
|
399 | interval?: string,
|
400 | /**
|
401 | * An explicit set of dependencies to be health checked
|
402 | */
|
403 | dependencies?: Array<copacetic.Dependency>,
|
404 | /**
|
405 | * check the health of dependencies in sequence, or parallel
|
406 | */
|
407 | parallel?: boolean,
|
408 | /**
|
409 | * schedule the next check as soon as a poll starts, or wait
|
410 | */
|
411 | schedule?: string,
|
412 | /**
|
413 | * When true the middleware will output all health information
|
414 | * for the registered dependencies. If not verbose, only a status code
|
415 | * will be returned
|
416 | */
|
417 | verbose?: boolean
|
418 | }
|
419 |
|
420 | /**
|
421 | * Describes the relationship between your service and a dependency
|
422 | */
|
423 | export enum dependencyLevel {
|
424 | /** your service cannot function when a hard dependency is unavailable **/
|
425 | HARD,
|
426 | /** your service can still run, even if this dependency is unavailable **/
|
427 | SOFT
|
428 | }
|
429 | /**
|
430 | * express middleware for a copacetic instance
|
431 | */
|
432 | export function Middleware(options: MiddlewareOptions): Function
|
433 |
|
434 | /**
|
435 | * factory function for providing different health strategies
|
436 | */
|
437 | export function HealthStrategy(options: HealthStrategyOptions): Function
|
438 | }
|
439 |
|
440 | export = copacetic
|
441 |
|
\ | No newline at end of file |