-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLDR-16900 Shorten server response if unchanged; bug fix, refactor #3596
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -25,8 +25,11 @@ const schedule = new cldrSchedule.FetchSchedule( | |||||
let thePosts = null; | ||||||
|
||||||
let callbackSetData = null; | ||||||
let callbackSetCounts = null; | ||||||
let callbackSetUnread = null; | ||||||
|
||||||
let alreadyGotId = 0; | ||||||
|
||||||
/** | ||||||
* Get the number of unread announcements, to display in the main menu | ||||||
* | ||||||
|
@@ -36,29 +39,28 @@ async function getUnreadCount(setUnreadCount) { | |||||
if (setUnreadCount) { | ||||||
callbackSetUnread = setUnreadCount; | ||||||
} | ||||||
await refresh(callbackSetData); | ||||||
await refresh(callbackSetData, callbackSetCounts); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Refresh the Announcements page and/or unread count | ||||||
* | ||||||
* @param {Function} viewCallbackSetData the callback function for the Announcements page, or null | ||||||
* @param {Function} viewCallbackSetCounts the callback function for the Announcements page, or null | ||||||
* | ||||||
* The callback function for setting the data may be null if the Announcements page isn't open and | ||||||
* we're only getting the number of unread announcements to display in the main header | ||||||
*/ | ||||||
async function refresh(viewCallbackSetData) { | ||||||
async function refresh(viewCallbackSetData, viewCallbackSetCounts) { | ||||||
if (DISABLE_ANNOUNCEMENTS) { | ||||||
return; | ||||||
} | ||||||
if (viewCallbackSetData) { | ||||||
if (!callbackSetData) { | ||||||
// The Announcements page was just opened, so re-fetch the data immediately regardless | ||||||
// of how recently it was fetched previously (for unread count) | ||||||
schedule.reset(); | ||||||
} | ||||||
callbackSetData = viewCallbackSetData; | ||||||
} | ||||||
if (viewCallbackSetCounts) { | ||||||
callbackSetCounts = viewCallbackSetCounts; | ||||||
} | ||||||
if (!cldrStatus.getSurveyUser()) { | ||||||
if (viewCallbackSetData) { | ||||||
viewCallbackSetData(null); | ||||||
|
@@ -68,36 +70,64 @@ async function refresh(viewCallbackSetData) { | |||||
if (schedule.tooSoon()) { | ||||||
return; | ||||||
} | ||||||
const url = cldrAjax.makeApiUrl("announce", null); | ||||||
let p = null; | ||||||
if (alreadyGotId) { | ||||||
p = new URLSearchParams(); | ||||||
p.append("alreadyGotId", alreadyGotId); | ||||||
} | ||||||
const url = cldrAjax.makeApiUrl("announce", p); | ||||||
schedule.setRequestTime(); | ||||||
return await cldrAjax | ||||||
.doFetch(url) | ||||||
.then(cldrAjax.handleFetchErrors) | ||||||
.then((r) => r.json()) | ||||||
.then(setPosts) | ||||||
.catch((e) => console.error(e)); | ||||||
.catch(handleErrorOrNotModified); | ||||||
} | ||||||
|
||||||
function handleErrorOrNotModified(e) { | ||||||
if (e.message === "Not Modified") { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
should be able to check the status code directly - the message can be variable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would require changes to cldrAjax -- currently cldrAjax.handleFetchErrors is as follows:
The Error only contains response.statusText -- I'm not sure how to set e.status in a standard way |
||||||
// 304 | ||||||
if (CLDR_ANNOUNCE_DEBUG) { | ||||||
console.log("cldrAnnounce got " + e.message); | ||||||
} | ||||||
} else { | ||||||
console.error(e); | ||||||
} | ||||||
} | ||||||
|
||||||
function setPosts(json) { | ||||||
thePosts = json; | ||||||
schedule.setResponseTime(); | ||||||
setAlreadyGotId(thePosts); | ||||||
const totalCount = thePosts.announcements?.length || 0; | ||||||
let checkedCount = 0; | ||||||
for (let announcement of thePosts.announcements) { | ||||||
if (announcement.checked) { | ||||||
++checkedCount; | ||||||
} | ||||||
} | ||||||
const unreadCount = totalCount - checkedCount; | ||||||
if (callbackSetData) { | ||||||
callbackSetData(thePosts); | ||||||
callbackSetData(thePosts); // AnnouncePanel.vue | ||||||
} | ||||||
if (callbackSetCounts) { | ||||||
callbackSetCounts(unreadCount, totalCount); // AnnouncePanel.vue | ||||||
} | ||||||
if (callbackSetUnread) { | ||||||
const totalCount = thePosts.announcements?.length || 0; | ||||||
let checkedCount = 0; | ||||||
for (let announcement of thePosts.announcements) { | ||||||
if (announcement.checked) { | ||||||
++checkedCount; | ||||||
} | ||||||
} | ||||||
const unreadCount = totalCount - checkedCount; | ||||||
callbackSetUnread(unreadCount); | ||||||
callbackSetUnread(unreadCount); // MainHeader.vue (balloon icon) | ||||||
} | ||||||
return thePosts; | ||||||
} | ||||||
|
||||||
function setAlreadyGotId(thePosts) { | ||||||
for (let announcement of thePosts.announcements) { | ||||||
if (announcement.id > alreadyGotId) { | ||||||
alreadyGotId = announcement.id; | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
function canAnnounce() { | ||||||
return cldrStatus.getPermissions()?.userIsManager || false; | ||||||
} | ||||||
|
@@ -107,7 +137,7 @@ function canChooseAllOrgs() { | |||||
} | ||||||
|
||||||
async function compose(formState, viewCallbackComposeResult) { | ||||||
schedule.reset(); | ||||||
resetSchedule(); | ||||||
const init = cldrAjax.makePostData(formState); | ||||||
const url = cldrAjax.makeApiUrl("announce", null); | ||||||
return await cldrAjax | ||||||
|
@@ -119,6 +149,7 @@ async function compose(formState, viewCallbackComposeResult) { | |||||
} | ||||||
|
||||||
async function saveCheckmark(checked, announcement) { | ||||||
resetSchedule(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this fixes a bug -- otherwise, the "unread" number by the balloon icon in the main menu took 60 seconds before it updated in response to adding a checkmark for "I have read this" |
||||||
window.setTimeout(refreshCount, 1000); | ||||||
const init = cldrAjax.makePostData({ | ||||||
id: announcement.id, | ||||||
|
@@ -154,12 +185,18 @@ async function combineAndValidateLocales(locs, validateLocCallback) { | |||||
.catch((e) => console.error(`Error: ${e} validating locales`)); | ||||||
} | ||||||
|
||||||
function resetSchedule() { | ||||||
alreadyGotId = 0; | ||||||
schedule.reset(); | ||||||
} | ||||||
|
||||||
export { | ||||||
canAnnounce, | ||||||
canChooseAllOrgs, | ||||||
compose, | ||||||
getUnreadCount, | ||||||
refresh, | ||||||
resetSchedule, | ||||||
saveCheckmark, | ||||||
combineAndValidateLocales, | ||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,12 @@ public class Announcements { | |
mediaType = "application/json", | ||
schema = @Schema(implementation = STError.class))), | ||
}) | ||
public Response getAnnouncements(@HeaderParam(Auth.SESSION_HEADER) String sessionString) { | ||
public Response getAnnouncements( | ||
@HeaderParam(Auth.SESSION_HEADER) String sessionString, | ||
@QueryParam("alreadyGotId") | ||
@Schema(description = "The client already got this announcement ID") | ||
@DefaultValue("0") | ||
int alreadyGotId) { | ||
CookieSession session = Auth.getSession(sessionString); | ||
if (session == null) { | ||
return Auth.noSessionResponse(); | ||
|
@@ -71,6 +76,9 @@ public Response getAnnouncements(@HeaderParam(Auth.SESSION_HEADER) String sessio | |
if (SurveyMain.isBusted() || !SurveyMain.wasInitCalled() || !SurveyMain.triedToStartUp()) { | ||
return STError.surveyNotQuiteReady(); | ||
} | ||
if (alreadyGotId != 0 && alreadyGotId == AnnouncementData.getMostRecentAnnouncementId()) { | ||
return Response.notModified().build(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have some doubt whether this is a standard way to use notModified (304)... Possible alternatives include (1) setting headers so that the browser delivers cached response for 304 (but that's maybe less efficient -- needless work processing the identical json); (2) return 200 and short json, e.g., just json.unchanged = true; (3) Etag... |
||
} | ||
Comment on lines
+79
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might consider adding this here (see entry for 503, etc in the annotations on this function) @APIResponse(responseCode = "304", description = "No further announcements (past alreadyGotId"), There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good idea if tests pass, maybe best to merge this as-is since it does include bug fix and performance improvement; but keep ticket open and consider protocol improvements under discussion |
||
AnnouncementResponse response = new AnnouncementResponse(session.user); | ||
return Response.ok(response).build(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This schedule.reset isn't needed here anymore since now AnnouncePanel.vue "created" method calls cldrAnnounce.resetSchedule