-
Notifications
You must be signed in to change notification settings - Fork 53
Push: Check existing progress of push on start #1943
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
Conversation
📊 Performance Test ResultsComparing f3e82e8 vs trunk site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change |
0826961 to
7dad8c9
Compare
7dad8c9 to
606f6b3
Compare
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.
Pull Request Overview
This PR implements functionality to restore push operations that were in progress when Studio was closed, ensuring users can track ongoing sync operations across app restarts.
Key Changes:
- Adds startup check for in-progress push operations via server API query
- Maps server import response statuses to internal push state objects
- Updates active sync operation tracking when restoring push states
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/lib/active-sync-operations.ts | Removes unused getSyncOperations() function |
| src/hooks/sync-sites/use-sync-push.ts | Adds mapImportResponseToPushState() helper and guards addSyncOperation call |
| src/hooks/sync-sites/sync-sites-context.tsx | Implements useEffect to check and restore in-progress push operations on mount |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
sejas
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.
Feature-wise, it works as described. I confirm that it continues polling push information from the backend after restarting the app. ✨
applying.changes.works.as.expected.mp4
| // Query the server for each connected site to check for in-progress operations | ||
| for ( const connectedSite of connectedSites ) { | ||
| try { | ||
| // Find the local site |
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.
Let's remove these comments when they are unnecessary.
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.
Sure, I have removed and re-worded some of them here 5b5f0a1 but please suggest if other comments feel also unnecessary, happy to remove them 😄
fredrikekelund
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.
This is a great addition 👍 I haven't finished my review, but since I see you're actively working on this PR, @epeicher, I'll submit some of the feedback I have so far.
| hasInitialized.current = true; | ||
|
|
||
| const initializePushStates = async () => { | ||
| try { |
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 try-catch basically only catches exceptions from getIpcApi().getSiteDetails(), right? I'm not sure that's really necessary, but if we keep it, then maybe we can wrap just that row instead of the entire function body to reduce indentation.
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 could also catch potential exceptions thrown by this request, for example, being offline, so I think it's good that it covers both
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's already an inner try-catch statement to capture exceptions from that API call, though. That's why I figured we could make this statement wrap fewer lines.
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.
Ah, you're right, I mixed it with the inner one.
I could reduce the indentation by narrowing the scope, but it would require extracting the allSites variable outside of the try-catch and checking if it's null before continuing after the try-catch, which could be less readable. Alternatively, I could remove this try-catch as it could be unnecessary, what option do you prefer?
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.
How about removing this clause and wrapping the initializePushStates call in a try..catch instead?
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.
You could add a .catch handler to the initializePushStates call and remove the void operator.
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.
Yes, of course, I have tested that and it works. Do you think that is more readable than the try-catch in the initializePushStates? I honestly think we would be mixing promise handling (the .catch) with async-await, but if you have a strong opinion about it, I am happy to change that
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.
Principally, I don't think it's wrong to mix "classic" promise handling with async/await. The root problem here is essentially that useEffect can't handle async callbacks, but we still want some way to run async code inside that function. To that end, it's more about finding the least clunky solution.
However, this specific issue is really mostly cosmetic and not worth getting hung up on, IMO. Feel free to make a call and proceed as you see fit, @epeicher 👍
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.
The root problem here is essentially that useEffect can't handle async callbacks, but we still want some way to run async code inside that function.
💯 I agree, that's the root issue
it's more about finding the least clunky solution.
I didn't find clunky to have the outer try-catch, but you and two different agents think the .catch is less clunky so e5fb0f8 😄
fredrikekelund
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.
I wish we had untangled some of the push/pull React context and moved it to Redux slices, but that's beyond the scope of this PR.
Again, great addition 👍 Functionality-wise, this works as described. The code looks good overall, but I'd prefer we address the comments from my previous review (especially this). Approving now to unblock you later, @epeicher.
fredrikekelund
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.
Some final minor comments
| hasInitialized.current = true; | ||
|
|
||
| const initializePushStates = async () => { | ||
| try { |
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.
How about removing this clause and wrapping the initializePushStates call in a try..catch instead?
sejas
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.
Works as expected. I confirm all ongoing pushes are resumed after restarting Studio.
Thanks for fixing the issue I caught by mistake, and renaming the localSite variable.
…ush-progress-on-start
|
@epeicher This is a great improvement to sync UX 🥳 |

Related issues
Proposed Changes
useEffecttosync-sites-context.tsxthat only runs once to check if there is any connected site with a push operation in progresspushStatesof the sites if there is any status in progressCleanShot.2025-10-28.at.19.15.08.mp4
Testing Instructions
npm startSynctab and connect a site or use any existing connected siteBacking up remote site…Cmd+Qto quit StudioPre-merge Checklist