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

[Real Browser] close the browser after getBrowser() #3791

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

Ali-Razmjoo
Copy link

@Ali-Razmjoo Ali-Razmjoo commented Sep 23, 2023

Tick the checkbox if you understand [x]:

  • I have read and understand the pull request rules.

Description

This fixes High CPU Usage after enabling the Web Driver (#3788).

This PR focuses on improving the cleanup process after each monitoring check in the server/monitor-types/real-browser-monitor-type.js file. The main changes include the introduction of a new cleanupBrowser function, which is responsible for terminating all browser processes and clearing the cache, and the replacement of the context.close() method with the new cleanupBrowser function in the RealBrowserMonitorType class.

Here are the key changes:

  • server/monitor-types/real-browser-monitor-type.js: Added a new cleanupBrowser function that terminates all browser processes and clears the cache after each monitoring check. This function loops through all contexts of the browser, clears cookies and permissions, and then closes the context.
  • server/monitor-types/real-browser-monitor-type.js: Replaced the context.close() method with the new cleanupBrowser function in the RealBrowserMonitorType class. This ensures that the cleanup process is executed after each monitoring check.

Type of change

Please delete any options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • My code follows the style guidelines of this project
  • I ran ESLint and other linters for modified files
  • I have performed a self-review of my own code and tested it
  • I have commented my code, particularly in hard-to-understand areas
    (including JSDoc for methods)
  • My changes generate no new warnings
  • My code needed automated testing. I have added them (this is optional task)

Screenshots (if any)

  • Not applicable

@chakflying
Copy link
Collaborator

This probably works, but it may be better for getBrowser to return an existing instance, and just open/close tabs instead. That way we save even more resources by not having to go to the kernel for a new process.

@louislam louislam added the question Further information is requested label Sep 23, 2023
@louislam
Copy link
Owner

louislam commented Sep 23, 2023

Haven't look into this issue yet, but by my design, one browser belongs to one monitor. If the browser closed in here, the next beat should throw an exception unexpectedly.

The getBrowser is actually returning the same instance.

@louislam louislam added this to the 1.23.3 milestone Sep 23, 2023
@Ali-Razmjoo
Copy link
Author

@louislam I have reviewed the code every time check function is called, inside that you get new browser by const browser = await getBrowser();. Inside of that code if the browser is closed it opens a new one; but not sure if opening and closing are efficient, but better than high CPU usage...

async function getBrowser() {
    if (!browser) {
        let executablePath = await Settings.get("chromeExecutable");

        executablePath = await prepareChromeExecutable(executablePath);

        browser = await chromium.launch({
            //headless: false,
            executablePath,
        });
    }
    return browser;
}

@louislam
Copy link
Owner

louislam commented Oct 7, 2023

Just tested. As I expected before. The monitor is crashed in the second tick. Browser cannot be closed in the middle of the tick.

Still not clear what causes #3788. I guess it is Linux only bug, as I cannot reproduce #3788 on Windows.

image

@louislam louislam modified the milestones: 1.23.3, Pending Oct 7, 2023
@chakflying chakflying added the area:monitor Everything related to monitors label Dec 2, 2023
@CommanderStorm CommanderStorm changed the title close the browser after getBrowser() [Real Browser] close the browser after getBrowser() Jan 21, 2024
@CommanderStorm CommanderStorm added the pr:please address review comments this PR needs a bit more work to be mergable label May 19, 2024
@Ali-Razmjoo
Copy link
Author

@louislam I updated the code. Can you give me some thoughts/insights on what needs to be done to get rid of this issue?

@Ali-Razmjoo
Copy link
Author

Ali-Razmjoo commented Jun 10, 2024

forgot the screenshots...

I added a test, and let it run for a while to ensure it's working...
Screenshot 2024-06-10 at 22 49 07

then I started watching the processes
Screenshot 2024-06-10 at 22 51 07

seems to be working, but unsure if I missed anything.


update: Now I am wondering if it closes context from other monitors? in that case we can maybe close a singular context...

Comment on lines 236 to 246
async function cleanupBrowser() {
if (browser) {
const contexts = browser.contexts();
for (const context of contexts) {
await context.clearCookies();
await context.clearPermissions();
await context.close();
}
}
}

Copy link
Owner

@louislam louislam Jun 11, 2024

Choose a reason for hiding this comment

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

For the current design, Uptime Kuma creates one browser instance for multiple monitors.
So I am afraid that your new fix is still not working, as closing all contexts will probably affect other monitors.

As I said before, the current code is working fine on Windows.
Uncommenting headless: false, can see behind the screens.

However, I don't have a desktop environment right now on Linux, I can't debug it with headless: false on Linux

Copy link
Author

Choose a reason for hiding this comment

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

For the current design, Uptime Kuma creates one browser instance for multiple monitors.
So I am afraid that your new fix is still not working, as closing all contexts will probably affect other monitors.

that's what I suspected... I will send a fix now.

As I said before, the current code is working fine on Windows.
Uncommenting headless: false, can see behind the screens.

As I posted in
#3788 there are many chromium processes/tabs left opened after check() is called, and needs to be closed to prevent the DoS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:monitor Everything related to monitors pr:please address review comments this PR needs a bit more work to be mergable question Further information is requested
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Real Browser] High CPU/Memory Usage
4 participants