Add guards to regular change update polling
We are regularly polling every 10 seconds for change updates. If we
detect a new change message, then we show a toast to the user such that
they know that reloading the change is a good idea.
However, we are showing this toast too often, especially when the user
has just sent a reply themselves. The reason is that we did not have
any checks for the update still being relevant. This change adds two
checks: Is the change page loading? Was the change already updated?
This is most likely not fixing the issue 100%, but we are hoping for
99%. And we have plans for switching away from the polling updates
altogether, so we don't want to invest a huge amount of time into
fixing the remaining 1%.
Bug: Issue 13394
Change-Id: I579bf270c5ab8bca5343bd424a6f0122c8fb17ba
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 2504419..ce08a86 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -2138,7 +2138,8 @@
}
this._updateCheckTimerHandle = this.async(() => {
- fetchChangeUpdates(this._change, this.$.restAPI).then(result => {
+ const change = this._change;
+ fetchChangeUpdates(change, this.$.restAPI).then(result => {
let toastMessage = null;
if (!result.isLatest) {
toastMessage = ReloadToastMessage.NEWER_REVISION;
@@ -2152,7 +2153,12 @@
toastMessage = ReloadToastMessage.NEW_MESSAGE;
}
- if (!toastMessage) {
+ // We have to make sure that the update is still relevant for the user.
+ // Since starting to fetch the change update the user may have sent a
+ // reply, or the change might have been reloaded, or it could be in the
+ // process of being reloaded.
+ const changeWasReloaded = change !== this._change;
+ if (!toastMessage || this._loading || changeWasReloaded) {
this._startUpdateCheckTimer();
return;
}
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
index 3d530b5..179caaa 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
@@ -1971,7 +1971,7 @@
assert.isFalse(getChangeDetailStub.called);
});
- test('_startUpdateCheckTimer up-to-date', () => {
+ test('_startUpdateCheckTimer up-to-date', async () => {
const getChangeDetailStub =
sinon.stub(element.$.restAPI, 'getChangeDetail')
.callsFake(() => Promise.resolve(generateChange({
@@ -1981,8 +1981,9 @@
})));
element._serverConfig = {change: {update_delay: 12345}};
+ await flush();
- assert.isTrue(element._startUpdateCheckTimer.called);
+ assert.equal(element._startUpdateCheckTimer.callCount, 2);
assert.isTrue(getChangeDetailStub.called);
assert.equal(element.async.lastCall.args[1], 12345 * 1000);
});
@@ -2001,6 +2002,24 @@
done();
});
element._serverConfig = {change: {update_delay: 12345}};
+
+ assert.equal(element._startUpdateCheckTimer.callCount, 1);
+ });
+
+ test('_startUpdateCheckTimer respects _loading', async () => {
+ sinon.stub(element.$.restAPI, 'getChangeDetail')
+ .callsFake(() => Promise.resolve(generateChange({
+ // new patchset was uploaded
+ revisionsCount: 2,
+ messagesCount: 1,
+ })));
+
+ element._loading = true;
+ element._serverConfig = {change: {update_delay: 12345}};
+ await flush();
+
+ // No toast, instead a second call to _startUpdateCheckTimer().
+ assert.equal(element._startUpdateCheckTimer.callCount, 2);
});
test('_startUpdateCheckTimer new status shows an alert', done => {