Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
U014CQVU4LW can we add an endpoint that behaves [ch5384]
add - api endpoint for importer healthcheck
- Loading branch information
Matthew Eric Bassett
committed
Jul 10, 2020
1 parent
4502580
commit 4ac1798
Showing
4 changed files
with
123 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { UtilEither } from "./utils"; | ||
import * as BestBlock from "./services/bestblock"; | ||
|
||
const REQUEST_RATE_MS = 2000; | ||
const REQUEST_TIMEOUT_MS = 5000; | ||
const REQUEST_STALE_BLOCK = 50000; | ||
|
||
export type HealthCheckerStatus = "OK" | "DOWN" | "SLOW" | "BLOCK_IS_STALE"; | ||
|
||
export class HealthChecker { | ||
// given a function that returns a /bestBlock, this class | ||
// will spawn a thread that checks to see that /bestBlock | ||
// is changing over time. | ||
// If it is not, then we have an error! | ||
|
||
healthCheckerFunc : () => Promise<UtilEither<BestBlock.CardanoFrag>>; | ||
|
||
lastBlock : UtilEither<BestBlock.CardanoFrag>; | ||
lastTime : number; | ||
lastGoodBlockChange : number; | ||
currentBlock : [number, UtilEither<BestBlock.CardanoFrag>]; | ||
|
||
constructor( bestBlockFunc : () => Promise<UtilEither<BestBlock.CardanoFrag>> ) { | ||
this.healthCheckerFunc = bestBlockFunc; | ||
const currentTime = Date.now(); | ||
|
||
this.lastBlock = { kind: 'error', errMsg: 'init' }; | ||
this.lastTime = currentTime; | ||
this.lastGoodBlockChange = currentTime; | ||
this.currentBlock = [currentTime, { kind: 'error', errMsg: 'init' }]; | ||
|
||
setInterval( this.checkHealth, REQUEST_RATE_MS); | ||
|
||
} | ||
|
||
checkHealth = async () => { | ||
let mBlock : UtilEither<BestBlock.CardanoFrag> = { kind: 'error', errMsg: 'function failed' }; | ||
try { | ||
mBlock = await this.healthCheckerFunc(); | ||
} catch { | ||
} | ||
const currentTime = Date.now(); | ||
|
||
const [currentSavedTime, currentMBlock] = this.currentBlock; | ||
|
||
if(currentMBlock.kind !== this.lastBlock.kind) | ||
this.lastBlock = currentMBlock; | ||
if(currentMBlock.kind === 'ok' && this.lastBlock.kind === 'ok') | ||
if(currentMBlock.value.blockHeight !== this.lastBlock.value.blockHeight){ | ||
this.lastBlock = currentMBlock; | ||
this.lastGoodBlockChange = currentTime; | ||
} | ||
|
||
|
||
this.lastTime = currentSavedTime; | ||
this.currentBlock = [currentTime, mBlock]; | ||
} | ||
|
||
getStatus = ():HealthCheckerStatus => { | ||
const [currentSavedTime, currentMBlock] = this.currentBlock; | ||
if (currentMBlock.kind !== 'ok') | ||
return "DOWN"; | ||
if (currentSavedTime - this.lastTime > REQUEST_TIMEOUT_MS) | ||
return "SLOW"; | ||
if (currentSavedTime - this.lastGoodBlockChange > REQUEST_STALE_BLOCK) | ||
if(this.lastBlock.kind === 'ok') | ||
if(this.lastBlock.value.blockHeight === currentMBlock.value.blockHeight) | ||
return "BLOCK_IS_STALE"; | ||
return "OK"; | ||
|
||
} | ||
|
||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import axios from 'axios'; | ||
import { expect } from 'chai'; | ||
import { config, Config } from './config' | ||
|
||
import { UtilEither } from "../src/utils"; | ||
import * as BestBlock from "../src/services/bestblock"; | ||
import { HealthChecker } from "../src/HealthChecker"; | ||
|
||
const endpoint = config.apiUrl; | ||
|
||
describe('/importerhealthcheck', function() { | ||
this.timeout(10000); | ||
it('returns', async function() { | ||
let result = await axios.get(endpoint+"v2/importerhealthcheck"); | ||
expect(result.data).to.have.property('message'); | ||
expect(result.data.message).to.be.eql("Importer is OK"); | ||
}); | ||
it('fails for broken graphql api', async function () { | ||
const badFunc = async () : Promise<UtilEither<BestBlock.CardanoFrag>> => { | ||
return { kind: 'error', errMsg: 'haha I don\'t work' }; | ||
|
||
}; | ||
const healthChecker = new HealthChecker(badFunc); | ||
const status = healthChecker.getStatus(); | ||
expect(status).to.not.be.eql('OK'); | ||
|
||
|
||
}); | ||
}); |