Skip to content
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

I1027 Add Contest Clock To WTI #1034

Open
wants to merge 142 commits into
base: develop
Choose a base branch
from

Conversation

clevengr
Copy link
Contributor

@clevengr clevengr commented Jan 12, 2025

Description of what the PR does

Adds "Elapsed Time" and "Remaining Time" counters to the WTI header bar whenever a team is logged in.

The counters are initialized with values read from the PC2 Server (via the WTI-API Server and its PC2 API connection) each time a team logs in. The counters respond appropriately to changes in the "PC2 contest clock" state -- that is, when the Admin "Starts" the contest the counters begin counting (up/down respectively), and the counters stop (freeze) whenever the Admin "Stops" (pauses) the contest. The counters also respond correctly to changes in the contest times; for example, if the Admin extends the contest (adds more time), then the "Remaining Time" counter automatically adjusts as appropriate.

Times are displayed in HH:MM:SS format, preceded by a number of days if the total time is greater than 24 hours.

The counters are driven by a JavaScript setInterval() object which ticks at a rate of once per second. To handle potential clock drift, the code automatically "resynchronizes" the on-screen counters with the current PC2 Server time, at a frequency defined by a constant in the WTI-UI constants.ts file (currently every 15 minutes).

A screenshot showing the clocks for a contest that was scheduled to run for 30 hours and has been running for just over an hour is shown here:

image

Issue which the PR addresses:

Fixes #1027, #1029

Environment in which the PR was developed (OS,IDE, Java version, etc.)

  • Windows 10 & 11
  • Eclipse Versions 2021-12 (4.22.0) and 2020-12 (4.18.0)
  • Java versions 1.8.0_381 and 11.0.16.1
  • Chrome Version 131.0.6778.109
  • MS Edge Version 131.0.2903.112

