perf: skip unchanged live snapshot sections (#285)
This commit is contained in:
1 parent
e28472b268
commit
fedddb246d
10 files changed
+188
-20
No files matched your search
@@ -10,6 +10,8 @@ function createContextPoller({
|
||||
let inFlight = null;
|
||||
let timer = null;
|
||||
let stopped = false;
|
||||
let revisions = {};
|
||||
let retainedSnapshot = null;
|
||||
|
||||
function cancelTimer() {
|
||||
if (timer !== null) clearTimer(timer);
|
||||
@@ -31,14 +33,19 @@ function createContextPoller({
|
||||
|
||||
let request;
|
||||
try {
|
||||
request = fetchContext();
|
||||
request = fetchContext({ ...revisions });
|
||||
} catch (error) {
|
||||
request = Promise.reject(error);
|
||||
}
|
||||
inFlight = Promise.resolve(request)
|
||||
.then((snapshot) => {
|
||||
onSnapshot(snapshot);
|
||||
return snapshot;
|
||||
const changedSections = ['context', 'events', 'notifications'].filter(
|
||||
(section) => Object.prototype.hasOwnProperty.call(snapshot, section)
|
||||
);
|
||||
retainedSnapshot = retainedSnapshot ? { ...retainedSnapshot, ...snapshot } : { ...snapshot };
|
||||
revisions = { ...revisions, ...(snapshot.revisions || {}) };
|
||||
onSnapshot(retainedSnapshot, changedSections);
|
||||
return retainedSnapshot;
|
||||
})
|
||||
.catch((error) => {
|
||||
onError(error);
|
||||
|
||||
+18
-7
@@ -1004,8 +1004,15 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
function setClock() { qs('#clock').textContent = fmt(new Date()); }
|
||||
setClock(); setInterval(setClock, 1000);
|
||||
|
||||
async function fetchLiveSnapshot() {
|
||||
const res = await fetch('api/v1/live', { headers: { Accept: 'application/json' } });
|
||||
async function fetchLiveSnapshot(revisions = {}) {
|
||||
const params = new URLSearchParams();
|
||||
Object.entries(revisions).forEach(([section, revision]) => {
|
||||
if (Number.isInteger(revision) && revision >= 0) params.set(section + '_revision', revision);
|
||||
});
|
||||
const query = params.toString();
|
||||
const res = await fetch('api/v1/live' + (query ? '?' + query : ''), {
|
||||
headers: { Accept: 'application/json' },
|
||||
});
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status);
|
||||
return res.json();
|
||||
}
|
||||
@@ -2445,15 +2452,19 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
qs('#gitea-events-status').textContent = message;
|
||||
}
|
||||
|
||||
function renderLiveSnapshot(snapshot) {
|
||||
function renderLiveSnapshot(snapshot, changedSections = ['context', 'events', 'notifications']) {
|
||||
setOfflineWorkMode(false);
|
||||
offlineStatus.hidden = true;
|
||||
const contextFreshness = snapshot.freshness?.sections?.context;
|
||||
const eventsFreshness = snapshot.freshness?.sections?.events;
|
||||
const notificationFreshness = snapshot.freshness?.sections?.notifications;
|
||||
const contextChanged = changedSections.includes('context');
|
||||
const notificationsChanged = changedSections.includes('notifications');
|
||||
const eventsChanged = changedSections.includes('events');
|
||||
const workChanged = contextChanged || notificationsChanged;
|
||||
const hasNotifications = Array.isArray(snapshot.notifications);
|
||||
const notificationsFresh = hasNotifications && !notificationFreshness?.stale;
|
||||
if (hasNotifications) {
|
||||
if (notificationsChanged && hasNotifications) {
|
||||
if (notificationPagination.page > 1) {
|
||||
const byId = new Map(lastNotifications.map(item => [item.id, item]));
|
||||
snapshot.notifications.forEach(item => byId.set(item.id, item));
|
||||
@@ -2471,7 +2482,7 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
});
|
||||
}
|
||||
}
|
||||
if (snapshot.context) {
|
||||
if (snapshot.context && workChanged) {
|
||||
setOfflineWorkMode(false);
|
||||
const contextIdentityFresh = !snapshot.context.error && !contextFreshness?.stale &&
|
||||
!contextFreshness?.degraded && !contextFreshness?.revalidating;
|
||||
@@ -2494,8 +2505,8 @@ textarea { resize: vertical; min-height: 120px; }
|
||||
}
|
||||
flushIssueOutbox();
|
||||
flushAuthoredOutbox();
|
||||
} else handleContextError(new Error('Context section unavailable'));
|
||||
if (Array.isArray(snapshot.events)) paintEventStream(snapshot.events);
|
||||
} else if (!snapshot.context) handleContextError(new Error('Context section unavailable'));
|
||||
if (eventsChanged && Array.isArray(snapshot.events)) paintEventStream(snapshot.events);
|
||||
if (eventsFreshness?.revalidating) {
|
||||
setEventStreamStatus('Refreshing activity · showing last activity');
|
||||
} else if (eventsFreshness?.stale || eventsFreshness?.degraded) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const BASE = new URL('./', self.location.href).pathname;
|
||||
importScripts(BASE + 'static/background-issue-sync.js');
|
||||
const CACHE = 'stackchain-dashboard-shell-v22';
|
||||
const CACHE = 'stackchain-dashboard-shell-v23';
|
||||
const OUTAGE_STATUSES = new Set([500, 502, 503, 504]);
|
||||
const SHELL = [
|
||||
BASE,
|
||||
|
||||
Reference in new issue
Block a user