@remotion/serverless 4.0.425 → 4.0.427

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.
@@ -343,7 +343,7 @@ const innerLaunchHandler = async ({ params, options, overallProgress, registerCl
343
343
  willRetry: false,
344
344
  totalAttempts: 1,
345
345
  });
346
- overallProgress.upload();
346
+ overallProgress.upload('artifactWriteError');
347
347
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, 'Failed to write artifact to S3', err);
348
348
  });
349
349
  return { alreadyExisted: false };
@@ -488,7 +488,7 @@ const launchHandler = async ({ params, options, providerSpecifics, insideFunctio
488
488
  willRetry: false,
489
489
  totalAttempts: 1,
490
490
  });
491
- overallProgress.upload();
491
+ overallProgress.upload('timeoutWebhookError');
492
492
  }
493
493
  };
494
494
  let webhookInvoked = false;
@@ -565,7 +565,7 @@ const launchHandler = async ({ params, options, providerSpecifics, insideFunctio
565
565
  willRetry: false,
566
566
  totalAttempts: 1,
567
567
  });
568
- overallProgress.upload();
568
+ overallProgress.upload('successWebhookError');
569
569
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, 'Failed to invoke webhook:');
570
570
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, err);
571
571
  }
@@ -589,7 +589,7 @@ const launchHandler = async ({ params, options, providerSpecifics, insideFunctio
589
589
  willRetry: false,
590
590
  message: err.message,
591
591
  });
592
- await overallProgress.upload();
592
+ await overallProgress.upload('fatalError');
593
593
  runCleanupTasks();
594
594
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, 'Wrote error to S3');
595
595
  clearTimeout(webhookDueToTimeout);
@@ -633,7 +633,7 @@ const launchHandler = async ({ params, options, providerSpecifics, insideFunctio
633
633
  willRetry: false,
634
634
  totalAttempts: 1,
635
635
  });
636
- overallProgress.upload();
636
+ overallProgress.upload('errorWebhookError');
637
637
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, 'Failed to invoke webhook:');
638
638
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel: params.logLevel }, error);
639
639
  }
@@ -89,7 +89,7 @@ const mergeChunksAndFinishRender = async (options) => {
89
89
  timeToFinish: Date.now() - options.startTime,
90
90
  providerSpecifics: options.providerSpecifics,
91
91
  });
92
- options.overallProgress.setPostRenderData(postRenderData);
92
+ await options.overallProgress.setPostRenderData(postRenderData);
93
93
  fs_1.default.unlinkSync(outfile);
94
94
  await cleanupChunksProm;
95
95
  return postRenderData;
@@ -1,6 +1,6 @@
1
1
  import type { ChunkRetry, CloudProvider, FunctionErrorInfo, OverallRenderProgress, PostRenderData, ProviderSpecifics, ReceivedArtifact, RenderMetadata } from '@remotion/serverless-client';