Precise steps for testing the PR :

  • Download and unzip the PR distribution.
  • Edit samps/contests/sumithello/config/contest.yaml: change from running:true to running:false,then save the updated file.
  • Start a PC2 server using --load sumithello.
  • Start a PC2 Admin; verify that the contest is NOT running and has NEVER BEEN STARTED (check the "Times" tab"; under "Started?" it should say "No").
  • In the PC2 "projects" folder, unzip the WebTeamInterface .zip file.
  • Go into the resulting WebTeamInterface folder, open a terminal command prompt, and start the WTI server with the command ./bin/pc2wti.
  • Open a browser, then hit F12 (or the browser's equivalent) to open the browser devtools; select the "Console" tab.
  • Enter "http://localhost:8080" in the browser address bar. Verify:
    • you are presented with the PC2 Login screen, and
    • no ERRORS appear on the browser console (there will be lots of debug/tracing messages, but none should say "Error").
  • Login as "team1/team1". Verify:
    • you are presented with the PC2 "Runs" screen
    • the Header displays a field "Elapsed Time: 00:00:00 (no contest time has elapsed because the contest hasn't been started)
    • the Header displays a field "Remaining Time: xx:xx:xx", where xx:xx:xx is the number of hours/mins/secs defined as the
      length of the contest (for the default values in the "sumithello" contest, that should be "05:00:00")
      Note: if you change the Contest Length in the contest.yaml file BEFORE STARTING THE SERVER, and the value you set for
      contest length is greater than 24 hours, the "Remaining Time" field should also include a count of the number of DAYS remaining.
    • neither the Elapsed Time nor the Remaining Time values are changing (because the contest isn't running).
    • there are no ERRORS on the browser console (again, there will be lots of tracing/debug messages, but there should be none marked ERROR)
  • In the browser, click on the Clarifications menu item; verify there are no ERROR messages in the browser console.
  • Click on the Runs menu item, then click on the "Select Problem" dropdown in the "Filters" pane. Verify that the contest problems are NOT shown.
  • On the PC2 Admin, START the contest, then verify:
    • the Elapsed Time field on the browser header starts counting up at a rate of once per second;
    • the Remaining Time field on the browser header starts counting down at a rate of once per second;
    • clicking on the "Select Problem" dropdown in the "Filters" pane now shows the contest problems (Sumit and Hello).
    • there are no ERROR messages on the browser console.
  • On the PC2 Admin, STOP ("pause") the contest, then verify:
    • both clock fields on the browser freeze;
    • the sum of the Elapsed time plus the Remaining Time on the browser header equals the "Contest Length" shown on the Admin "Length" field.
    • clicking on the "Select Problem" dropdown in the "Filters" pane still shows the contest problems.
    • there are no ERROR messages on the browser console.
  • Note the "frozen" times in the browser window header, then on the PC2 Admin, START ("un-pause") the contest, then verify:
    • both clock fields start changing again, with Elapsed counting up and Remaining counting down, from the times they were "frozen" at when the contest was stopped.
    • there are no ERROR messages on the browser console.
  • On the PC2 Admin, once again STOP the contest, then note the "Elapsed" and "Remaining" times which are now frozen on the browser header.
  • Hit F5 in the browser window; verify that
    • the Elapsed and Remaining Time clock values still have their same (frozen) values.
    • Clicking the "Select Problem" dropdown in the "Filters" pane still shows the contest problems.
  • On the PC2 Admin, START the contest again; verify that
    • the Elapsed and Remaining Time clocks resume counting correctly from their frozen values.
    • Clicking the "Select Problem" dropdown in the "Filters" pane still shows the contest problems.
  • On the browser window, hit the "Logout" menu item; verify that you are returned to the PC2 Login screen.
  • Login as another team; verify that the Elapsed and Remaining Time counters start at the expected values and are correctly changing (the current "Elapsed" and "Remaining" times can be seen by hitting the "Refresh" button on the Admin "Times" tab).
  • On the Admin, STOP the contest, then EXTEND the length of the contest by some amount (on the Admin "Times" screen, select Site1, click "Edit", add some time to "Contest Length", and also add a corresponding amount of time to "Current Remaining Time".) Click "Update", then verify that the "Remaining Time" on the team browser is properly updated.
  • On the Admin, START the contest, then verify that the browser times begin properly changing again (and that "Remaining Time" correctly shows the updated value).
  • MINIMIZE the team browser, wait a minute, then restore the browser. Watch the "Elapsed Time" field as the browser is restored; it will start by displaying the elapsed time as it was AT THE MOMENT IT WAS MINIMIZED but should then (almost immediately) be updated to the correct elapsed time (which can be determined by hitting the "Refresh" button on the Admin "Times" window). (This is happening because JavaScript timers don't run at the correct rate when the browser is minimized;
    a separate issue will be filed for this.)

johnc and others added 30 commits December 14, 2024 16:52
can be used to transform Date objects into strings displaying
day/hours/minutes/seconds.
- a count of the number of elapsed seconds (planned for removal), and
- a string showing days plus hh:mm:ss (the real plan).
@clevengr clevengr added enhancement New feature or request WTI-UI This bug or feature request applies to the WTI-UI (browser-side). Usability Issue This is an enhancement for which there is currently no usable workaround medium-high Should be consider for next release In PR code review NEXT Contest Consider fixing for next contet Primary CCS Required for PC2 to act as primary CCS labels Jan 12, 2025
Copy link
Collaborator

@kkarakas kkarakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not run it on my machine yet, but these are my opinions. Looks like it would work well!

console.error ("LoginPageComponent.onSubmit() ContestClock subscription callback: unable to get ContestClock from PC2 API via ContestService!");
} else {
//copy the data fields received from the PC2 Server (via the WTI-API) into the local ContestClock object
this.contestClock.isRunning = data.running ;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of nested conditionals here, maybe we can use break to break out of conditions. This would improve readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite follow this comment. As far as I can tell there are no nested conditionals which would allow using break. What there ARE (or at least, WERE) are a lot of "debug if's". I will remove all those debug statements; hopefully the logic will be clearer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant return sorry. Maybe the method can be terminated early if it is not going to lead anywhere?

Copy link
Contributor Author

@clevengr clevengr Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the large number of "debug" statements, which makes the nested conditionals pretty easy to follow (as JohnB has noted elsewhere, the traditional JavaScript usage of "lamba functions" does complicate it a little bit). As it now stands I don't really see where there's any place that the addition of "return" statements would be particularly helpful...

Let me know if you have a specific suggestion (short of rewriting the whole thing avoiding lambda expressions :) for improving it further. If not, please mark the conversation "Resolved".

* and if wallClockStartTime is greater than zero it fetches the current problem list from the server and displays it in the
* component; otherwise it sets the list of displayed problems to an empty list (array).
*/
private loadProblems(): void {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woah. Is it possible to simplify this method through having multiple methods breaks etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the previous comment, I don't see any way to use breaks to address this. As before, I think the problem was the large number of "debug" ifs in the code, making it hard to see the structure. I've eliminated all those debug statements; hopefully that makes the code more readable. I'll welcome any suggestion for how to use breaks to simplify it further.

Copy link
Collaborator

@johnbrvc johnbrvc Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the in-line lambda function is what clutters it up. Folks love doing that in javascript too, and it makes it very hard to follow and read. I guess it's the nature of the beast.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant return sorry. Maybe the method can be terminated early if it is not going to lead anywhere?

Copy link
Contributor Author

@clevengr clevengr Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted, I've removed the large number of "debug" statements; hopefully this makes the code clearer. Also, as @johnbrvc noted, the use of JavaScript "lambda functions" makes it a little hard to read. (I didn't write that code originally, and I'm reluctant to change it as part of this PR. If you think it still needs to be changed, I suggest submitting a separate Issue for cleaning that up...)

Again, let me know if you have a specific suggestion (short of rewriting the whole thing avoiding lambda expressions :) for improving it further. If not, please mark the conversation "Resolved".

@clevengr clevengr requested a review from kkarakas February 6, 2025 22:10
Copy link
Collaborator

@kkarakas kkarakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More opinions!

Comment on lines +83 to +85
if (this.intervalId) {
console.error("ContestTimerService.startTimer(): call to startTimer() when timer is already running");
return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tabbing doesn't seem to match on my screen here and other places. Is this intentional?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is just on my screen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are talking about the way indentation appears when you look at the code in Eclipse, that's a function of your Eclipse settings -- both global settings and the setting for the particular editor you're viewing it with. At one point in time we (the early members of the PC2 project) had agreed upon a common set of indentation settings; perhaps yours don't match?

(If it's NOT in Eclipse that you're talking about, then where is it?)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that there is an actual "TAB" character on the lines in question. As @clevengr pointed out, if your Eclipse settings are "right" (by "right" I mean that they match ours), it will line up properly. What IS interesting is, the code indenting appears to violate the indenting rules that we use in the java code. The particular line in @kkarakas example has a TAB SPACE SPACE. It seems to me, if TAB is 4 spaces, then the next level of indenting should be a total of 8 spaces (however you want to arrive at that: TAB TAB, 8x SPACE, etc.) Not sure where the "+2" spaces comes from, unless that's standard for TS? I attached a screenshot of my general editor properties.
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% positive, but I think the "default standard" for TypeScript IS "2 space indents". I say this only because almost all the TS code we inherited from the students who did the original WTI project was indented by 2 spaces (on each indent). I know that has caused some aggravation for me... Not sure how we "fix" this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's fine, but what they did initially, it seems, is they "know" that TAB is 4 spaces, which is 2 "TS" indents, one keypress. Ugh. So, I guess just set your TAB to 4 spaces, and you should be ok. The problem is, adding new code, you have to be aware of this and increase levels by 2 spaces...

Comment on lines +17 to +26
padding-left: 8px;
padding-right: 8px;
}

/* Set the container holding the contest clock value(s) to medium, white font */
.clock-container {
color: white;
font-size: 1.0rem;
padding-left: 8px;
padding-right: 8px;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some concerns about how these pixel paddings would look in different window sizes. Did you play around with different window size and different pixel counts? Perhaps we could use relative units such as em/ rem, vw, just like you use it for font-size. But this is not necessarily problematic, there are cases where pixels are better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did try it using various window sizes, and I didn't spot any problems. Do you have a specific example of a platform and window size which shows a problem?

Regarding the "pixel paddings", I didn't create those; they came from a CSS file I got from @johnbrvc . But I haven't observed any issues with it (I tested it in both Chrome and Edge, using various window sizes). Again, do you have an example of a specific situation where a problem is demonstrated?

- use concrete data types rather than "any".
- remove debug statements.
- use "const" instead of "let" in variable declarations where
applicable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request In PR code review medium-high Should be consider for next release NEXT Contest Consider fixing for next contet Primary CCS Required for PC2 to act as primary CCS Usability Issue This is an enhancement for which there is currently no usable workaround WTI-UI This bug or feature request applies to the WTI-UI (browser-side).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a contest clock to WTI
3 participants