@staticn0va/wigolo 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/cli/doctor.d.ts +8 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +153 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/warmup.d.ts.map +1 -1
- package/dist/cli/warmup.js +30 -1
- package/dist/cli/warmup.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/search/engines/bing.d.ts +1 -0
- package/dist/search/engines/bing.d.ts.map +1 -1
- package/dist/search/engines/bing.js +27 -1
- package/dist/search/engines/bing.js.map +1 -1
- package/dist/searxng/bootstrap.d.ts +30 -0
- package/dist/searxng/bootstrap.d.ts.map +1 -1
- package/dist/searxng/bootstrap.js +150 -23
- package/dist/searxng/bootstrap.js.map +1 -1
- package/dist/searxng/process.d.ts +13 -1
- package/dist/searxng/process.d.ts.map +1 -1
- package/dist/searxng/process.js +52 -2
- package/dist/searxng/process.js.map +1 -1
- package/dist/server/backend-status.d.ts +11 -0
- package/dist/server/backend-status.d.ts.map +1 -0
- package/dist/server/backend-status.js +27 -0
- package/dist/server/backend-status.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -4
- package/dist/server.js.map +1 -1
- package/dist/tools/search.d.ts +2 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +16 -4
- package/dist/tools/search.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,84 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
|
1
|
+
import { execSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, rmSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { getConfig } from '../config.js';
|
|
5
5
|
import { createLogger } from '../logger.js';
|
|
6
|
+
import { isProcessAlive } from './process.js';
|
|
6
7
|
const log = createLogger('searxng');
|
|
8
|
+
export function backoffSchedule(attempt) {
|
|
9
|
+
const config = getConfig();
|
|
10
|
+
const max = config.bootstrapMaxAttempts;
|
|
11
|
+
const schedule = config.bootstrapBackoffSeconds;
|
|
12
|
+
if (attempt < 1 || attempt > max)
|
|
13
|
+
return null;
|
|
14
|
+
return schedule[attempt - 1] ?? null;
|
|
15
|
+
}
|
|
16
|
+
export class BootstrapError extends Error {
|
|
17
|
+
detail;
|
|
18
|
+
constructor(detail) {
|
|
19
|
+
super(`bootstrap step failed: ${detail.command} (exit ${detail.exitCode})`);
|
|
20
|
+
this.detail = detail;
|
|
21
|
+
this.name = 'BootstrapError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function runStep(command, args, opts) {
|
|
25
|
+
const result = spawnSync(command, args, { encoding: 'utf-8', timeout: opts.timeout });
|
|
26
|
+
if (result.status !== 0 || result.error) {
|
|
27
|
+
throw new BootstrapError({
|
|
28
|
+
stderr: result.stderr || String(result.error ?? ''),
|
|
29
|
+
exitCode: result.status,
|
|
30
|
+
command: `${command} ${args.join(' ')}`,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function acquireBootstrapLock(dataDir) {
|
|
35
|
+
const lockFile = join(dataDir, 'bootstrap.lock');
|
|
36
|
+
if (existsSync(lockFile)) {
|
|
37
|
+
let stale = false;
|
|
38
|
+
try {
|
|
39
|
+
const data = JSON.parse(readFileSync(lockFile, 'utf-8'));
|
|
40
|
+
if (data.pid && isProcessAlive(data.pid)) {
|
|
41
|
+
throw new Error(`SearXNG bootstrap already in progress (pid ${data.pid}). ` +
|
|
42
|
+
`Wait for it to finish, or force-recover: kill ${data.pid} && npx @staticn0va/wigolo warmup --force`);
|
|
43
|
+
}
|
|
44
|
+
stale = true;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof Error && err.message.startsWith('SearXNG bootstrap already in progress'))
|
|
48
|
+
throw err;
|
|
49
|
+
stale = true; // unparseable → treat as stale
|
|
50
|
+
}
|
|
51
|
+
if (stale) {
|
|
52
|
+
log.info('wiping stale bootstrap lock');
|
|
53
|
+
try {
|
|
54
|
+
unlinkSync(lockFile);
|
|
55
|
+
}
|
|
56
|
+
catch { }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
mkdirSync(dataDir, { recursive: true });
|
|
60
|
+
writeFileSync(lockFile, JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }));
|
|
61
|
+
return function release() {
|
|
62
|
+
try {
|
|
63
|
+
unlinkSync(lockFile);
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function waitForBootstrap(dataDir, opts) {
|
|
69
|
+
const deadline = Date.now() + opts.timeoutMs;
|
|
70
|
+
while (Date.now() < deadline) {
|
|
71
|
+
const state = getBootstrapState(dataDir);
|
|
72
|
+
if (state?.status === 'ready')
|
|
73
|
+
return 'ready';
|
|
74
|
+
if (state?.status === 'failed')
|
|
75
|
+
return 'failed';
|
|
76
|
+
if (state?.status === 'no_runtime')
|
|
77
|
+
return 'failed';
|
|
78
|
+
await new Promise(r => setTimeout(r, opts.intervalMs));
|
|
79
|
+
}
|
|
80
|
+
throw new Error(`waitForBootstrap timed out after ${opts.timeoutMs}ms`);
|
|
81
|
+
}
|
|
7
82
|
export function checkPythonAvailable() {
|
|
8
83
|
try {
|
|
9
84
|
execSync('python3 --version', { stdio: 'pipe' });
|
|
@@ -87,15 +162,29 @@ export async function resolveSearchBackend() {
|
|
|
87
162
|
return { type: 'native', searxngPath: state.searxngPath };
|
|
88
163
|
}
|
|
89
164
|
if (state?.status === 'downloading') {
|
|
90
|
-
log.warn('previous SearXNG download was interrupted
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
165
|
+
log.warn('previous SearXNG download was interrupted; bootstrapNativeSearxng will clean up under lock');
|
|
166
|
+
}
|
|
167
|
+
if (state?.status === 'failed') {
|
|
168
|
+
const attempts = state.attempts ?? 1;
|
|
169
|
+
const nextRetryAt = state.nextRetryAt ? new Date(state.nextRetryAt) : new Date(0);
|
|
170
|
+
const retryWindowOpen = new Date() >= nextRetryAt;
|
|
171
|
+
const budgetRemaining = attempts < config.bootstrapMaxAttempts;
|
|
172
|
+
if (retryWindowOpen && budgetRemaining && checkPythonAvailable()) {
|
|
173
|
+
log.info('SearXNG bootstrap retry window reached', { attempts, nextRetryAt: state.nextRetryAt });
|
|
174
|
+
return { type: 'native', searxngPath: join(dataDir, 'searxng') };
|
|
94
175
|
}
|
|
95
|
-
|
|
176
|
+
log.warn('SearXNG bootstrap stuck', {
|
|
177
|
+
attempts,
|
|
178
|
+
nextRetryAt: state.nextRetryAt,
|
|
179
|
+
error: state.lastError?.message ?? state.error,
|
|
180
|
+
});
|
|
181
|
+
if (checkDockerAvailable() && config.searxngMode !== 'native') {
|
|
182
|
+
return { type: 'docker' };
|
|
183
|
+
}
|
|
184
|
+
return { type: 'scraping' };
|
|
96
185
|
}
|
|
97
|
-
if (state?.status === '
|
|
98
|
-
log.warn('SearXNG
|
|
186
|
+
if (state?.status === 'no_runtime') {
|
|
187
|
+
log.warn('SearXNG runtime not found, using fallback', { error: state.error });
|
|
99
188
|
if (checkDockerAvailable() && config.searxngMode !== 'native') {
|
|
100
189
|
return { type: 'docker' };
|
|
101
190
|
}
|
|
@@ -112,26 +201,36 @@ export async function resolveSearchBackend() {
|
|
|
112
201
|
return { type: 'scraping' };
|
|
113
202
|
}
|
|
114
203
|
export async function bootstrapNativeSearxng(dataDir) {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
log.info('bootstrapping SearXNG', { path: searxngDir });
|
|
204
|
+
const release = acquireBootstrapLock(dataDir);
|
|
205
|
+
const priorAttempts = getBootstrapState(dataDir)?.attempts ?? 0;
|
|
118
206
|
try {
|
|
207
|
+
const searxngDir = join(dataDir, 'searxng');
|
|
208
|
+
if (existsSync(searxngDir)) {
|
|
209
|
+
log.info('removing previous SearXNG install before (re)bootstrap');
|
|
210
|
+
rmSync(searxngDir, { recursive: true, force: true });
|
|
211
|
+
}
|
|
212
|
+
setBootstrapState(dataDir, { status: 'downloading', attempts: priorAttempts });
|
|
213
|
+
log.info('bootstrapping SearXNG', { path: searxngDir });
|
|
119
214
|
mkdirSync(searxngDir, { recursive: true });
|
|
120
|
-
|
|
215
|
+
runStep('python3', ['-m', 'venv', join(searxngDir, 'venv')], { timeout: 60_000 });
|
|
121
216
|
const pip = join(searxngDir, 'venv', 'bin', 'pip');
|
|
122
|
-
|
|
123
|
-
// Download SearXNG tarball and install with deps (pip install from zip fails due to build-time imports)
|
|
217
|
+
runStep(pip, ['install', '--upgrade', 'pip', 'setuptools', 'wheel'], { timeout: 60_000 });
|
|
124
218
|
const repoDir = join(searxngDir, 'repo');
|
|
125
219
|
mkdirSync(repoDir, { recursive: true });
|
|
126
220
|
const tarPath = join(searxngDir, 'searxng.tar.gz');
|
|
127
221
|
log.info('downloading SearXNG source');
|
|
128
222
|
const response = await fetch('https://github.com/searxng/searxng/archive/refs/heads/master.tar.gz');
|
|
129
|
-
if (!response.ok)
|
|
130
|
-
throw new
|
|
223
|
+
if (!response.ok) {
|
|
224
|
+
throw new BootstrapError({
|
|
225
|
+
stderr: `SearXNG download failed: ${response.status} ${response.statusText}`,
|
|
226
|
+
exitCode: response.status,
|
|
227
|
+
command: 'fetch searxng.tar.gz',
|
|
228
|
+
});
|
|
229
|
+
}
|
|
131
230
|
writeFileSync(tarPath, Buffer.from(await response.arrayBuffer()));
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
231
|
+
runStep('tar', ['xzf', tarPath, '--strip-components=1', '-C', repoDir], { timeout: 60_000 });
|
|
232
|
+
runStep(pip, ['install', '-r', join(repoDir, 'requirements.txt')], { timeout: 300_000 });
|
|
233
|
+
runStep(pip, ['install', '--no-build-isolation', '--no-deps', repoDir], { timeout: 120_000 });
|
|
135
234
|
const config = getConfig();
|
|
136
235
|
const settings = generateSettings(config.searxngPort);
|
|
137
236
|
writeFileSync(join(searxngDir, 'settings.yml'), settings);
|
|
@@ -139,10 +238,38 @@ export async function bootstrapNativeSearxng(dataDir) {
|
|
|
139
238
|
log.info('SearXNG bootstrap complete');
|
|
140
239
|
}
|
|
141
240
|
catch (err) {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
241
|
+
const attempts = priorAttempts + 1;
|
|
242
|
+
const backoffSecs = backoffSchedule(attempts);
|
|
243
|
+
const nextRetryAt = backoffSecs === null
|
|
244
|
+
? undefined
|
|
245
|
+
: new Date(Date.now() + backoffSecs * 1000).toISOString();
|
|
246
|
+
const lastError = err instanceof BootstrapError
|
|
247
|
+
? {
|
|
248
|
+
message: err.message,
|
|
249
|
+
stderr: err.detail.stderr,
|
|
250
|
+
exitCode: err.detail.exitCode,
|
|
251
|
+
command: err.detail.command,
|
|
252
|
+
timestamp: new Date().toISOString(),
|
|
253
|
+
}
|
|
254
|
+
: {
|
|
255
|
+
message: err instanceof Error ? err.message : String(err),
|
|
256
|
+
stderr: '',
|
|
257
|
+
exitCode: null,
|
|
258
|
+
command: '',
|
|
259
|
+
timestamp: new Date().toISOString(),
|
|
260
|
+
};
|
|
261
|
+
setBootstrapState(dataDir, {
|
|
262
|
+
status: 'failed',
|
|
263
|
+
attempts,
|
|
264
|
+
lastAttemptAt: new Date().toISOString(),
|
|
265
|
+
nextRetryAt,
|
|
266
|
+
lastError,
|
|
267
|
+
});
|
|
268
|
+
log.error('SearXNG bootstrap failed', { attempts, nextRetryAt, error: lastError.message });
|
|
145
269
|
throw err;
|
|
146
270
|
}
|
|
271
|
+
finally {
|
|
272
|
+
release();
|
|
273
|
+
}
|
|
147
274
|
}
|
|
148
275
|
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/searxng/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/searxng/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,34 @@
|
|
|
1
|
+
export interface ProcessCallbacks {
|
|
2
|
+
onUnhealthy?: (reason: string) => void;
|
|
3
|
+
onHealthy?: () => void;
|
|
4
|
+
}
|
|
1
5
|
export declare function findAvailablePort(startPort: number): Promise<number>;
|
|
2
6
|
interface LockResult {
|
|
3
7
|
acquired: boolean;
|
|
4
8
|
existingPid?: number;
|
|
5
9
|
existingPort?: number;
|
|
6
10
|
}
|
|
11
|
+
export declare function isProcessAlive(pid: number): boolean;
|
|
7
12
|
export declare function acquireLock(dataDir: string): LockResult;
|
|
8
13
|
export declare function releaseLock(dataDir: string): void;
|
|
9
14
|
export declare class SearxngProcess {
|
|
10
15
|
private readonly searxngPath;
|
|
11
16
|
private readonly dataDir;
|
|
17
|
+
private readonly callbacks;
|
|
12
18
|
private child;
|
|
13
19
|
private port;
|
|
14
20
|
private crashTimes;
|
|
15
21
|
private stopped;
|
|
16
|
-
|
|
22
|
+
private isCurrentlyUnhealthy;
|
|
23
|
+
private healthProbeFailures;
|
|
24
|
+
private healthProbeTimer;
|
|
25
|
+
constructor(searxngPath: string, dataDir: string, callbacks?: ProcessCallbacks);
|
|
17
26
|
getUrl(): string | null;
|
|
18
27
|
start(): Promise<string | null>;
|
|
19
28
|
private monitorCrashes;
|
|
29
|
+
private startHealthProbe;
|
|
30
|
+
private probeOnce;
|
|
31
|
+
private notePotentialFailure;
|
|
20
32
|
stop(): Promise<void>;
|
|
21
33
|
}
|
|
22
34
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/searxng/process.ts"],"names":[],"mappings":"AAiBA,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBpE;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/searxng/process.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBpE;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAmBvD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASjD;AAcD,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAX5B,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,gBAAgB,CAA+B;gBAGpC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,gBAAqB;IAGnD,MAAM,IAAI,MAAM,GAAG,IAAI;IAIjB,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA8DrC,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,gBAAgB;YASV,SAAS;IAkBvB,OAAO,CAAC,oBAAoB;IAQtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAwB5B"}
|
package/dist/searxng/process.js
CHANGED
|
@@ -34,7 +34,7 @@ export function findAvailablePort(startPort) {
|
|
|
34
34
|
tryPort();
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
function isProcessAlive(pid) {
|
|
37
|
+
export function isProcessAlive(pid) {
|
|
38
38
|
try {
|
|
39
39
|
process.kill(pid, 0);
|
|
40
40
|
return true;
|
|
@@ -94,13 +94,18 @@ async function waitForHealth(url, timeoutMs) {
|
|
|
94
94
|
export class SearxngProcess {
|
|
95
95
|
searxngPath;
|
|
96
96
|
dataDir;
|
|
97
|
+
callbacks;
|
|
97
98
|
child = null;
|
|
98
99
|
port = null;
|
|
99
100
|
crashTimes = [];
|
|
100
101
|
stopped = false;
|
|
101
|
-
|
|
102
|
+
isCurrentlyUnhealthy = false;
|
|
103
|
+
healthProbeFailures = 0;
|
|
104
|
+
healthProbeTimer = null;
|
|
105
|
+
constructor(searxngPath, dataDir, callbacks = {}) {
|
|
102
106
|
this.searxngPath = searxngPath;
|
|
103
107
|
this.dataDir = dataDir;
|
|
108
|
+
this.callbacks = callbacks;
|
|
104
109
|
}
|
|
105
110
|
getUrl() {
|
|
106
111
|
return this.port ? `http://127.0.0.1:${this.port}` : null;
|
|
@@ -150,6 +155,7 @@ export class SearxngProcess {
|
|
|
150
155
|
return null;
|
|
151
156
|
}
|
|
152
157
|
this.monitorCrashes();
|
|
158
|
+
this.startHealthProbe();
|
|
153
159
|
log.info('SearXNG started', { port: this.port, url });
|
|
154
160
|
return url;
|
|
155
161
|
}
|
|
@@ -166,6 +172,10 @@ export class SearxngProcess {
|
|
|
166
172
|
if (this.crashTimes.length >= MAX_CRASH_RESTARTS) {
|
|
167
173
|
log.error('too many crashes, giving up on SearXNG', { crashes: this.crashTimes.length });
|
|
168
174
|
releaseLock(this.dataDir);
|
|
175
|
+
if (!this.isCurrentlyUnhealthy) {
|
|
176
|
+
this.isCurrentlyUnhealthy = true;
|
|
177
|
+
this.callbacks.onUnhealthy?.(`SearXNG process crashed ${this.crashTimes.length} times in ${CRASH_WINDOW_MS / 1000}s`);
|
|
178
|
+
}
|
|
169
179
|
return;
|
|
170
180
|
}
|
|
171
181
|
const backoff = Math.min(1000 * Math.pow(2, this.crashTimes.length - 1), 30000);
|
|
@@ -176,7 +186,47 @@ export class SearxngProcess {
|
|
|
176
186
|
}, backoff);
|
|
177
187
|
});
|
|
178
188
|
}
|
|
189
|
+
startHealthProbe() {
|
|
190
|
+
if (this.healthProbeTimer)
|
|
191
|
+
clearInterval(this.healthProbeTimer);
|
|
192
|
+
const config = getConfig();
|
|
193
|
+
const intervalMs = config.healthProbeIntervalMs;
|
|
194
|
+
this.healthProbeTimer = setInterval(() => {
|
|
195
|
+
void this.probeOnce();
|
|
196
|
+
}, intervalMs);
|
|
197
|
+
}
|
|
198
|
+
async probeOnce() {
|
|
199
|
+
if (this.stopped || !this.port)
|
|
200
|
+
return;
|
|
201
|
+
try {
|
|
202
|
+
const r = await fetch(`http://127.0.0.1:${this.port}/healthz`, { signal: AbortSignal.timeout(2000) });
|
|
203
|
+
if (r.ok) {
|
|
204
|
+
this.healthProbeFailures = 0;
|
|
205
|
+
if (this.isCurrentlyUnhealthy) {
|
|
206
|
+
this.isCurrentlyUnhealthy = false;
|
|
207
|
+
this.callbacks.onHealthy?.();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.notePotentialFailure();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
this.notePotentialFailure();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
notePotentialFailure() {
|
|
219
|
+
this.healthProbeFailures++;
|
|
220
|
+
if (this.healthProbeFailures === 3 && !this.isCurrentlyUnhealthy) {
|
|
221
|
+
this.isCurrentlyUnhealthy = true;
|
|
222
|
+
this.callbacks.onUnhealthy?.('SearXNG /healthz unreachable for 3 consecutive probes');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
179
225
|
async stop() {
|
|
226
|
+
if (this.healthProbeTimer) {
|
|
227
|
+
clearInterval(this.healthProbeTimer);
|
|
228
|
+
this.healthProbeTimer = null;
|
|
229
|
+
}
|
|
180
230
|
this.stopped = true;
|
|
181
231
|
if (this.child) {
|
|
182
232
|
this.child.kill('SIGTERM');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/searxng/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AAEpC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,eAAe,GAAG,KAAK,CAAC;AAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/searxng/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class BackendStatus {
|
|
2
|
+
private _active;
|
|
3
|
+
private _reason;
|
|
4
|
+
private _warned;
|
|
5
|
+
get isActive(): boolean;
|
|
6
|
+
markUnhealthy(reason: string): void;
|
|
7
|
+
markHealthy(): void;
|
|
8
|
+
/** Returns warning text once per fallback session, then undefined. */
|
|
9
|
+
consumeWarning(): string | undefined;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=backend-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-status.d.ts","sourceRoot":"","sources":["../../src/server/backend-status.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,OAAO,CAAS;IAExB,IAAI,QAAQ,IAAI,OAAO,CAAyB;IAEhD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMnC,WAAW,IAAI,IAAI;IAMnB,sEAAsE;IACtE,cAAc,IAAI,MAAM,GAAG,SAAS;CAUrC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class BackendStatus {
|
|
2
|
+
_active = false;
|
|
3
|
+
_reason;
|
|
4
|
+
_warned = false;
|
|
5
|
+
get isActive() { return this._active; }
|
|
6
|
+
markUnhealthy(reason) {
|
|
7
|
+
this._active = false;
|
|
8
|
+
this._reason = reason;
|
|
9
|
+
this._warned = false;
|
|
10
|
+
}
|
|
11
|
+
markHealthy() {
|
|
12
|
+
this._active = true;
|
|
13
|
+
this._reason = undefined;
|
|
14
|
+
this._warned = false;
|
|
15
|
+
}
|
|
16
|
+
/** Returns warning text once per fallback session, then undefined. */
|
|
17
|
+
consumeWarning() {
|
|
18
|
+
if (this._active || this._warned)
|
|
19
|
+
return undefined;
|
|
20
|
+
this._warned = true;
|
|
21
|
+
return (`SearXNG embedded search is unavailable; using direct engine scraping (lower quality). ` +
|
|
22
|
+
`Reason: ${this._reason ?? 'unknown'}. ` +
|
|
23
|
+
`To retry: \`npx @staticn0va/wigolo warmup --force\`. ` +
|
|
24
|
+
`For details: \`npx @staticn0va/wigolo doctor\`.`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=backend-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-status.js","sourceRoot":"","sources":["../../src/server/backend-status.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAa;IAChB,OAAO,GAAG,KAAK,CAAC;IAChB,OAAO,CAAqB;IAC5B,OAAO,GAAG,KAAK,CAAC;IAExB,IAAI,QAAQ,KAAc,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEhD,aAAa,CAAC,MAAc;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,WAAW;QACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,sEAAsE;IACtE,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,OAAO,CACL,wFAAwF;YACxF,WAAW,IAAI,CAAC,OAAO,IAAI,SAAS,IAAI;YACxC,uDAAuD;YACvD,iDAAiD,CAClD,CAAC;IACJ,CAAC;CACF"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAsMA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA8OjD"}
|
package/dist/server.js
CHANGED
|
@@ -20,6 +20,7 @@ import { StartpageEngine } from './search/engines/startpage.js';
|
|
|
20
20
|
import { resolveSearchBackend, bootstrapNativeSearxng, getBootstrapState } from './searxng/bootstrap.js';
|
|
21
21
|
import { SearxngProcess } from './searxng/process.js';
|
|
22
22
|
import { DockerSearxng } from './searxng/docker.js';
|
|
23
|
+
import { BackendStatus } from './server/backend-status.js';
|
|
23
24
|
import { getConfig } from './config.js';
|
|
24
25
|
import { createLogger } from './logger.js';
|
|
25
26
|
const log = createLogger('server');
|
|
@@ -192,6 +193,7 @@ export async function startServer() {
|
|
|
192
193
|
};
|
|
193
194
|
const browserPool = new BrowserPool();
|
|
194
195
|
const router = new SmartRouter(httpClient, browserPool);
|
|
196
|
+
const backendStatus = new BackendStatus();
|
|
195
197
|
// Direct scraping engines work without any bootstrap — always available so
|
|
196
198
|
// search() succeeds immediately even before SearXNG finishes setup.
|
|
197
199
|
const searchEngines = [
|
|
@@ -250,9 +252,14 @@ export async function startServer() {
|
|
|
250
252
|
}
|
|
251
253
|
if (name === 'search') {
|
|
252
254
|
const input = (args ?? {});
|
|
253
|
-
const result = await handleSearch(input, searchEngines, router);
|
|
255
|
+
const result = await handleSearch(input, searchEngines, router, backendStatus);
|
|
256
|
+
const blocks = [];
|
|
257
|
+
if (result.warning) {
|
|
258
|
+
blocks.push({ type: 'text', text: `[wigolo notice] ${result.warning}` });
|
|
259
|
+
}
|
|
260
|
+
blocks.push({ type: 'text', text: JSON.stringify(result, null, 2) });
|
|
254
261
|
return {
|
|
255
|
-
content:
|
|
262
|
+
content: blocks,
|
|
256
263
|
isError: !!result.error,
|
|
257
264
|
};
|
|
258
265
|
}
|
|
@@ -298,6 +305,7 @@ export async function startServer() {
|
|
|
298
305
|
const backend = await resolveSearchBackend();
|
|
299
306
|
if (backend.type === 'external' && backend.url) {
|
|
300
307
|
searchEngines.unshift(new SearxngClient(backend.url));
|
|
308
|
+
backendStatus.markHealthy();
|
|
301
309
|
log.info('using external SearXNG', { url: backend.url });
|
|
302
310
|
return;
|
|
303
311
|
}
|
|
@@ -308,21 +316,42 @@ export async function startServer() {
|
|
|
308
316
|
try {
|
|
309
317
|
await bootstrapNativeSearxng(config.dataDir);
|
|
310
318
|
}
|
|
311
|
-
catch {
|
|
319
|
+
catch (err) {
|
|
312
320
|
log.warn('SearXNG bootstrap failed, continuing with direct scraping fallback');
|
|
321
|
+
backendStatus.markUnhealthy(`bootstrap exception: ${String(err)}`);
|
|
313
322
|
return;
|
|
314
323
|
}
|
|
315
324
|
}
|
|
316
325
|
const postBootstrapState = getBootstrapState(config.dataDir);
|
|
317
326
|
if (postBootstrapState?.status === 'ready') {
|
|
318
|
-
searxngProcess = new SearxngProcess(backend.searxngPath, config.dataDir
|
|
327
|
+
searxngProcess = new SearxngProcess(backend.searxngPath, config.dataDir, {
|
|
328
|
+
onUnhealthy: (reason) => {
|
|
329
|
+
backendStatus.markUnhealthy(reason);
|
|
330
|
+
const idx = searchEngines.findIndex(e => e.name === 'searxng');
|
|
331
|
+
if (idx >= 0)
|
|
332
|
+
searchEngines.splice(idx, 1);
|
|
333
|
+
log.warn('SearXNG marked unhealthy', { reason });
|
|
334
|
+
},
|
|
335
|
+
onHealthy: () => {
|
|
336
|
+
const url = searxngProcess?.getUrl();
|
|
337
|
+
if (!url)
|
|
338
|
+
return;
|
|
339
|
+
backendStatus.markHealthy();
|
|
340
|
+
if (!searchEngines.some(e => e.name === 'searxng')) {
|
|
341
|
+
searchEngines.unshift(new SearxngClient(url));
|
|
342
|
+
}
|
|
343
|
+
log.info('SearXNG recovered');
|
|
344
|
+
},
|
|
345
|
+
});
|
|
319
346
|
const url = await searxngProcess.start();
|
|
320
347
|
if (url) {
|
|
321
348
|
searchEngines.unshift(new SearxngClient(url));
|
|
349
|
+
backendStatus.markHealthy();
|
|
322
350
|
log.info('SearXNG ready and added to search engines', { url });
|
|
323
351
|
}
|
|
324
352
|
else {
|
|
325
353
|
log.warn('SearXNG failed to start, using direct scraping fallback');
|
|
354
|
+
backendStatus.markUnhealthy('SearXNG process failed to start');
|
|
326
355
|
}
|
|
327
356
|
}
|
|
328
357
|
return;
|
|
@@ -332,15 +361,23 @@ export async function startServer() {
|
|
|
332
361
|
const url = await dockerSearxng.start();
|
|
333
362
|
if (url) {
|
|
334
363
|
searchEngines.unshift(new SearxngClient(url));
|
|
364
|
+
backendStatus.markHealthy();
|
|
335
365
|
log.info('Docker SearXNG ready', { url });
|
|
336
366
|
}
|
|
337
367
|
else {
|
|
338
368
|
log.warn('Docker SearXNG failed to start, using direct scraping fallback');
|
|
369
|
+
backendStatus.markUnhealthy('Docker SearXNG failed to start');
|
|
339
370
|
}
|
|
340
371
|
}
|
|
372
|
+
if (backend.type === 'scraping') {
|
|
373
|
+
const state = getBootstrapState(config.dataDir);
|
|
374
|
+
const reason = state?.lastError?.message ?? state?.error ?? 'no SearXNG backend available';
|
|
375
|
+
backendStatus.markUnhealthy(reason);
|
|
376
|
+
}
|
|
341
377
|
}
|
|
342
378
|
catch (err) {
|
|
343
379
|
log.warn('background backend setup failed', { error: String(err) });
|
|
380
|
+
backendStatus.markUnhealthy(`backend setup failed: ${String(err)}`);
|
|
344
381
|
}
|
|
345
382
|
})();
|
|
346
383
|
const shutdown = async () => {
|