2
2
  export type OverallProgressHelper<Provider extends CloudProvider> = {
3
- upload: () => Promise<void>;
3
+ upload: (reason: string) => Promise<void>;
4
4
  setFrames: ({ encoded, rendered, index }: {
5
5
  rendered: number;
6
6
  encoded: number;
@@ -11,7 +11,7 @@ export type OverallProgressHelper<Provider extends CloudProvider> = {
11
11
  setCombinedFrames: (framesEncoded: number) => void;
12
12
  setTimeToCombine: (timeToCombine: number) => void;
13
13
  addRetry: (retry: ChunkRetry) => void;
14
- setPostRenderData: (postRenderData: PostRenderData<Provider>) => void;
14
+ setPostRenderData: (postRenderData: PostRenderData<Provider>) => Promise<void>;
15
15
  setRenderMetadata: (renderMetadata: RenderMetadata<Provider>) => void;
16
16
  addErrorWithoutUpload: (errorInfo: FunctionErrorInfo) => void;
17
17
  setExpectedChunks: (expectedChunks: number) => void;
@@ -31,51 +31,57 @@ const makeOverallRenderProgress = ({ renderId, bucketName, expectedBucketOwner,
31
31
  let framesEncoded = [];
32
32
  let lambdasInvoked = [];
33
33
  const renderProgress = (0, exports.makeInitialOverallRenderProgress)(timeoutTimestamp);
34
- let currentUploadPromise = null;
35
- const getCurrentProgress = () => renderProgress;
36
- let latestUploadRequest = 0;
37
- const getLatestRequestId = () => latestUploadRequest;
34
+ let dirty = false;
35
+ let dirtyReasons = [];
36
+ let uploadLoopPromise = null;
38
37
  let encodeStartTime = null;
39
38
  let renderFramesStartTime = null;
40
- const upload = async () => {
41
- const uploadRequestId = ++latestUploadRequest;
42
- if (currentUploadPromise) {
43
- await currentUploadPromise;
39
+ const markDirty = (reason) => {
40
+ dirty = true;
41
+ dirtyReasons.push(reason);
42
+ };
43
+ const runUploadLoop = async () => {
44
+ while (dirty) {
45
+ dirty = false;
46
+ const reasons = dirtyReasons.join(', ');
47
+ dirtyReasons = [];
48
+ const toWrite = JSON.stringify(renderProgress);
49
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `Uploading progress - ${reasons} (${toWrite.length} bytes)`);
50
+ const start = Date.now();
51
+ try {
52
+ await providerSpecifics.writeFile({
53
+ body: toWrite,
54
+ bucketName,
55
+ customCredentials: null,
56
+ downloadBehavior: null,
57
+ expectedBucketOwner,
58
+ key: (0, serverless_client_1.overallProgressKey)(renderId),
59
+ privacy: 'private',
60
+ region,
61
+ forcePathStyle,
62
+ storageClass: null,
63
+ requestHandler: null,
64
+ });
65
+ renderer_1.RenderInternals.Log.verbose({ indent: false, logLevel }, `Uploaded progress in ${Date.now() - start}ms`);
66
+ // Space out the requests a bit
67
+ await new Promise((resolve) => {
68
+ setTimeout(resolve, Math.max(0, 250 - (Date.now() - start)));
69
+ });
70
+ }
71
+ catch (err) {
72
+ // If an error occurs in uploading the state that contains the errors,
73
+ // that is unfortunate. We just log it.
74
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, 'Error uploading progress', err);
75
+ }
44
76
  }
45
- // If request has been replaced by a new one
46
- if (getLatestRequestId() !== uploadRequestId) {
47
- return;
77
+ uploadLoopPromise = null;
78
+ };
79
+ const upload = async (reason) => {
80
+ markDirty(reason);
81
+ if (!uploadLoopPromise) {
82
+ uploadLoopPromise = runUploadLoop();
48
83
  }
49
- const toWrite = JSON.stringify(getCurrentProgress());
50
- const start = Date.now();
51
- currentUploadPromise = providerSpecifics
52
- .writeFile({
53
- body: toWrite,
54
- bucketName,
55
- customCredentials: null,
56
- downloadBehavior: null,
57
- expectedBucketOwner,
58
- key: (0, serverless_client_1.overallProgressKey)(renderId),
59
- privacy: 'private',
60
- region,
61
- forcePathStyle,
62
- storageClass: null,
63
- requestHandler: null,
64
- })
65
- .then(() => {
66
- // By default, upload is way too fast (~20 requests per second)
67
- // Space out the requests a bit
68
- return new Promise((resolve) => {
69
- setTimeout(resolve, Math.max(0, 250 - (Date.now() - start)));
70
- });
71
- })
72
- .catch((err) => {
73
- // If an error occurs in uploading the state that contains the errors,
74
- // that is unfortunate. We just log it.
75
- renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, 'Error uploading progress', err);
76
- });
77
- await currentUploadPromise;
78
- currentUploadPromise = null;
84
+ await uploadLoopPromise;
79
85
  };
80
86
  return {
81
87
  upload,
@@ -108,7 +114,7 @@ const makeOverallRenderProgress = ({ renderId, bucketName, expectedBucketOwner,
108
114
  }
109
115
  renderProgress.framesRendered = totalFramesRendered;
110
116
  renderProgress.framesEncoded = totalFramesEncoded;
111
- upload();
117
+ upload(`setFrames(rendered=${totalFramesRendered}, encoded=${totalFramesEncoded})`);
112
118
  },
113
119
  addChunkCompleted: (chunkIndex, start, rendered) => {
114
120
  var _a;
@@ -123,15 +129,15 @@ const makeOverallRenderProgress = ({ renderId, bucketName, expectedBucketOwner,
123
129
  start,
124
130
  rendered,
125
131
  });
126
- upload();
132
+ upload(`addChunkCompleted(chunk=${chunkIndex})`);
127
133
  },
128
134
  setCombinedFrames: (frames) => {
129
135
  renderProgress.combinedFrames = frames;
130
- upload();
136
+ upload(`setCombinedFrames(${frames})`);
131
137
  },
132
138
  setTimeToCombine: (timeToCombine) => {
133
139
  renderProgress.timeToCombine = timeToCombine;
134
- upload();
140
+ upload(`setTimeToCombine(${timeToCombine})`);
135
141
  },
136
142
  setLambdaInvoked(chunk) {
137
143
  if (lambdasInvoked.length === 0) {
@@ -139,15 +145,15 @@ const makeOverallRenderProgress = ({ renderId, bucketName, expectedBucketOwner,
139
145
  }
140
146
  lambdasInvoked[chunk] = true;
141
147
  renderProgress.lambdasInvoked = lambdasInvoked.reduce((a, b) => a + Number(b), 0);
142
- upload();
148
+ upload(`setLambdaInvoked(chunk=${chunk})`);
143
149
  },
144
- setPostRenderData(postRenderData) {
150
+ async setPostRenderData(postRenderData) {
145
151
  renderProgress.postRenderData = postRenderData;
146
- upload();
152
+ await upload('setPostRenderData');
147
153
  },
148
154
  setRenderMetadata: (renderMetadata) => {
149
155
  renderProgress.renderMetadata = renderMetadata;
150
- upload();
156
+ upload('setRenderMetadata');
151
157
  },
152
158
  addErrorWithoutUpload: (errorInfo) => {
153
159
  renderProgress.errors.push(errorInfo);
@@ -159,19 +165,19 @@ const makeOverallRenderProgress = ({ renderId, bucketName, expectedBucketOwner,
159
165
  },
160
166
  setCompositionValidated(timestamp) {
161
167
  renderProgress.compositionValidated = timestamp;
162
- upload();
168
+ upload('setCompositionValidated');
163
169
  },
164
170
  setServeUrlOpened(timestamp) {
165
171
  renderProgress.serveUrlOpened = timestamp;
166
- upload();
172
+ upload('setServeUrlOpened');
167
173
  },
168
174
  addRetry(retry) {
169
175
  renderProgress.retries.push(retry);
170
- upload();
176
+ upload('addRetry');
171
177
  },
172
178
  addReceivedArtifact(asset) {
173
179
  renderProgress.receivedArtifact.push(asset);
174
- upload();
180
+ upload('addReceivedArtifact');
175
181
  },
176
182
  getReceivedArtifacts() {
177
183
  return renderProgress.receivedArtifact;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless"
4
4
  },
5
5
  "name": "@remotion/serverless",
6
- "version": "4.0.425",
6
+ "version": "4.0.427",
7
7
  "description": "A runtime for distributed rendering",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -23,13 +23,13 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@remotion/renderer": "4.0.425",
27
- "@remotion/bundler": "4.0.425",
28
- "@remotion/licensing": "4.0.425",
29
- "@remotion/serverless-client": "4.0.425"
26
+ "@remotion/renderer": "4.0.427",
27
+ "@remotion/bundler": "4.0.427",
28
+ "@remotion/licensing": "4.0.427",
29
+ "@remotion/serverless-client": "4.0.427"
30
30
  },
31
31
  "devDependencies": {
32
- "@remotion/eslint-config-internal": "4.0.425",
32
+ "@remotion/eslint-config-internal": "4.0.427",
33
33
  "eslint": "9.19.0",
34
34
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
35
35
  },