channel-worker 1.5.2 → 1.6.0
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/lib/api-client.js +1 -1
- package/lib/command-poller.js +37 -0
- package/lib/daemon.js +18 -0
- package/package.json +1 -1
package/lib/api-client.js
CHANGED
|
@@ -65,7 +65,7 @@ class ApiClient {
|
|
|
65
65
|
|
|
66
66
|
// Commands
|
|
67
67
|
async getNextCommand(workerId) {
|
|
68
|
-
const workerTypes = 'launch_profile,close_profile,save_file,set_thumbnail,set_tags,set_file_input,click_and_upload,type_text,verify_logins,update_extension,sync_youtube_stats';
|
|
68
|
+
const workerTypes = 'launch_profile,close_profile,save_file,set_thumbnail,set_tags,set_file_input,click_and_upload,type_text,verify_logins,update_extension,sync_youtube_stats,restart_worker';
|
|
69
69
|
return this.request('GET', `/workers/commands?worker_id=${workerId}&types=${encodeURIComponent(workerTypes)}`);
|
|
70
70
|
}
|
|
71
71
|
|
package/lib/command-poller.js
CHANGED
|
@@ -72,6 +72,9 @@ class CommandPoller {
|
|
|
72
72
|
case 'sync_youtube_stats':
|
|
73
73
|
await this.handleSyncYoutubeStats(command);
|
|
74
74
|
break;
|
|
75
|
+
case 'restart_worker':
|
|
76
|
+
await this.handleRestartWorker(command);
|
|
77
|
+
break;
|
|
75
78
|
default:
|
|
76
79
|
// Other commands (scan_facebook_pages, etc.) handled by extension
|
|
77
80
|
console.log(`[commands] Skipping ${command.type} — handled by extension`);
|
|
@@ -861,6 +864,40 @@ class CommandPoller {
|
|
|
861
864
|
await this.api.updateCommand(command._id, { status: 'done' });
|
|
862
865
|
}
|
|
863
866
|
|
|
867
|
+
async handleRestartWorker(command) {
|
|
868
|
+
console.log('[commands] Restart worker requested — spawning new process and exiting...');
|
|
869
|
+
try {
|
|
870
|
+
await this.api.updateCommand(command._id, {
|
|
871
|
+
status: 'done',
|
|
872
|
+
result: { message: 'Worker restarting', restarted_at: new Date().toISOString() },
|
|
873
|
+
});
|
|
874
|
+
} catch {}
|
|
875
|
+
|
|
876
|
+
// Spawn a new daemon process, then exit current one
|
|
877
|
+
const { spawn } = require('child_process');
|
|
878
|
+
const path = require('path');
|
|
879
|
+
const fs = require('fs');
|
|
880
|
+
const os = require('os');
|
|
881
|
+
const cliPath = path.resolve(__dirname, '../bin/cli.js');
|
|
882
|
+
const configDir = path.join(os.homedir(), '.channel-worker');
|
|
883
|
+
const logFile = path.join(configDir, 'daemon.log');
|
|
884
|
+
const logFd = fs.openSync(logFile, 'a');
|
|
885
|
+
|
|
886
|
+
const child = spawn(process.execPath, [cliPath, 'start', '--_daemon'], {
|
|
887
|
+
detached: true,
|
|
888
|
+
stdio: ['ignore', logFd, logFd],
|
|
889
|
+
cwd: os.homedir(),
|
|
890
|
+
});
|
|
891
|
+
child.unref();
|
|
892
|
+
|
|
893
|
+
// Update PID file
|
|
894
|
+
const pidFile = path.join(configDir, 'daemon.pid');
|
|
895
|
+
fs.writeFileSync(pidFile, String(child.pid));
|
|
896
|
+
console.log(`[commands] New daemon spawned (PID: ${child.pid}), exiting current process...`);
|
|
897
|
+
|
|
898
|
+
process.exit(0);
|
|
899
|
+
}
|
|
900
|
+
|
|
864
901
|
async handleSyncYoutubeStats(command) {
|
|
865
902
|
const { channel_id } = command.payload || {};
|
|
866
903
|
console.log(`[commands] Syncing YouTube stats for channel: ${channel_id}`);
|
package/lib/daemon.js
CHANGED
|
@@ -13,6 +13,7 @@ class Daemon {
|
|
|
13
13
|
this.poller = new JobPoller(this.api, config);
|
|
14
14
|
this.commandPoller = new CommandPoller(this.api, config);
|
|
15
15
|
this.updateChecker = new UpdateChecker(5 * 60 * 1000); // check every 5min
|
|
16
|
+
this.extCheckTimer = null;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
async start() {
|
|
@@ -71,6 +72,22 @@ class Daemon {
|
|
|
71
72
|
// Start auto-update checker
|
|
72
73
|
this.updateChecker.start();
|
|
73
74
|
console.log('[daemon] Auto-update checker started (every 5min)');
|
|
75
|
+
|
|
76
|
+
// Start extension auto-update checker (every 5min)
|
|
77
|
+
if (this.config.extension_path) {
|
|
78
|
+
this.extCheckTimer = setInterval(async () => {
|
|
79
|
+
try {
|
|
80
|
+
const result = await checkAndUpdateExtension(this.api, this.config.extension_path);
|
|
81
|
+
if (result.updated) {
|
|
82
|
+
console.log(`[daemon] Extension auto-updated: ${result.from || 'none'} → ${result.to}`);
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
// silent — don't spam logs on failure
|
|
86
|
+
}
|
|
87
|
+
}, 5 * 60 * 1000);
|
|
88
|
+
console.log('[daemon] Extension auto-update checker started (every 5min)');
|
|
89
|
+
}
|
|
90
|
+
|
|
74
91
|
console.log('[daemon] Waiting for jobs & commands...\n');
|
|
75
92
|
|
|
76
93
|
// Graceful shutdown
|
|
@@ -80,6 +97,7 @@ class Daemon {
|
|
|
80
97
|
this.poller.stop();
|
|
81
98
|
this.commandPoller.stop();
|
|
82
99
|
this.updateChecker.stop();
|
|
100
|
+
if (this.extCheckTimer) clearInterval(this.extCheckTimer);
|
|
83
101
|
|
|
84
102
|
// Mark offline
|
|
85
103
|
try {
|