openvibers/openvibe.host Commits
Host browser check: ask Network's registry again while Network restarts (its own release failed the check) (#113)
Changes
@@@ -86,15 +86,34 @@ async function get(url, accept = '*/*') {return { status: r.status, type: r.headers.get('content-type') || '', body: await r.text() };}++/**++ * The services with a public origin, from Network's registry. A run right after Network's own release can meet Network++ * restarting (an error, or an empty list): it asks again, up to REGISTRY_TRIES times REGISTRY_WAIT_MS apart.++ */++const REGISTRY_TRIES = Math.max(1, Number(process.env.BROWSER_CHECK_REGISTRY_TRIES) || 6);++const REGISTRY_WAIT_MS = Math.max(0, Number(process.env.BROWSER_CHECK_REGISTRY_WAIT_MS) || 10_000);async function registry() {-- const r = await get(`${NETWORK}/api/v1/registry/services`, 'application/json');-- const body = JSON.parse(r.body);-- const out = [];-- for (const s of Array.isArray(body) ? body : body.services || []) {-- const o = s.publicOrigin || s.public_origin;-- if (o && /^https?:\/\//.test(o)) out.push({ id: s.id || s.name, origin: new URL(o).origin });++ let last = null;++ for (let attempt = 1; attempt <= REGISTRY_TRIES; attempt++) {++ try {++ const r = await get(`${NETWORK}/api/v1/registry/services`, 'application/json');++ if (r.status === 200) {++ const body = JSON.parse(r.body);++ const out = [];++ for (const s of Array.isArray(body) ? body : body.services || []) {++ const o = s.publicOrigin || s.public_origin;++ if (o && /^https?:\/\//.test(o)) out.push({ id: s.id || s.name, origin: new URL(o).origin });++ }++ if (out.length) return out;++ last = 'an empty list';++ } else last = `HTTP ${r.status}`;++ } catch (err) { last = err.message; }++ if (attempt < REGISTRY_TRIES) {++ errLog(`registry: ${last} (Network restarting?); asking again in ${Math.round(REGISTRY_WAIT_MS / 1000)} s`);++ await new Promise((resolve) => setTimeout(resolve, REGISTRY_WAIT_MS));++ }}-- return out;++ throw new Error(`Network's registry gave no services after ${REGISTRY_TRIES} tries (${last})`);}// Sites the run did not check, with the reason: listed in the summary and the report, never left out@@@ -115,6 +115,31 @@ runTests([assert.match(missing.err, /browser harness not found \(tried .*none\.js\)/);} finally { server.close(); fs.rmSync(dir, { recursive: true, force: true }); }}),++ test('Network restarting: the registry is asked again after an error or an empty list, then the run goes on', async () => {++ let asked = 0;++ const site = http.createServer((req, res) => {++ const port = site.address().port;++ if (req.url === '/api/v1/registry/services') {++ asked += 1;++ if (asked === 1) { res.writeHead(503, { 'content-type': 'text/html' }); return res.end('restarting'); }++ res.writeHead(200, { 'content-type': 'application/json' });++ return res.end(JSON.stringify({ services: asked === 2 ? [] : [{ id: 'good', publicOrigin: `http://good.localhost:${port}` }] }));++ }++ res.writeHead(200, { 'content-type': 'text/html' }); res.end('<!doctype html><title>x</title>');++ });++ await new Promise((ok) => site.listen(0, '127.0.0.1', ok));++ const dir = tmp();++ try {++ const env = { OV_NETWORK_ORIGIN: `http://127.0.0.1:${site.address().port}`, STUB_CALLS: path.join(dir, 'calls.jsonl'), BROWSER_CHECK_REGISTRY_WAIT_MS: '20' };++ const r = await runScript(['--harness', STUB, '--sites', 'good', '--no-axe', '--no-nav'], env);++ assert.strictEqual(r.code, 0, r.err + r.out);++ assert.strictEqual(asked, 3, 'an error, an empty list, then the services');++ assert.match(r.err, /registry: HTTP 503 \(Network restarting\?\)/);++ const down = await runScript(['--harness', STUB, '--sites', 'good'], { ...env, OV_NETWORK_ORIGIN: 'http://127.0.0.1:9', BROWSER_CHECK_REGISTRY_TRIES: '2' });++ assert.strictEqual(down.code, 2);++ assert.match(down.err, /Network's registry gave no services after 2 tries/);++ } finally { site.close(); fs.rmSync(dir, { recursive: true, force: true }); }++ }),test('--remote: the script and harness go over ssh into a temp dir, run with --json there, the report is written here', async () => {const server = await serve();const dir = tmp();
@@ -86,15 +86,34 @@ async function get(url, accept = '*/*') {
@@ -86,15 +86,34 @@ async function get(url, accept = '*/*') {
return { status: r.status, type: r.headers.get('content-type') || '', body: await r.text() };
return { status: r.status, type: r.headers.get('content-type') || '', body: await r.text() };
}
}
+/**
+ * The services with a public origin, from Network's registry. A run right after Network's own release can meet Network
+ * restarting (an error, or an empty list): it asks again, up to REGISTRY_TRIES times REGISTRY_WAIT_MS apart.
+ */
+const REGISTRY_TRIES = Math.max(1, Number(process.env.BROWSER_CHECK_REGISTRY_TRIES) || 6);
+const REGISTRY_WAIT_MS = Math.max(0, Number(process.env.BROWSER_CHECK_REGISTRY_WAIT_MS) || 10_000);
async function registry() {
async function registry() {
- const r = await get(`${NETWORK}/api/v1/registry/services`, 'application/json');
- const body = JSON.parse(r.body);
- const out = [];
- for (const s of Array.isArray(body) ? body : body.services || []) {
- const o = s.publicOrigin || s.public_origin;
- if (o && /^https?:\/\//.test(o)) out.push({ id: s.id || s.name, origin: new URL(o).origin });
+ let last = null;
+ for (let attempt = 1; attempt <= REGISTRY_TRIES; attempt++) {
+ try {
+ const r = await get(`${NETWORK}/api/v1/registry/services`, 'application/json');
+ if (r.status === 200) {
+ const body = JSON.parse(r.body);
+ const out = [];
+ for (const s of Array.isArray(body) ? body : body.services || []) {
+ const o = s.publicOrigin || s.public_origin;
+ if (o && /^https?:\/\//.test(o)) out.push({ id: s.id || s.name, origin: new URL(o).origin });
+ }
+ if (out.length) return out;
+ last = 'an empty list';
+ } else last = `HTTP ${r.status}`;
+ } catch (err) { last = err.message; }
+ if (attempt < REGISTRY_TRIES) {
+ errLog(`registry: ${last} (Network restarting?); asking again in ${Math.round(REGISTRY_WAIT_MS / 1000)} s`);
+ await new Promise((resolve) => setTimeout(resolve, REGISTRY_WAIT_MS));
+ }
}
}
- return out;
+ throw new Error(`Network's registry gave no services after ${REGISTRY_TRIES} tries (${last})`);
}
}
// Sites the run did not check, with the reason: listed in the summary and the report, never left out
// Sites the run did not check, with the reason: listed in the summary and the report, never left out
@@ -115,6 +115,31 @@ runTests([
@@ -115,6 +115,31 @@ runTests([
assert.match(missing.err, /browser harness not found \(tried .*none\.js\)/);
assert.match(missing.err, /browser harness not found \(tried .*none\.js\)/);
} finally { server.close(); fs.rmSync(dir, { recursive: true, force: true }); }
} finally { server.close(); fs.rmSync(dir, { recursive: true, force: true }); }
}),
}),
+ test('Network restarting: the registry is asked again after an error or an empty list, then the run goes on', async () => {
+ let asked = 0;
+ const site = http.createServer((req, res) => {
+ const port = site.address().port;
+ if (req.url === '/api/v1/registry/services') {
+ asked += 1;
+ if (asked === 1) { res.writeHead(503, { 'content-type': 'text/html' }); return res.end('restarting'); }
+ res.writeHead(200, { 'content-type': 'application/json' });
+ return res.end(JSON.stringify({ services: asked === 2 ? [] : [{ id: 'good', publicOrigin: `http://good.localhost:${port}` }] }));
+ }
+ res.writeHead(200, { 'content-type': 'text/html' }); res.end('<!doctype html><title>x</title>');
+ });
+ await new Promise((ok) => site.listen(0, '127.0.0.1', ok));
+ const dir = tmp();
+ try {
+ const env = { OV_NETWORK_ORIGIN: `http://127.0.0.1:${site.address().port}`, STUB_CALLS: path.join(dir, 'calls.jsonl'), BROWSER_CHECK_REGISTRY_WAIT_MS: '20' };
+ const r = await runScript(['--harness', STUB, '--sites', 'good', '--no-axe', '--no-nav'], env);
+ assert.strictEqual(r.code, 0, r.err + r.out);
+ assert.strictEqual(asked, 3, 'an error, an empty list, then the services');
+ assert.match(r.err, /registry: HTTP 503 \(Network restarting\?\)/);
+ const down = await runScript(['--harness', STUB, '--sites', 'good'], { ...env, OV_NETWORK_ORIGIN: 'http://127.0.0.1:9', BROWSER_CHECK_REGISTRY_TRIES: '2' });
+ assert.strictEqual(down.code, 2);
+ assert.match(down.err, /Network's registry gave no services after 2 tries/);
+ } finally { site.close(); fs.rmSync(dir, { recursive: true, force: true }); }
+ }),
test('--remote: the script and harness go over ssh into a temp dir, run with --json there, the report is written here', async () => {
test('--remote: the script and harness go over ssh into a temp dir, run with --json there, the report is written here', async () => {
const server = await serve();
const server = await serve();
const dir = tmp();
const dir = tmp();