File size: 3,226 Bytes
e60e8d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// const puppeteer = require("puppeteer-core"); // Uncomment if using puppeteer-core
const { connect } = require("puppeteer-real-browser");

async function createBrowser(retry = 0) {
  try {
    // If a browser instance already exists, or if we're finished, return.
    // global.finished should be set to true when the application is shutting down.
    if (global.finished) return;

    // If global.browser is not null, it means we already have a connected browser.
    // This prevents launching multiple browsers if one is already active.
    if (global.browser) {
        console.log("Browser is already connected.");
        return;
    }

    console.log("Launching new browser instance...");

    /* If using puppeteer-core:
    const browser = await puppeteer.launch({
      headless: false,
      args: ["--no-sandbox", "--disable-gpu"],
    });
    */

    const { browser: _browser } = await connect({
      headless: false,
      turnstile: true,
      connectOption: { defaultViewport: null },
      disableXvfb: false,
    });

    // Store the new browser instance globally
    global.browser = _browser;

    // Set up a listener for when the browser disconnects
    browser.on("disconnected", async () => {
      if (global.finished) return; // If the app is shutting down, don't try to restart
      console.log("Browser disconnected. Attempting to restart browser...");
      global.browser = null; // Clear the disconnected instance
      // Recursively call createBrowser to launch a new instance
      await createBrowser();
    });

    console.log("Browser launched successfully and ready for use.");
  } catch (e) {
    console.error("Error launching browser:", e.stack);

    // Only retry if the application is not finished and retry attempts are within limit
    if (global.finished || retry >= 5) {
      console.error("Max retries reached or application is shutting down. Could not launch browser.");
      global.browser = null; // Ensure the instance is null if launch failed
      return;
    }

    console.log(`Retrying browser launch (${retry + 1}/5)...`);
    await new Promise((resolve) => setTimeout(resolve, 3000));
    await createBrowser(retry + 1);
  }
}

// Immediately call createBrowser when this module is required to ensure a browser is available from start
createBrowser();

// Optionally, export the createBrowser function if you need to manually trigger it from elsewhere
module.exports = createBrowser;

// Add a graceful shutdown handler
process.on('SIGINT', async () => {
    console.log('SIGINT signal received. Shutting down...');
    global.finished = true; // Signal that the application is shutting down

    if (global.browser) {
        console.log('Closing browser...');
        await global.browser.close().catch(e => console.error("Error closing browser:", e));
    }
    process.exit(0);
});

process.on('SIGTERM', async () => {
    console.log('SIGTERM signal received. Shutting down...');
    global.finished = true; // Signal that the application is shutting down

    if (global.browser) {
        console.log('Closing browser...');
        await global.browser.close().catch(e => console.error("Error closing browser:", e));
    }
    process.exit(0);
});