mirror of
https://github.com/nestriness/nestri.git
synced 2026-11-03 22:22:39 +02:00
fix(api): the same game added to a run twice is one launch (#426)
Follow-up to #422, from the nesktop #3 review. POST /session/{id}/launch for a game that already has an open launch (requested or running, no stop requested) in the run now answers that launch with 200 instead of inserting a second one. The check runs under the run's row lock that addLaunch already takes, so two concurrent adds resolve to one launch. OpenAPI documents the 200. Tested: apps/api 208 pass against the local test Postgres, including a new test adding the same game twice concurrently.
This commit is contained in:
@@ -476,6 +476,11 @@ export namespace SessionApi {
|
||||
description:
|
||||
'Adds a launch to a run that its host has taken on and that is not being stopped; the host starts it in the box without stopping what already runs there. Answers with the launch: its `id` is what the launched game’s window carries, and what to stop when that window closes. A run that is waiting for a host, stopping or over is 409: ask for a new run instead. So is a run on a host that does not handle launches, with code `host_too_old`: stop the run and ask for a new one, as before launches. The run is still what is billed and what the allowance counts, so adding a launch asks nothing of either.',
|
||||
responses: {
|
||||
200: {
|
||||
content: { 'application/json': { schema: Result(Launch.Info) } },
|
||||
description:
|
||||
'That game already has a launch in this run that is not over: it is answered instead of a second one'
|
||||
},
|
||||
201: {
|
||||
content: { 'application/json': { schema: Result(Launch.Info) } },
|
||||
description: 'The launch has been requested'
|
||||
@@ -537,6 +542,8 @@ export namespace SessionApi {
|
||||
conflict('That run is not running, so it cannot take another launch');
|
||||
case 'hostTooOld':
|
||||
hostTooOld();
|
||||
case 'existing':
|
||||
return c.json({ data: result.launch }, 200);
|
||||
default:
|
||||
return c.json({ data: result.launch }, 201);
|
||||
}
|
||||
|
||||
@@ -226,6 +226,16 @@ describe('launches', () => {
|
||||
expect(run.launches.map((l: any) => l.state)).toEqual(['running', 'running']);
|
||||
});
|
||||
|
||||
test('the same game added twice is one launch', async () => {
|
||||
const { s, id, second } = await liveRun('launch-dedupe', 7109);
|
||||
const [a, b] = await Promise.all([addLaunch(s, id, second), addLaunch(s, id, second)]);
|
||||
const statuses = [a.status, b.status].sort();
|
||||
expect(statuses).toEqual([200, 201]);
|
||||
const ids = [((await a.json()) as any).data.id, ((await b.json()) as any).data.id];
|
||||
expect(ids[0]).toBe(ids[1]);
|
||||
expect((await read(s, id)).launches.length).toBe(2);
|
||||
});
|
||||
|
||||
test('a run that is not running takes no launch', async () => {
|
||||
const s = await scene('launch-notrunning', 7102);
|
||||
const { body } = await requestSession(s);
|
||||
|
||||
Reference in New Issue
Block a user