openvibers/openvibe.shared Commits
Profile panel and user card: an 8 s limit, and a failed lookup is not kept (#280)
Changes
@@@ -29,8 +29,12 @@function load(username) {if (!seen.has(username)) {-- seen.set(username, fetch(`${api()}/api/v1/profiles/${encodeURIComponent(username)}`, { credentials: 'omit', headers: { Accept: 'application/json' } })-- .then((r) => (r.ok ? r.json() : null)).then((b) => (b && b.profile) || null).catch(() => null));++ // At most eight seconds, and a failure is not kept: a request held while Network restarted used to stay in++ // this map for the page's life, so that person's panel never opened again (11-03, the Live name card).++ const signal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(8000) : undefined;++ seen.set(username, fetch(`${api()}/api/v1/profiles/${encodeURIComponent(username)}`, { credentials: 'omit', headers: { Accept: 'application/json' }, signal })++ .then((r) => (r.ok ? r.json() : null)).then((b) => (b && b.profile) || null)++ .catch(() => { seen.delete(username); return null; }));}return seen.get(username);}nnew file mode 100644@@@ -0,0 +1,17 @@++'use strict';++// A name card never waits on a restarting service (11-03: Maticus's Live name card sat on "Loading..." for minutes++// while a deploy round restarted Chat). The shared profile panel and user card give a lookup eight seconds, and the++// panel does not keep a failed lookup, so a later click on the same name asks again.++const assert = require('assert');++const fs = require('fs');++const path = require('path');++const read = (f) => fs.readFileSync(path.join(__dirname, '..', f), 'utf8');++++const panel = read('profile-panel.js');++assert.match(panel, /AbortSignal\.timeout\(8000\)/);++assert.match(panel, /headers: \{ Accept: 'application\/json' \}, signal \}\)/, 'the panel\'s lookup carries the limit');++assert.match(panel, /\.catch\(\(\) => \{ seen\.delete\(username\); return null; \}\)/, 'a failed lookup is not kept');++const card = read('user-card.js');++assert.match(card, /AbortSignal\.timeout\(8000\)/);++assert.match(card, /credentials: 'include', signal \}\)/, 'the card\'s lookup carries the limit');++console.log('card fetch limits: ok');@@@ -94,7 +94,9 @@try {const headers = {};if (_config.token) headers['Authorization'] = `Bearer ${_config.token}`;-- const res = await fetch(`${_config.apiBase}/api/users/${userId}/card`, { headers, credentials: 'include' });++ // At most eight seconds: a click never waits on a service that is restarting (11-03).++ const signal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(8000) : undefined;++ const res = await fetch(`${_config.apiBase}/api/users/${userId}/card`, { headers, credentials: 'include', signal });if (!res.ok) return null;const data = await res.json();_cache.set(userId, data);
@@ -29,8 +29,12 @@
@@ -29,8 +29,12 @@
function load(username) {
function load(username) {
if (!seen.has(username)) {
if (!seen.has(username)) {
- seen.set(username, fetch(`${api()}/api/v1/profiles/${encodeURIComponent(username)}`, { credentials: 'omit', headers: { Accept: 'application/json' } })
- .then((r) => (r.ok ? r.json() : null)).then((b) => (b && b.profile) || null).catch(() => null));
+ // At most eight seconds, and a failure is not kept: a request held while Network restarted used to stay in
+ // this map for the page's life, so that person's panel never opened again (11-03, the Live name card).
+ const signal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(8000) : undefined;
+ seen.set(username, fetch(`${api()}/api/v1/profiles/${encodeURIComponent(username)}`, { credentials: 'omit', headers: { Accept: 'application/json' }, signal })
+ .then((r) => (r.ok ? r.json() : null)).then((b) => (b && b.profile) || null)
+ .catch(() => { seen.delete(username); return null; }));
}
}
return seen.get(username);
return seen.get(username);
}
}
new file mode 100644
new file mode 100644
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
+'use strict';
+// A name card never waits on a restarting service (11-03: Maticus's Live name card sat on "Loading..." for minutes
+// while a deploy round restarted Chat). The shared profile panel and user card give a lookup eight seconds, and the
+// panel does not keep a failed lookup, so a later click on the same name asks again.
+const assert = require('assert');
+const fs = require('fs');
+const path = require('path');
+const read = (f) => fs.readFileSync(path.join(__dirname, '..', f), 'utf8');
+
+const panel = read('profile-panel.js');
+assert.match(panel, /AbortSignal\.timeout\(8000\)/);
+assert.match(panel, /headers: \{ Accept: 'application\/json' \}, signal \}\)/, 'the panel\'s lookup carries the limit');
+assert.match(panel, /\.catch\(\(\) => \{ seen\.delete\(username\); return null; \}\)/, 'a failed lookup is not kept');
+const card = read('user-card.js');
+assert.match(card, /AbortSignal\.timeout\(8000\)/);
+assert.match(card, /credentials: 'include', signal \}\)/, 'the card\'s lookup carries the limit');
+console.log('card fetch limits: ok');
@@ -94,7 +94,9 @@
@@ -94,7 +94,9 @@
try {
try {
const headers = {};
const headers = {};
if (_config.token) headers['Authorization'] = `Bearer ${_config.token}`;
if (_config.token) headers['Authorization'] = `Bearer ${_config.token}`;
- const res = await fetch(`${_config.apiBase}/api/users/${userId}/card`, { headers, credentials: 'include' });
+ // At most eight seconds: a click never waits on a service that is restarting (11-03).
+ const signal = typeof AbortSignal !== 'undefined' && AbortSignal.timeout ? AbortSignal.timeout(8000) : undefined;
+ const res = await fetch(`${_config.apiBase}/api/users/${userId}/card`, { headers, credentials: 'include', signal });
if (!res.ok) return null;
if (!res.ok) return null;
const data = await res.json();
const data = await res.json();
_cache.set(userId, data);
_cache.set(userId, data);