@nexrender/worker 1.55.0 → 1.56.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexrender/worker",
3
- "version": "1.55.0",
3
+ "version": "1.56.1",
4
4
  "author": "inlife",
5
5
  "main": "src/index.js",
6
6
  "homepage": "https://www.nexrender.com",
@@ -29,5 +29,5 @@
29
29
  "publishConfig": {
30
30
  "access": "public"
31
31
  },
32
- "gitHead": "4fa2eb2322504330986ccd9973b339aa91905e8b"
32
+ "gitHead": "08af86cf1867fc7299add1a8c9afd3bccadeb623"
33
33
  }
package/readme.md CHANGED
@@ -96,4 +96,4 @@ Available settings (almost same as for `nexrender-core`):
96
96
  * `actions` - an object with keys corresponding to the `module` field when defining an action, value should be a function matching expected signature of an action. Used for defining actions programmatically without needing to package the action as a separate package
97
97
  * `cache` - boolean or string. Set the cache folder used by HTTP assets. If `true` will use the default path of `${workpath}/http-cache`, if set to a string it will be interpreted as a filesystem path to the cache folder.
98
98
  * `name` - string. An unique name (or not) to the `nexrender-worker`, and it will be identified in the `nexrender-server`. It can be used as an executor name on picked job(s) as well.
