Skip to content

Commit

Permalink
Memoized renderering (#37)
Browse files Browse the repository at this point in the history
Pre-render metrics on discovery once and then reuse rendered response.
  • Loading branch information
lstrojny committed Nov 24, 2022
1 parent 565f423 commit 6530479
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/adapters/http/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ export interface HttpServer {
onMetrics(): HttpResponse
onNotFound(): HttpResponse
onError(error: Error): HttpResponse
updateMetrics(metrics: Metric[]): void
onMetricsDiscovery(metrics: Metric[]): void
}
2 changes: 1 addition & 1 deletion src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class PrometheusExporterPlatform implements IndependentPlatformPlugin {
discover({ log: this.log, config: this.config })
.then((devices) => {
const metrics = aggregate(devices, new Date())
this.httpServer.updateMetrics(metrics)
this.httpServer.onMetricsDiscovery(metrics)
this.log.debug('HAP discovery completed, %d metrics discovered', metrics.length)
this.startHapDiscovery()
})
Expand Down
23 changes: 12 additions & 11 deletions src/prometheus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ function headers(contentType: string, headers: Record<string, string> = {}): Rec
}

export class PrometheusServer implements HttpServer {
private metricsInitialized = false
private metrics: Metric[] = []
private metricsDiscovered = false
private metricsResponse = ''

constructor(public readonly config: HttpConfig, public readonly log: Logger | undefined = undefined) {}
constructor(
public readonly config: HttpConfig,
public readonly log: Logger | undefined = undefined,
private readonly renderer: MetricsRenderer = new MetricsRenderer(config.prefix),
) {}

onRequest(): HttpResponse | undefined {
if (!this.metricsInitialized) {
if (!this.metricsDiscovered) {
return {
statusCode: 503,
headers: headers(textContentType, { 'Retry-After': String(retryAfterWhileDiscovery) }),
Expand All @@ -60,13 +64,10 @@ export class PrometheusServer implements HttpServer {
}

onMetrics(): HttpResponse {
const renderer = new MetricsRenderer(this.config.prefix)
const metrics = this.metrics.map((metric) => renderer.render(metric)).join('\n')

return {
statusCode: 200,
headers: headers(metricsContentType),
body: metrics,
body: this.metricsResponse,
}
}

Expand All @@ -86,9 +87,9 @@ export class PrometheusServer implements HttpServer {
}
}

updateMetrics(metrics: Metric[]): void {
this.metrics = metrics
this.metricsInitialized = true
onMetricsDiscovery(metrics: Metric[]): void {
this.metricsResponse = metrics.map((metric) => this.renderer.render(metric)).join('\n')
this.metricsDiscovered = true
}
}

Expand Down
10 changes: 5 additions & 5 deletions tests/adapters/http/fastify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('Fastify HTTP adapter', () => {

test('Serves 404 on / when metrics are available', () => {
const testServer = createTestServer()
testServer.prometheus.updateMetrics([])
testServer.prometheus.onMetricsDiscovery([])

return request(testServer.http)
.get('/')
Expand All @@ -58,7 +58,7 @@ describe('Fastify HTTP adapter', () => {
test('Serves metrics', () => {
const testServer = createTestServer()
const timestamp = new Date('2020-01-01 00:00:00 UTC')
testServer.prometheus.updateMetrics([
testServer.prometheus.onMetricsDiscovery([
new Metric('metric', 0.1, timestamp, { name: 'metric' }),
new Metric('total_something', 100, timestamp, { name: 'counter' }),
])
Expand All @@ -79,7 +79,7 @@ describe('Fastify HTTP adapter', () => {

test('Basic auth denied without user', () => {
const testServer = createTestServerWithBasicAuth({ joanna: secretAsBcrypt })
testServer.prometheus.updateMetrics([])
testServer.prometheus.onMetricsDiscovery([])

return request(testServer.http)
.get('/metrics')
Expand All @@ -90,7 +90,7 @@ describe('Fastify HTTP adapter', () => {

test('Basic auth denied with incorrect user', () => {
const testServer = createTestServerWithBasicAuth({ joanna: secretAsBcrypt })
testServer.prometheus.updateMetrics([])
testServer.prometheus.onMetricsDiscovery([])

return request(testServer.http)
.get('/metrics')
Expand All @@ -103,7 +103,7 @@ describe('Fastify HTTP adapter', () => {
test('Basic auth grants access', () => {
const testServer = createTestServerWithBasicAuth({ joanna: secretAsBcrypt })
const timestamp = new Date('2020-01-01 00:00:00 UTC')
testServer.prometheus.updateMetrics([
testServer.prometheus.onMetricsDiscovery([
new Metric('metric', 0.1, timestamp, { name: 'metric' }),
new Metric('total_something', 100, timestamp, { name: 'counter' }),
])
Expand Down

0 comments on commit 6530479

Please sign in to comment.