Skip to content

Commit

Permalink
CLDR-17515 Improve the announcements protocol
Browse files Browse the repository at this point in the history
-Distinguish between -1 for no response yet, and 0 for no announcements yet

-Include the most recent ID in the response even if that particular announcement is filtered out, so that the client will not keep getting redundant filtered data when there are no new announcements
  • Loading branch information
btangmu committed Apr 5, 2024
1 parent d6ad707 commit d858020
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 24 deletions.
28 changes: 12 additions & 16 deletions tools/cldr-apps/js/src/esm/cldrAnnounce.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ let callbackSetData = null;
let callbackSetCounts = null;
let callbackSetUnread = null;

let alreadyGotId = 0;
const MOST_RECENT_ID_UNKNOWN = -1; // must be less than zero

/**
* The most recent announcement ID the back end has told us about
*
* MOST_RECENT_ID_UNKNOWN means the front end hasn't received a response yet;
* 0 means the response from the back end indicated no announcements exist yet
*/
let alreadyGotId = MOST_RECENT_ID_UNKNOWN;

/**
* Get the number of unread announcements, to display in the main menu
Expand Down Expand Up @@ -70,11 +78,7 @@ async function refresh(viewCallbackSetData, viewCallbackSetCounts) {
if (schedule.tooSoon()) {
return;
}
let p = null;
if (alreadyGotId) {
p = new URLSearchParams();
p.append("alreadyGotId", alreadyGotId);
}
const p = new URLSearchParams().append("alreadyGotId", alreadyGotId);
const url = cldrAjax.makeApiUrl("announce", p);
schedule.setRequestTime();
return await cldrAjax
Expand All @@ -90,8 +94,8 @@ function setPosts(json) {
if (json.unchanged) {
return;
}
alreadyGotId = json.mostRecentId;
thePosts = json;
setAlreadyGotId(thePosts);
const totalCount = thePosts.announcements?.length || 0;
let checkedCount = 0;
for (let announcement of thePosts.announcements) {
Expand All @@ -112,14 +116,6 @@ function setPosts(json) {
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;
}
Expand Down Expand Up @@ -178,7 +174,7 @@ async function combineAndValidateLocales(locs, validateLocCallback) {
}

function resetSchedule() {
alreadyGotId = 0;
alreadyGotId = MOST_RECENT_ID_UNKNOWN;
schedule.reset();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public Response getAnnouncements(
@HeaderParam(Auth.SESSION_HEADER) String sessionString,
@QueryParam("alreadyGotId")
@Schema(description = "The client already got this announcement ID")
@DefaultValue("0")
@DefaultValue("-1")
int alreadyGotId) {
CookieSession session = Auth.getSession(sessionString);
if (session == null) {
Expand All @@ -76,25 +76,39 @@ public Response getAnnouncements(
if (SurveyMain.isBusted() || !SurveyMain.wasInitCalled() || !SurveyMain.triedToStartUp()) {
return STError.surveyNotQuiteReady();
}
Boolean unchanged =
(alreadyGotId != 0
&& alreadyGotId == AnnouncementData.getMostRecentAnnouncementId());
AnnouncementResponse response = new AnnouncementResponse(session.user, unchanged);
final int mostRecentId = AnnouncementData.getMostRecentAnnouncementId();
final Boolean unchanged = alreadyGotId != -1 && alreadyGotId == mostRecentId;
final AnnouncementResponse response =
new AnnouncementResponse(session.user, unchanged, mostRecentId);
return Response.ok(response).build();
}

@Schema(description = "List of announcements")
public static final class AnnouncementResponse {
@Schema(description = "unchanged")
@Schema(description = "unchanged (true if request specified ID matching most recent ID)")
public boolean unchanged;

/**
* This ID is for the most recent announcement ID even if that announcement is filtered out,
* for example to exclude locales that are not of interest to the user who made the request.
* (The timestamp of the most recent announcement could just as well be used.) This way, the
* client will not endlessly keep getting redundant filtered data when there are no new
* announcements. The client may get redundant filtered data when a new announcement is made
* that doesn't pass the user's filter, but this will not happen more than once per new
* announcement. Further optimization would seem to require the back end to keep track of
* the most recent announcement ID for each filter, or else to repeat the database query for
* each request even if the result would be unchanged -- with dubious benefits.
*/
@Schema(description = "most recent announcement ID (even if filtered out)")
public int mostRecentId;

@Schema(description = "announcements")
public Announcement[] announcements;

public AnnouncementResponse(UserRegistry.User user, Boolean unchanged) {
public AnnouncementResponse(UserRegistry.User user, Boolean unchanged, int mostRecentId) {
this.unchanged = unchanged;

if (!unchanged) {
this.mostRecentId = mostRecentId;
List<Announcement> announcementList = new ArrayList<>();
AnnouncementData.get(user, announcementList);
announcements = announcementList.toArray(new Announcement[0]);
Expand Down

0 comments on commit d858020

Please sign in to comment.