-
Notifications
You must be signed in to change notification settings - Fork 298
[DDW-1088] Fix no progress shown on loading screen on Windows #2967
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
[DDW-1088] Fix no progress shown on loading screen on Windows #2967
Conversation
5ab1201 to
761d05a
Compare
|
@marcin-mazurek I think the |
| const percentage = line.match(/Progress:([\s\d.,]+)%/)?.[1]; | ||
| const progressType = getProgressType(line); | ||
| if (!percentage || !progressType) { | ||
| const unparsedProgress = line.match(/Progress:([\s\d.,]+)%/)?.[1]; |
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.
I've decided to make the variable names more concise as the if in line 70 was getting a bit too big to read it easily.
|
|
||
| const progress = Math.floor(parseFloat(unparsedProgress)); | ||
|
|
||
| if (lastReportedProgressByType[type] !== progress) { |
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 helps us ensure we're not sending duplicate events via IPC, and mitigates the risk of getting the MaxListenersExceededWarning, which could previously be observed while trying to send multiple (10+) messages at once.
The way fs.fileWatch works is, it pools for file changes every 5 seconds (by default) and invokes given callback for each line - so if there are 100 new lines added in 5 seconds = 100 callback calls = 100 IPC messages.
| // https://github.com/nodejs/node/issues/36888 | ||
| // https://github.com/lucagrulla/node-tail/issues/137 | ||
| // https://nodejs.org/dist/latest-v14.x/docs/api/fs.html#fs_caveats | ||
| useWatchFile: environment.isWindows, |
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 is the actual fix for Windows.
| className={makePercentageCellStyles(props[type] === 100)} | ||
| > | ||
| {Math.floor(props[type])}% | ||
| {props[type]}% |
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.
I moved this to the main process so we can compare against actually displayed values (currently we're getting values as float and then dropping the fractional part in the component itself, which results in unnecessary re-renders)
…ogress-on-win-splash-screen
|
@marcin-mazurek The behavior is as expected in most scenarios, but I found some inconsistencies:
|
|
Hi @marcin-mazurek , For build 21637, on Linux when starting the first time all 3 items were showing 0%. The percentages never went up. But the transition to main screen happened eventually. However, the subsequent attempts did show percentages going up. When retested with production, the production did show percentages going up the first time I ran Daedalus. (ps: I didn't take any video as some of the issues overlap with what @gabriela-ponce found here) |
…ges are lost if the IPC subscription is registered late
| } | ||
|
|
||
| const progress = Math.floor(parseFloat(unparsedProgress)); | ||
| // In rare cases cardano-node does not log 100%, therefore we need to manually mark the previous step as complete. |
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 mitigates the risk of having a race condition. In rare cases the log entries can be pushed before we set up the file watch mechanism, so this additional logic ensures we mark previous steps as complete when the next steps starts. This also improves UX as currently sometimes cardano-node doesn't report 100% progress.
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.
I believe the initial goal was to have the UI matching 1:1 the logs so the users could report the exactly progress in case they get stuck. @dmitrii-gaico Do you think this new behavior is fine ?
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.
Alternatively we can read past entries from the file. @szymonmaslowski found out that there is a param in tail that allows us to do that.
But to be fair, I believe it just depends how you interpret logs. Eg. you can interpret the following entry:
�[34m[Marcins-:cardano.node.ChainDB:Info:19]�[0m [2022-04-27 12:30:36.94 UTC] Opened lgr db
�[34m[Marcins-:cardano.node.ChainDB:Info:19]�[0m [2022-04-27 12:30:36.94 UTC] Started initial chain selection
as "replayed block is completed". It just doesn't match the Progress: x%. But makes the UX much better and shows the truth. The steps are sequential, but previous logic would often result in showing the previous step is stuck at eg. 67% and next step is complete, while that's not true.
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.
Are we 100% the steps are sequential? Often cardano-node would output in a different order depending of the ledger state.
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.
Although I observed this behaviour consistently while testing, I might be wrong. Since this implementation is controversial, I'll reimplement this with the approach @szymonmaslowski suggested - using the fromBeginning param from tail.
|
|
||
| if (progressReport[type] !== progress) { | ||
| progressReport[type] = progress; | ||
| getBlockSyncProgressChannel.send(progressReport, mainWindow.webContents); |
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.
Instead of sending report for a specific type, we will send the whole progress report. This resolves the issue where the IPC channel subscription in the renderer is registered late and messages from the main thread are sent into the void in case sync step is very quick.
Question for people more experienced with IPC: is there any way to send a 'sticky' message (messsage which can be delivered to subscriptions registered after the message was sent)? If so, we could just slightly tweak the previous implementation which sends less data... However, I tried searching for it and couldn't find anything.
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.
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.
I don't know about the electron IPC implementation but the node IPC protocol itself does not support queueing messages. I think sending the entire progressReport object totally makes sense. It is not a concern from the performance perspective.
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.
Agreed sending a snapshot of progressReport , that's smart.
|
@gabriela-ponce @miorsufianiohk could you please have one more look when you get the chance? Hopefully I addressed the scenarios you've described.
|
szymonmaslowski
left a comment
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.
Good job!
| tail.on('line', handleNewLogLine); | ||
| }; | ||
|
|
||
| const waitForLogFileToBeCreatedAndWatchLogFile = ({ |
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.
| const waitForLogFileToBeCreatedAndWatchLogFile = ({ | |
| const waitForLogFileToBeCreatedAndWatchIt = ({ |
|
|
||
| if (progressReport[type] !== progress) { | ||
| progressReport[type] = progress; | ||
| getBlockSyncProgressChannel.send(progressReport, mainWindow.webContents); |
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.
I don't know about the electron IPC implementation but the node IPC protocol itself does not support queueing messages. I think sending the entire progressReport object totally makes sense. It is not a concern from the performance perspective.
|
@marcin-mazurek @szymonmaslowski Hello! Let's keep this PR as a Fix Only and gather all the "suggestions to improve" in a separate card so we can implement those in near future. Thank you in advance! |
…ed previous sync steps as complete when 100% was not seen in logs
|
@gabriela-ponce @miorsufianiohk @dmitrii-gaico I just pushed another change, which is a result of a discussion we had in the code review. Please use the 21648 build for testing. Sorry for last minute change. |
danielmain
left a comment
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.
Clean and well refactor 💪
Great job @marcin-mazurek !
|
@danielmain kudos to @lucas-barros too as he contributed to this PR! |

This PR fixes the issue with no progress shown on the loading screen on Windows.
Screenshots
Testing Checklist
Review Checklist
Basics
input-output-hk/daedalus-devandinput-output-hk/daedalus-qaassigned as PR reviewersIf there are UI changes, Alexander Rukin assigned as an additional reviewerAll visual regression testing has been reviewed (assignrun Chromaticlabel to PR to trigger the run)release-vNext,feature/bug/chore,WIP)There are no missing translations (runningyarn manage:translationsproduces no changes)Text changes are proofread and approved (Jane Wild / Amy Reeve)Japanese text changes are proofread and approved (Junko Oda)yarn storybook)In case of dependency changesyarn.lockfile is updatedCode Quality
Testing
After Review