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

fix(pre-req): several fixes to the current hidden window launching process - INS-3319 #7174

Merged
merged 8 commits into from Mar 22, 2024

Conversation

ihexxa
Copy link
Contributor

@ihexxa ihexxa commented Mar 13, 2024

Please review this PR (#7173) firstly as current one is based on it

Changes:

  • fix: the hidden window is not started in some launching paths (when app is packaged), so that sending request is always timeout as the hidden window is never up.
  • fix: restart the hidden window if it is down (just for defense)
  • test: updated one smoke test to test it
  • fix: restart the hidden window if it is stuck

How to test

Try to close the hidden window or make it crash and send a request.

@ihexxa ihexxa changed the title chore: restart hidden window if it is down fix: restart hidden window if it is down Mar 13, 2024
@ihexxa ihexxa self-assigned this Mar 13, 2024
@jackkav
Copy link
Contributor

jackkav commented Mar 15, 2024

Please clean up commits in this PR and address both detection and recovery.

@ihexxa ihexxa changed the title fix: restart hidden window if it is down fix: restart hidden window if it is down - INS-3319 Mar 15, 2024
@ihexxa ihexxa changed the title fix: restart hidden window if it is down - INS-3319 fix(pre-req): restart hidden window if it is down - INS-3319 Mar 18, 2024
@ihexxa ihexxa changed the title fix(pre-req): restart hidden window if it is down - INS-3319 fix(pre-req): several fixes to the current hidden window launching process - INS-3319 Mar 18, 2024
Comment on lines +63 to +64
// as the hidden window is restarted, it should not show "Timeout: Hidden browser window is not responding"
await page.getByText('Timeout: Pre-request script took too long').click();
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔

@jackkav
Copy link
Contributor

jackkav commented Mar 18, 2024

If i'm not mistaken this PR doesn't yet detect a a unresponsive or closed window it just tries to open the same window on every run and the promise will hang if the hidden window isn't up. Either way its important to make it very clear here since it we can't afford for this mechanism to be buggy.

@ihexxa
Copy link
Contributor Author

ihexxa commented Mar 18, 2024

Thanks for heads up, I've just added the mechanism to restart the stuck hidden window.

@ihexxa
Copy link
Contributor Author

ihexxa commented Mar 18, 2024

I would say that it should still be an advance as in the current implementation the hidden window seems never up. :(
Let's test it.

@ihexxa
Copy link
Contributor Author

ihexxa commented Mar 19, 2024

I would like to share 2 videos to help understand how does current window restarting mechanism work:

In this one, the hidden window is not started at beginning, it is started when send is clicked, the hidden window is started, for twice.
This means that the mechanism can start the hidden window if it is down.
https://github.com/Kong/insomnia/assets/24986718/60d4cc8a-93cc-4467-9814-2d149a4299aa

In this one, one infinite loop script is enabled. In the first sending, it hangs. And cancel the first one, disable infinite loop and re-trigger send, it still works.
This means that it can reset the hidden window to normal if it hangs.
https://github.com/Kong/insomnia/assets/24986718/2befb295-fb0d-4752-87c0-68640b28c4de

@jackkav jackkav force-pushed the pre-req-win-cleanup-5 branch 2 times, most recently from 9596351 to 1c53738 Compare March 20, 2024 17:36
jackkav
jackkav previously approved these changes Mar 20, 2024
Copy link
Contributor

@jackkav jackkav left a comment

Choose a reason for hiding this comment

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

In order to help move this PR forward and add value faster. I took the liberty of removing the new code paths and focused this PR in to only fixing the start hidden window bug. Lets address the retry mechanism in its own PR since it is not a trivial UX or implementation. I have left the commits in detailing the approach to syncing a busy flag in main file scoped variable. So we can check the trade-offs against other detection and retry mechanisms.

stopHiddenBrowserWindow();
});
}
export async function createHiddenBrowserWindow() {
const hiddenBrowserWindow = new BrowserWindow({
Copy link
Contributor

Choose a reason for hiding this comment

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

since we check the browsers windows map outside of this function we no longer need to detect it being open and restart it. Since we should aim to trust the state of this map otherwise there is no benefit to keeping a record of its state in the map.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me try to clarify it. The state of window and the state of execution are 2 different states.

The windows map: means the hidden window is up or down.
The busy state: means if the hidden window is busy.
So, the hidden window is up != the hidden window is busy.

If the busy state is unknown, the mechanism must restart the window every time (to avoid it hangs), which seems not a good option for performance.
I can give more detailed elaboration of these 2 states if you would like to.

Comment on lines +723 to +784
const mainWindow = browserWindows.get('Insomnia') ?? createWindow();
if (!browserWindows.get('HiddenBrowserWindow')) {
createHiddenBrowserWindow();
Copy link
Contributor

Choose a reason for hiding this comment

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

it helps to keep createWindow and createHiddenWindow signatures and behaviour aligned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool

@ihexxa
Copy link
Contributor Author

ihexxa commented Mar 21, 2024

Really thankful for the review, probably some points should be clarified to make sure that we are on the same page:

  • This PR basically a hotfix PR which fixes some showstopper bugs in the existing sandbox launching mechanism, so I would propose to have another PR when we've figured out a better solution (after comparison). Iteration normally is the better practice than making it perfect at first. :)
  • As discussed, the restarting action should be transparent to users, pls let me know if we need any more improvement on the ux.

Some tests are also failed after force-pushing, so changes are stored. Lets follow the review process in most of repos by adding comments instead of modifying them.

@@ -57,5 +60,6 @@ test('handle hidden browser window getting closed', async ({ app, page }) => {
const hiddenWindow = windows[1];
hiddenWindow.close();
await page.getByRole('button', { name: 'Send' }).click();
await page.getByText('Timeout: Hidden browser window is not responding').click();
// as the hidden window is restarted, it should not show "Timeout: Hidden browser window is not responding"
await page.getByText('Timeout: Pre-request script took too long').click();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
await page.getByText('Timeout: Pre-request script took too long').click();
await page.getByText('Timeout: An error occurred while running a pre-request script please restart Insomnia').click();

Comment on lines 117 to 144
ipcMain.removeHandler('renderer-listener-ready');
const hiddenWinListenerReady = new Promise<void>(resolve => {
ipcMain.handleOnce('renderer-listener-ready', () => {
console.log('[main] hidden window listener is ready');
resolve();
});
});
await hiddenWinListenerReady;

ipcMain.removeHandler('hidden-window-received-port');
const hiddenWinPortReady = new Promise<void>(resolve => {
ipcMain.handleOnce('hidden-window-received-port', () => {
console.log('[main] hidden window has received port');
resolve();
});
});

const { port1, port2 } = new MessageChannelMain();
hiddenBrowserWindow.webContents.postMessage('renderer-listener', null, [port1]);
await hiddenWinPortReady;

ipcMain.removeHandler('main-window-script-port-ready');
const mainWinPortReady = new Promise<void>(resolve => {
ipcMain.handleOnce('main-window-script-port-ready', () => {
console.log('[main] main window has received hidden window port');
resolve();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see value in this. Can you explain why its required in this bug fix PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

Value add: this is a defensive way to show a console log allowing a specific sync error to be deduced from app logs.

packages/insomnia/src/main/window-utils.ts Outdated Show resolved Hide resolved
@ihexxa ihexxa enabled auto-merge (squash) March 22, 2024 03:00
@ihexxa ihexxa merged commit 915513c into develop Mar 22, 2024
7 checks passed
@ihexxa ihexxa deleted the pre-req-win-cleanup-5 branch March 22, 2024 03:10
Copy link

sentry-io bot commented Mar 22, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ Error: Attempted to register a second handler for 'open-channel-to-hidden-browser-window' createWindow(src/main/window-utils) View Issue
  • ‼️ Error: Attempted to register a second handler for 'open-channel-to-hidden-browser-window' createWindow(src/main/window-utils) View Issue

Did you find this useful? React with a 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants