mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
fix(server): tell a user over the routing allowance when to ask the relay again
The per-user 429 carried no Retry-After, so the planner left the relay alone for its full ten minutes and routed every day with OSRM meanwhile. It now answers like the installation limit does, with the minute the window takes.
This commit is contained in:
@@ -9,7 +9,12 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||
import type { ConfigType } from '@nestjs/config';
|
||||
import { VALHALLA_RELAY_REQUEST_SCHEMAS, compactValhallaRequest, type ValhallaRelayAction } from '@trek/shared';
|
||||
|
||||
/** Questions one user may put to the TREK Valhalla a minute, the browser and the server's own routing together. */
|
||||
/**
|
||||
* Questions one user may put to the TREK Valhalla a minute, the browser and the server's
|
||||
* own routing together. A day is one question of up to twenty stops however long it is,
|
||||
* and the road trip rail asks one a second at most, so a whole trip fits; past it the
|
||||
* refusal says when to come back (see `ask`).
|
||||
*/
|
||||
const QUESTIONS_PER_MINUTE = 60;
|
||||
/**
|
||||
* Questions the whole installation may put a minute. The TREK services allow
|
||||
@@ -93,7 +98,9 @@ export class RoutingRelayService {
|
||||
RATE_WINDOW_MS,
|
||||
now,
|
||||
);
|
||||
if (!allowed) throw new DomainError(429, 'Too many routing requests, try again in a minute');
|
||||
// With the wait it asks for: the planner leaves the relay alone that long and routes
|
||||
// the days with OSRM meanwhile, rather than for the ten minutes a refusal without one costs.
|
||||
if (!allowed) return refusal(429, 'Too many routing requests, try again in a minute', RATE_WINDOW_MS);
|
||||
const withinInstallation = await this.rateLimit.check(
|
||||
'valhalla-relay-installation',
|
||||
'all',
|
||||
|
||||
@@ -124,12 +124,12 @@ describe('RoutingRelayService.ask', () => {
|
||||
expect(safeFetchAdminConfigured).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('RELAY-006: holds every user to 60 questions a minute, each user apart', async () => {
|
||||
it('RELAY-006: holds every user to 60 questions a minute, each user apart, and says when to come back', async () => {
|
||||
vi.mocked(safeFetchAdminConfigured).mockImplementation(async () => upstream(200, '{}'));
|
||||
await oneByOne(times(60), () => relay.ask(1, 'height', { shape: [{ lat: 47, lon: 11 }] }));
|
||||
const refused = await relay.ask(1, 'route', ROUTE).catch((err: unknown) => err);
|
||||
expect(refused).toBeInstanceOf(DomainError);
|
||||
expect(refused).toMatchObject({ status: 429, message: 'Too many routing requests, try again in a minute' });
|
||||
const refused = await relay.ask(1, 'route', ROUTE);
|
||||
expect(refused).toMatchObject({ status: 429, retryAfter: '60' });
|
||||
expect(JSON.parse(refused.body.toString())).toEqual({ error: 'Too many routing requests, try again in a minute' });
|
||||
expect((await relay.ask(2, 'route', ROUTE)).status).toBe(200);
|
||||
expect(safeFetchAdminConfigured).toHaveBeenCalledTimes(61);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user