99
-
99
+ * `handleInterruption` - boolean, if set to true, enables handling of interruption signals (SIGINT, SIGTERM). When an interruption signal is received, the worker will attempt to update the current job's state to 'queued' before shutting down. (false by default)
package/src/bin.js CHANGED
@@ -49,6 +49,8 @@ const args = arg({
49
49
  '--aerender-parameter': [String],
50
50
  '--language': String,
51
51
 
52
+ '--handle-interruption': Boolean,
53
+
52
54
  // Aliases
53
55
  '-v': '--version',
54
56
  '-t': '--tag-selector',
@@ -193,6 +195,7 @@ if (args['--help']) {
193
195
 
194
196
  {bold $} NEXRENDER_API_POLLING=1000 {cyan nexrender-worker}
195
197
  `);
198
+
196
199
  process.exit(2);
197
200
  }
198
201
 
@@ -245,6 +248,7 @@ opt('wslMap', '--wsl-map');
245
248
  opt('aeParams', '--aerender-parameter');
246
249
  opt('tagSelector', '--tag-selector');
247
250
  opt('language', '--language');
251
+ opt('handleInterruption', '--handle-interruption');
248
252
 
249
253
  if(args['--cache-path']){
250
254
  opt('cache', '--cache-path');
package/src/instance.js CHANGED
@@ -13,13 +13,32 @@ const createWorker = () => {
13
13
  let active = false;
14
14
  let settingsRef = null;
15
15
  let stop_datetime = null;
16
+ let currentJob = null;
17
+ let client = null;
18
+
19
+ // New function to handle interruption
20
+ const handleInterruption = async () => {
21
+ if (currentJob) {
22
+ settingsRef.logger.log(`[${currentJob.uid}] Interruption signal received. Updating job state to 'queued'...`);
23
+ currentJob.onRenderProgress = null;
24
+ currentJob.state = 'queued';
25
+ try {
26
+ await client.updateJob(currentJob.uid, getRenderingStatus(currentJob));
27
+ settingsRef.logger.log(`[${currentJob.uid}] Job state updated to 'queued' successfully.`);
28
+ } catch (err) {
29
+ settingsRef.logger.error(`[${currentJob.uid}] Failed to update job state: ${err.message}`);
30
+ }
31
+ }
32
+ active = false;
33
+ process.exit(0);
34
+ };
16
35
 
17
36
  const nextJob = async (client, settings) => {
18
37
  do {
19
38
  try {
20
39
  if (stop_datetime !== null && new Date() > stop_datetime) {
21
40
  active = false;
22
- return
41
+ return null
23
42
  }
24
43
 
25
44
  let job = await (settings.tagSelector ?
@@ -63,6 +82,7 @@ const createWorker = () => {
63
82
  process: 'nexrender-worker',
64
83
  stopOnError: false,
65
84
  logger: console,
85
+ handleInterruption: false,
66
86
  }, settings))
67
87
 
68
88
  settingsRef = settings;
@@ -85,7 +105,7 @@ const createWorker = () => {
85
105
  headers = headers || {};
86
106
  headers['user-agent'] = ('nexrender-worker/' + pkg.version + ' ' + (headers['user-agent'] || '')).trim();
87
107
 
88
- const client = createClient({ host, secret, headers, name: settings.name });
108
+ client = createClient({ host, secret, headers, name: settings.name });
89
109
 
90
110
  settings.track('Worker Started', {
91
111
  worker_tags_set: !!settings.tagSelector,
@@ -114,39 +134,45 @@ const createWorker = () => {
114
134
  }
115
135
  }
116
136
 
117
- do {
137
+ // Set up interruption handlers if enabled
138
+ if (settings.handleInterruption) {
139
+ process.on('SIGINT', handleInterruption);
140
+ process.on('SIGTERM', handleInterruption);
141
+ settingsRef.logger.log('Interruption handling enabled.');
142
+ }
118
143
 
119
- let job = await nextJob(client, settings);
144
+ do {
145
+ currentJob = await nextJob(client, settings);
120
146
 
121
147
  // if the worker has been deactivated, exit this loop
122
148
  if (!active) break;
123
149
 
124
150
  settings.track('Worker Job Started', {
125
- job_id: job.uid, // anonymized internally
151
+ job_id: currentJob.uid, // anonymized internally
126
152
  })
127
153
 
128
- job.state = 'started';
129
- job.startedAt = new Date()
154
+ currentJob.state = 'started';
155
+ currentJob.startedAt = new Date()
130
156
 
131
157
  try {
132
- await client.updateJob(job.uid, job)
158
+ await client.updateJob(currentJob.uid, currentJob)
133
159
  } catch (err) {
134
- console.log(`[${job.uid}] error while updating job state to ${job.state}. Job abandoned.`)
135
- console.log(`[${job.uid}] error stack: ${err.stack}`)
160
+ console.log(`[${currentJob.uid}] error while updating job state to ${currentJob.state}. Job abandoned.`)
161
+ console.log(`[${currentJob.uid}] error stack: ${err.stack}`)
136
162
  continue;
137
163
  }
138
164
 
139
165
  try {
140
- job.onRenderProgress = (job) => {
166
+ currentJob.onRenderProgress = ((c, s) => (job) => {
141
167
  try {
142
168
  /* send render progress to our server */
143
- client.updateJob(job.uid, getRenderingStatus(job));
169
+ c.updateJob(job.uid, getRenderingStatus(job));
144
170
 
145
- if (settings.onRenderProgress) {
146
- settings.onRenderProgress(job);
171
+ if (s.onRenderProgress) {
172
+ s.onRenderProgress(job);
147
173
  }
148
174
  } catch (err) {
149
- if (settings.stopOnError) {
175
+ if (s.stopOnError) {
150
176
  throw err;
151
177
  } else {
152
178
  console.log(`[${job.uid}] error occurred: ${err.stack}`)
@@ -154,52 +180,52 @@ const createWorker = () => {
154
180
  console.log(`[${job.uid}] continue listening next job...`)
155
181
  }
156
182
  }
157
- }
183
+ })(client, settings);
158
184
 
159
- job.onRenderError = (job, err /* on render error */) => {
160
- job.error = [].concat(job.error || [], [err.toString()]);
185
+ currentJob.onRenderError = (currentJob, err /* on render error */) => {
186
+ currentJob.error = [].concat(currentJob.error || [], [err.toString()]);
161
187
 
162
188
  if (settings.onRenderError) {
163
- settings.onRenderError(job, err);
189
+ settings.onRenderError(currentJob, err);
164
190
  }
165
191
  }
166
192
 
167
- job = await render(job, settings); {
168
- job.state = 'finished';
169
- job.finishedAt = new Date();
193
+ currentJob = await render(currentJob, settings); {
194
+ currentJob.state = 'finished';
195
+ currentJob.finishedAt = new Date();
170
196
  if (settings.onFinished) {
171
- settings.onFinished(job);
197
+ settings.onFinished(currentJob);
172
198
  }
173
199
  }
174
200
 
175
- settings.track('Worker Job Finished', { job_id: job.uid })
201
+ settings.track('Worker Job Finished', { job_id: currentJob.uid })
176
202
 
177
- await client.updateJob(job.uid, getRenderingStatus(job))
203
+ await client.updateJob(currentJob.uid, getRenderingStatus(currentJob))
178
204
  } catch (err) {
179
- job.error = [].concat(job.error || [], [err.toString()]);
180
- job.errorAt = new Date();
181
- job.state = 'error';
205
+ currentJob.error = [].concat(currentJob.error || [], [err.toString()]);
206
+ currentJob.errorAt = new Date();
207
+ currentJob.state = 'error';
182
208
 
183
- settings.track('Worker Job Error', { job_id: job.uid });
209
+ settings.track('Worker Job Error', { job_id: currentJob.uid });
184
210
 
185
211
  if (settings.onError) {
186
- settings.onError(job, err);
212
+ settings.onError(currentJob, err);
187
213
  }
188
214
 
189
215
  try {
190
- await client.updateJob(job.uid, getRenderingStatus(job))
216
+ await client.updateJob(currentJob.uid, getRenderingStatus(currentJob))
191
217
  }
192
218
  catch (e) {
193
- console.log(`[${job.uid}] error while updating job state to ${job.state}. Job abandoned.`)
194
- console.log(`[${job.uid}] error stack: ${e.stack}`)
219
+ console.log(`[${currentJob.uid}] error while updating job state to ${currentJob.state}. Job abandoned.`)
220
+ console.log(`[${currentJob.uid}] error stack: ${e.stack}`)
195
221
  }
196
222
 
197
223
  if (settings.stopOnError) {
198
224
  throw err;
199
225
  } else {
200
- console.log(`[${job.uid}] error occurred: ${err.stack}`)
201
- console.log(`[${job.uid}] render proccess stopped with error...`)
202
- console.log(`[${job.uid}] continue listening next job...`)
226
+ console.log(`[${currentJob.uid}] error occurred: ${err.stack}`)
227
+ console.log(`[${currentJob.uid}] render proccess stopped with error...`)
228
+ console.log(`[${currentJob.uid}] continue listening next job...`)
203
229
  }
204
230
  }
205
231
 
@@ -207,6 +233,12 @@ const createWorker = () => {
207
233
  await delay(settings.waitBetweenJobs);
208
234
  }
209
235
  } while (active)
236
+
237
+ // Clean up interruption handlers
238
+ if (settings.handleInterruption) {
239
+ process.removeListener('SIGINT', handleInterruption);
240
+ process.removeListener('SIGTERM', handleInterruption);
241
+ }
210
242
  }
211
243
 
212
244
  /**