fix: forefront stable
このコミットが含まれているのは:
コミット
b7194fbe28
2
index.ts
2
index.ts
|
@ -65,7 +65,7 @@ router.get('/ask/stream', async (ctx) => {
|
||||||
app.use(router.routes());
|
app.use(router.routes());
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await freeBrowserPool.init(1, process.env.DEBUG === '1');
|
await freeBrowserPool.init(5, process.env.DEBUG === '1');
|
||||||
const server = app.listen(3000, () => {
|
const server = app.listen(3000, () => {
|
||||||
console.log("Now listening: 127.0.0.1:3000");
|
console.log("Now listening: 127.0.0.1:3000");
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,7 @@ export class Forefrontnew extends Chat {
|
||||||
private page: Page | undefined = undefined;
|
private page: Page | undefined = undefined;
|
||||||
private url: string = 'https://chat.forefront.ai/';
|
private url: string = 'https://chat.forefront.ai/';
|
||||||
private writing: NodeJS.Timer | undefined = undefined;
|
private writing: NodeJS.Timer | undefined = undefined;
|
||||||
|
private msgSize: number = 0;
|
||||||
|
|
||||||
constructor(options?: ChatOptions) {
|
constructor(options?: ChatOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
|
@ -37,6 +38,13 @@ export class Forefrontnew extends Chat {
|
||||||
pt.end();
|
pt.end();
|
||||||
return {text: pt}
|
return {text: pt}
|
||||||
}
|
}
|
||||||
|
if (this.msgSize === 2) {
|
||||||
|
await freeBrowserPool.remove(this.browser?.id||"");
|
||||||
|
this.browser = undefined;
|
||||||
|
this.page = undefined;
|
||||||
|
this.msgSize = 0;
|
||||||
|
}
|
||||||
|
this.msgSize++;
|
||||||
if (!this.browser) {
|
if (!this.browser) {
|
||||||
this.browser = freeBrowserPool.getRandom();
|
this.browser = freeBrowserPool.getRandom();
|
||||||
}
|
}
|
||||||
|
@ -105,8 +113,7 @@ export class Forefrontnew extends Chat {
|
||||||
const mdList = await this.page.$('#__next > .flex > .relative > .relative > .w-full:nth-child(1) > div');
|
const mdList = await this.page.$('#__next > .flex > .relative > .relative > .w-full:nth-child(1) > div');
|
||||||
const md = mdList;
|
const md = mdList;
|
||||||
// get latest markdown id
|
// get latest markdown id
|
||||||
let id: number = (await md?.evaluate(el => el.children.length)) || 0
|
let id: number = this.msgSize * 4;
|
||||||
id = id * 4;
|
|
||||||
const selector = `div > .w-full:nth-child(${id}) > .flex > .flex > .post-markdown`;
|
const selector = `div > .w-full:nth-child(${id}) > .flex > .flex > .post-markdown`;
|
||||||
await this.page.waitForSelector(selector);
|
await this.page.waitForSelector(selector);
|
||||||
const result = await this.page.$(selector)
|
const result = await this.page.$(selector)
|
||||||
|
|
|
@ -2,6 +2,8 @@ import puppeteer, {Browser, Page, PuppeteerLaunchOptions} from "puppeteer";
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import run from "node:test";
|
import run from "node:test";
|
||||||
|
import {randomUUID} from "crypto";
|
||||||
|
import {v4} from "uuid";
|
||||||
|
|
||||||
const runPath = path.join(__dirname, 'run');
|
const runPath = path.join(__dirname, 'run');
|
||||||
|
|
||||||
|
@ -10,7 +12,7 @@ export class FreeBrowser {
|
||||||
private readonly options: PuppeteerLaunchOptions | undefined;
|
private readonly options: PuppeteerLaunchOptions | undefined;
|
||||||
private urls: Set<string> = new Set<string>();
|
private urls: Set<string> = new Set<string>();
|
||||||
private pages: Record<string, Page> = {};
|
private pages: Record<string, Page> = {};
|
||||||
private readonly id: string;
|
public readonly id: string;
|
||||||
|
|
||||||
constructor(id: string, options?: PuppeteerLaunchOptions) {
|
constructor(id: string, options?: PuppeteerLaunchOptions) {
|
||||||
this.options = {
|
this.options = {
|
||||||
|
@ -38,37 +40,62 @@ export class FreeBrowser {
|
||||||
this.pages[url] = page;
|
this.pages[url] = page;
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async close() {
|
||||||
|
this.browser?.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class FreeBrowserPool {
|
class FreeBrowserPool {
|
||||||
private size: number = 0;
|
private size: number = 0;
|
||||||
private readonly pool: FreeBrowser[];
|
private readonly pool: FreeBrowser[];
|
||||||
|
private debug: boolean = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pool = [];
|
this.pool = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async init(size: number, debug: boolean) {
|
public async init(size: number,debug:boolean) {
|
||||||
|
this.debug = debug;
|
||||||
console.log(`browser pool init size:${size}`)
|
console.log(`browser pool init size:${size}`)
|
||||||
if (!fs.existsSync(runPath)) {
|
if (!fs.existsSync(runPath)) {
|
||||||
fs.mkdirSync(runPath);
|
fs.mkdirSync(runPath);
|
||||||
}
|
}
|
||||||
this.size = size;
|
this.size = size;
|
||||||
const options: PuppeteerLaunchOptions = {
|
|
||||||
headless: !debug,
|
|
||||||
args: ['--no-sandbox']
|
|
||||||
};
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
const browser = new FreeBrowser(`${i}`, options);
|
this.pool.push(await this.newBrowser());
|
||||||
await browser.init();
|
|
||||||
this.pool.push(browser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRandom(): FreeBrowser {
|
public getRandom(): FreeBrowser {
|
||||||
return this.pool[Math.floor(Math.random() * this.pool.length)]
|
return this.pool[Math.floor(Math.random() * this.pool.length)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async newBrowser(): Promise<FreeBrowser> {
|
||||||
|
const options: PuppeteerLaunchOptions = {
|
||||||
|
headless: !this.debug,
|
||||||
|
args: ['--no-sandbox']
|
||||||
|
};
|
||||||
|
const browser = new FreeBrowser(v4(), options);
|
||||||
|
await browser.init();
|
||||||
|
return browser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async remove(id: string) {
|
||||||
|
let removed = false;
|
||||||
|
this.pool.filter(item => {
|
||||||
|
if (item.id === id) {
|
||||||
|
item.close();
|
||||||
|
removed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
if (removed) {
|
||||||
|
this.pool.push(await this.newBrowser());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const freeBrowserPool = new FreeBrowserPool();
|
export const freeBrowserPool = new FreeBrowserPool();
|
||||||
|
|
読み込み中…
新しいイシューから参照