From 8e358cfeee2ca0bc9d8dfa96add663c6797b3824 Mon Sep 17 00:00:00 2001 From: Blayne Chard Date: Thu, 26 Feb 2026 13:23:53 +1300 Subject: [PATCH 1/3] build: disable logging every fetchId --- packages/lambda-tiler/src/index.ts | 1 - packages/lambda-tiler/src/util/config.loader.ts | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/lambda-tiler/src/index.ts b/packages/lambda-tiler/src/index.ts index 77f3502897..d7dd61cf4b 100644 --- a/packages/lambda-tiler/src/index.ts +++ b/packages/lambda-tiler/src/index.ts @@ -54,7 +54,6 @@ handler.router.hook('request', (req) => { handler.router.hook('response', (req, res) => { req.set('fetchCount', FsaLog.count); - req.set('fetches', FsaLog.requests); req.set('cacheSize', FsaCache.size); // Force access-control-allow-origin to everything res.header('access-control-allow-origin', '*'); diff --git a/packages/lambda-tiler/src/util/config.loader.ts b/packages/lambda-tiler/src/util/config.loader.ts index 337043cb09..5e28f88408 100644 --- a/packages/lambda-tiler/src/util/config.loader.ts +++ b/packages/lambda-tiler/src/util/config.loader.ts @@ -20,15 +20,17 @@ export class ConfigLoader { /** Exposed for testing */ static async getDefaultConfig(req?: LambdaHttpRequest): Promise { const config = getDefaultConfig(); + req?.timer.start('config:load'); // Look up the latest config bundle out of dynamodb, then load the config from the provided path const cb = await config.ConfigBundle.get('cb_latest'); if (cb == null) return config; - req?.timer.start('config:load'); - - return CachedConfig.get(fsa.toUrl(cb.path)).then((cfg) => { + const configUrl = fsa.toUrl(cb.path); + return CachedConfig.get(configUrl).then((cfg) => { req?.timer.end('config:load'); + req?.set('config', configUrl.href); + if (cfg == null) throw new LambdaHttpResponse(500, 'Unable to find latest configuration'); if (cfg.assets == null) cfg.assets = cb.assets; return cfg; @@ -45,7 +47,7 @@ export class ConfigLoader { static async load(req: LambdaHttpRequest): Promise { const rawLocation = req.query.get('config'); - if (rawLocation == null) return this.getDefaultConfig(); + if (rawLocation == null) return this.getDefaultConfig(req); const configLocation = isBase58(rawLocation) ? Buffer.from(base58.decode(rawLocation)).toString() : rawLocation; const configUrl = fsa.toUrl(configLocation); From 0019e4a71a31f25dfd309b5cadd8e560c1b50f42 Mon Sep 17 00:00:00 2001 From: Blayne Chard Date: Thu, 26 Feb 2026 14:52:15 +1300 Subject: [PATCH 2/3] refactor: prevent duplicate timers --- packages/lambda-tiler/src/util/config.loader.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/lambda-tiler/src/util/config.loader.ts b/packages/lambda-tiler/src/util/config.loader.ts index 5e28f88408..e29a187f12 100644 --- a/packages/lambda-tiler/src/util/config.loader.ts +++ b/packages/lambda-tiler/src/util/config.loader.ts @@ -20,7 +20,6 @@ export class ConfigLoader { /** Exposed for testing */ static async getDefaultConfig(req?: LambdaHttpRequest): Promise { const config = getDefaultConfig(); - req?.timer.start('config:load'); // Look up the latest config bundle out of dynamodb, then load the config from the provided path const cb = await config.ConfigBundle.get('cb_latest'); @@ -28,7 +27,6 @@ export class ConfigLoader { const configUrl = fsa.toUrl(cb.path); return CachedConfig.get(configUrl).then((cfg) => { - req?.timer.end('config:load'); req?.set('config', configUrl.href); if (cfg == null) throw new LambdaHttpResponse(500, 'Unable to find latest configuration'); @@ -46,6 +44,13 @@ export class ConfigLoader { } static async load(req: LambdaHttpRequest): Promise { + req.timer.start('config:load'); + const config = await this._load(req); + req.timer.end('config:load'); + return config; + } + + static async _load(req: LambdaHttpRequest): Promise { const rawLocation = req.query.get('config'); if (rawLocation == null) return this.getDefaultConfig(req); @@ -60,10 +65,9 @@ export class ConfigLoader { throw new LambdaHttpResponse(400, `Bucket: "${configUrl.hostname}" is not a allowed bucket location`); } - req.set('config', configUrl.href); - req.timer.start('config:load'); return CachedConfig.get(configUrl).then((f) => { - req.timer.end('config:load'); + req.set('config', configUrl.href); + if (f == null) throw new LambdaHttpResponse(400, `Invalid config location at ${configLocation}`); return f; }); From 6206e32462716e682a7eeddeb9166358c7e978f1 Mon Sep 17 00:00:00 2001 From: Blayne Chard Date: Thu, 26 Feb 2026 16:29:20 +1300 Subject: [PATCH 3/3] refactor: intermitent test --- .../src/routes/__tests__/health.test.ts | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/packages/lambda-tiler/src/routes/__tests__/health.test.ts b/packages/lambda-tiler/src/routes/__tests__/health.test.ts index 4fee37058d..e9dfd682cb 100644 --- a/packages/lambda-tiler/src/routes/__tests__/health.test.ts +++ b/packages/lambda-tiler/src/routes/__tests__/health.test.ts @@ -2,30 +2,17 @@ import assert from 'node:assert'; import { afterEach, before, beforeEach, describe, it } from 'node:test'; import { ConfigProviderMemory } from '@basemaps/config'; -import { LogConfig } from '@basemaps/shared'; -import { LambdaAlbRequest, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda'; +import { LambdaHttpResponse } from '@linzjs/lambda'; import { VectorTile, VectorTileFeature, VectorTileLayer } from '@mapbox/vector-tile'; -import { ALBEventRequestContext, Context } from 'aws-lambda'; import sinon from 'sinon'; import { FakeData } from '../../__tests__/config.data.js'; +import { mockRequest } from '../../__tests__/xyz.util.js'; import { ConfigLoader } from '../../util/config.loader.js'; import { getTestBuffer, healthGet, TestFeature, TestTiles, VectorTileProvider } from '../health.js'; import { TileXyzRaster } from '../tile.xyz.raster.js'; import { tileXyzVector } from '../tile.xyz.vector.js'; -const ctx: LambdaHttpRequest = new LambdaAlbRequest( - { - requestContext: null as unknown as ALBEventRequestContext, - httpMethod: 'get', - path: '/v1/tiles/health', - body: null, - isBase64Encoded: false, - }, - {} as Context, - LogConfig.get(), -); - // Function to create a vector tile with specific properties for testing function createTestTile(testFeatures: TestFeature[]): VectorTile { const layers: Record = {}; @@ -65,14 +52,14 @@ describe('/v1/health', () => { sandbox.restore(); }); - it('Should return bad response', () => { + it('Should return bad response', async () => { // Given ... a bad get tile response const BadResponse = new LambdaHttpResponse(500, 'Can not get Tile Set.'); sandbox.stub(TileXyzRaster, 'tile').resolves(BadResponse); sandbox.stub(tileXyzVector, 'tile').resolves(BadResponse); // When ...Then ... - assert.rejects(() => healthGet(ctx), BadResponse); + await assert.rejects(() => healthGet(mockRequest('/v1/tiles/health')), BadResponse); }); const Response1 = new LambdaHttpResponse(200, 'ok'); @@ -99,20 +86,20 @@ describe('/v1/health', () => { callbackVectorTile.onCall(1).resolves(testVectorTile2); // When ... - const res = await healthGet(ctx); + const res = await healthGet(mockRequest('/v1/tiles/health')); // Then ... assert.equal(res.status, 200); assert.equal(res.statusDescription, 'ok'); }); - it('Should return mis-match tile response', () => { + it('Should return mis-match tile response', async () => { // Given ... a bad get tile response for second get tile const callback = sandbox.stub(TileXyzRaster, 'tile'); callback.onCall(0).resolves(Response2); // When ... Then ... const BadResponse = new LambdaHttpResponse(500, 'TileSet does not match.'); - assert.rejects(() => healthGet(ctx), BadResponse); + await assert.rejects(() => healthGet(mockRequest('/v1/tiles/health')), BadResponse); }); });