serverless-offline 9.1.0 → 9.1.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 +100 -33
- package/package.json +2 -2
- package/src/config/constants.js +1 -1
- package/src/lambda/LambdaFunction.js +1 -1
- package/src/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +10 -6
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +3 -1
- package/src/lambda/handler-runner/go-runner/GoRunner.js +13 -8
- package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +3 -2
- package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +2 -2
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<a href="https://www.npmjs.com/package/serverless-offline">
|
|
8
8
|
<img src="https://img.shields.io/npm/v/serverless-offline.svg?style=flat-square">
|
|
9
9
|
</a>
|
|
10
|
-
<a href="https://github.com/dherault/serverless-offline/actions
|
|
11
|
-
<img src="https://img.shields.io/github/workflow/status/dherault/serverless-offline/
|
|
10
|
+
<a href="https://github.com/dherault/serverless-offline/actions/workflows/integrate.yml">
|
|
11
|
+
<img src="https://img.shields.io/github/workflow/status/dherault/serverless-offline/Integrate">
|
|
12
12
|
</a>
|
|
13
13
|
<img src="https://img.shields.io/node/v/serverless-offline.svg?style=flat-square">
|
|
14
14
|
<a href="https://github.com/serverless/serverless">
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
This [Serverless](https://github.com/serverless/serverless) plugin emulates [AWS λ](https://aws.amazon.com/lambda) and [API Gateway](https://aws.amazon.com/api-gateway) on your local machine to speed up your development cycles.
|
|
30
30
|
To do so, it starts an HTTP server that handles the request's lifecycle like APIG does and invokes your handlers.
|
|
31
31
|
|
|
32
|
-
**Features
|
|
32
|
+
**Features**
|
|
33
33
|
|
|
34
|
-
- [Node.js](https://nodejs.org), [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org)
|
|
34
|
+
- [Node.js](https://nodejs.org), [Python](https://www.python.org), [Ruby](https://www.ruby-lang.org), [Go](https://golang.org), [Java](https://www.java.com) (incl. [Kotlin](https://kotlinlang.org), [Groovy](https://groovy-lang.org), [Scala](https://www.scala-lang.org)) λ runtimes.
|
|
35
35
|
- Velocity templates support.
|
|
36
36
|
- Lazy loading of your handler files.
|
|
37
37
|
- And more: integrations, authorizers, proxies, timeouts, responseParameters, HTTPS, CORS, etc...
|
|
@@ -42,6 +42,7 @@ This plugin is updated by its users, I just do maintenance and ensure that PRs a
|
|
|
42
42
|
|
|
43
43
|
- [Installation](#installation)
|
|
44
44
|
- [Usage and command line options](#usage-and-command-line-options)
|
|
45
|
+
- [Run modes](#run-modes)
|
|
45
46
|
- [Usage with `invoke`](#usage-with-invoke)
|
|
46
47
|
- [The `process.env.IS_OFFLINE` variable](#the-processenvis_offline-variable)
|
|
47
48
|
- [Docker and Layers](#docker-and-layers)
|
|
@@ -84,7 +85,7 @@ Then inside your project's `serverless.yml` file add following entry to the plug
|
|
|
84
85
|
|
|
85
86
|
It should look something like this:
|
|
86
87
|
|
|
87
|
-
```
|
|
88
|
+
```yml
|
|
88
89
|
plugins:
|
|
89
90
|
- serverless-offline
|
|
90
91
|
```
|
|
@@ -146,13 +147,13 @@ All CLI options are optional:
|
|
|
146
147
|
|
|
147
148
|
Any of the CLI options can be added to your `serverless.yml`. For example:
|
|
148
149
|
|
|
149
|
-
```
|
|
150
|
+
```yml
|
|
150
151
|
custom:
|
|
151
152
|
serverless-offline:
|
|
152
|
-
httpsProtocol:
|
|
153
|
+
httpsProtocol: 'dev-certs'
|
|
153
154
|
httpPort: 4000
|
|
154
155
|
stageVariables:
|
|
155
|
-
foo:
|
|
156
|
+
foo: 'bar'
|
|
156
157
|
```
|
|
157
158
|
|
|
158
159
|
Options passed on the command line override YAML options.
|
|
@@ -164,18 +165,64 @@ By default you can send your requests to `http://localhost:3000/`. Please note t
|
|
|
164
165
|
But if you send an `application/x-www-form-urlencoded` or a `multipart/form-data` body with an `application/json` (or no) Content-Type, API Gateway won't parse your data (you'll get the ugly raw as input), whereas the plugin will answer 400 (malformed JSON).
|
|
165
166
|
Please consider explicitly setting your requests' Content-Type and using separate templates.
|
|
166
167
|
|
|
168
|
+
## Run modes
|
|
169
|
+
|
|
170
|
+
### node.js
|
|
171
|
+
|
|
172
|
+
Lambda handlers for the `node.js` runtime can run in different execution modes with `serverless-offline` and they have subtle differences with a variety of pros and cons. they are mutually exclusive and it is planned to combine the flags into one single flag in the future.
|
|
173
|
+
|
|
174
|
+
#### worker-threads (default)
|
|
175
|
+
|
|
176
|
+
- handlers run in their own context
|
|
177
|
+
- memory is not being shared between handlers, memory consumption is therefore higher
|
|
178
|
+
- memory is being released when handlers reload or after usage
|
|
179
|
+
- environment (process.env) is not being shared across handlers
|
|
180
|
+
- global state is not being shared across handlers
|
|
181
|
+
- easy debugging
|
|
182
|
+
|
|
183
|
+
#### in-process
|
|
184
|
+
|
|
185
|
+
- handlers run in the same context (instance) as `serverless` and `serverless-offline`
|
|
186
|
+
- memory is being shared across lambda handlers as well as with `serverless` and `serverless-offline`
|
|
187
|
+
- no reloading capabilities as it is [currently] not possible to implement for commonjs handlers (without memory leaks) and for esm handlers
|
|
188
|
+
- environment (process.env) is being shared across handlers as well as with `serverless` and `serverless-offline`
|
|
189
|
+
- global state is being shared across lambda handlers as well as with `serverless` and `serverless-offline`
|
|
190
|
+
- easy debugging
|
|
191
|
+
|
|
192
|
+
#### child-processes
|
|
193
|
+
|
|
194
|
+
- handlers run in a separate node.js instance
|
|
195
|
+
- memory is not being shared between handlers, memory consumption is therefore higher
|
|
196
|
+
- memory is being released when handlers reload or after usage
|
|
197
|
+
- environment (process.env) is not being shared across handlers
|
|
198
|
+
- global state is not being shared across handlers
|
|
199
|
+
- debugging more complicated
|
|
200
|
+
|
|
201
|
+
#### docker
|
|
202
|
+
|
|
203
|
+
- handlers run in a docker container
|
|
204
|
+
- memory is not being shared between handlers, memory consumption is therefore higher
|
|
205
|
+
- memory is being released when handlers reload or after usage
|
|
206
|
+
- environment (process.env) is not being shared across handlers
|
|
207
|
+
- global state is not being shared across handlers
|
|
208
|
+
- debugging more complicated
|
|
209
|
+
|
|
210
|
+
### Python, Ruby, Go, Java (incl. Kotlin, Groovy, Scala)
|
|
211
|
+
|
|
212
|
+
the Lambda handler process is running in a child process.
|
|
213
|
+
|
|
167
214
|
## Usage with `invoke`
|
|
168
215
|
|
|
169
|
-
To use `Lambda.invoke` you need to set the lambda endpoint to the serverless-offline endpoint:
|
|
216
|
+
To use `Lambda.invoke` you need to set the lambda endpoint to the `serverless-offline` endpoint:
|
|
170
217
|
|
|
171
218
|
```js
|
|
219
|
+
const { env } = require('node:process')
|
|
172
220
|
const { Lambda } = require('aws-sdk')
|
|
173
221
|
|
|
174
222
|
const lambda = new Lambda({
|
|
175
223
|
apiVersion: '2015-03-31',
|
|
176
|
-
// endpoint needs to be set only if it deviates from the default
|
|
177
|
-
|
|
178
|
-
endpoint: process.env.SOME_VARIABLE
|
|
224
|
+
// endpoint needs to be set only if it deviates from the default
|
|
225
|
+
endpoint: env.IS_OFFLINE
|
|
179
226
|
? 'http://localhost:3002'
|
|
180
227
|
: 'https://lambda.us-east-1.amazonaws.com',
|
|
181
228
|
})
|
|
@@ -184,15 +231,33 @@ const lambda = new Lambda({
|
|
|
184
231
|
All your lambdas can then be invoked in a handler using
|
|
185
232
|
|
|
186
233
|
```js
|
|
234
|
+
const { Buffer } = require('node:buffer')
|
|
235
|
+
const { Lambda } = require('aws-sdk')
|
|
236
|
+
|
|
237
|
+
const { stringify } = JSON
|
|
238
|
+
|
|
239
|
+
const lambda = new Lambda({
|
|
240
|
+
apiVersion: '2015-03-31',
|
|
241
|
+
endpoint: 'http://localhost:3002',
|
|
242
|
+
})
|
|
243
|
+
|
|
187
244
|
exports.handler = async function () {
|
|
245
|
+
const clientContextData = stringify({ foo: 'foo' })
|
|
246
|
+
|
|
188
247
|
const params = {
|
|
248
|
+
ClientContext: Buffer.from(clientContextData).toString('base64'),
|
|
189
249
|
// FunctionName is composed of: service name - stage - function name, e.g.
|
|
190
250
|
FunctionName: 'myServiceName-dev-invokedHandler',
|
|
191
251
|
InvocationType: 'RequestResponse',
|
|
192
|
-
Payload:
|
|
252
|
+
Payload: stringify({ data: 'foo' }),
|
|
193
253
|
}
|
|
194
254
|
|
|
195
255
|
const response = await lambda.invoke(params).promise()
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
body: stringify(response),
|
|
259
|
+
statusCode: 200,
|
|
260
|
+
}
|
|
196
261
|
}
|
|
197
262
|
```
|
|
198
263
|
|
|
@@ -244,7 +309,7 @@ to calling it via `aws-sdk`.
|
|
|
244
309
|
|
|
245
310
|
## The `process.env.IS_OFFLINE` variable
|
|
246
311
|
|
|
247
|
-
Will be `"true"` in your handlers
|
|
312
|
+
Will be `"true"` in your handlers when using `serverless-offline`.
|
|
248
313
|
|
|
249
314
|
## Docker and Layers
|
|
250
315
|
|
|
@@ -326,11 +391,11 @@ Only [custom authorizers](https://aws.amazon.com/blogs/compute/introducing-custo
|
|
|
326
391
|
|
|
327
392
|
The Custom authorizer is passed an `event` object as below:
|
|
328
393
|
|
|
329
|
-
```
|
|
394
|
+
```js
|
|
330
395
|
{
|
|
331
|
-
"type": "TOKEN",
|
|
332
396
|
"authorizationToken": "<Incoming bearer token>",
|
|
333
|
-
"methodArn": "arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>"
|
|
397
|
+
"methodArn": "arn:aws:execute-api:<Region id>:<Account id>:<API id>/<Stage>/<Method>/<Resource path>",
|
|
398
|
+
"type": "TOKEN"
|
|
334
399
|
}
|
|
335
400
|
```
|
|
336
401
|
|
|
@@ -338,11 +403,11 @@ The `methodArn` does not include the Account id or API id.
|
|
|
338
403
|
|
|
339
404
|
The plugin only supports retrieving Tokens from headers. You can configure the header as below:
|
|
340
405
|
|
|
341
|
-
```
|
|
406
|
+
```js
|
|
342
407
|
"authorizer": {
|
|
343
|
-
"
|
|
408
|
+
"authorizerResultTtlInSeconds": "0",
|
|
344
409
|
"identitySource": "method.request.header.Authorization", // or method.request.header.SomeOtherHeader
|
|
345
|
-
"
|
|
410
|
+
"type": "TOKEN"
|
|
346
411
|
}
|
|
347
412
|
```
|
|
348
413
|
|
|
@@ -370,14 +435,14 @@ If your authentication needs are custom and not satisfied by the existing capabi
|
|
|
370
435
|
```js
|
|
371
436
|
module.exports = function (endpoint, functionKey, method, path) {
|
|
372
437
|
return {
|
|
373
|
-
name: 'your strategy name',
|
|
374
|
-
scheme: 'your scheme name',
|
|
375
|
-
|
|
376
438
|
getAuthenticateFunction: () => ({
|
|
377
439
|
async authenticate(request, h) {
|
|
378
440
|
// your implementation
|
|
379
441
|
},
|
|
380
442
|
}),
|
|
443
|
+
|
|
444
|
+
name: 'your strategy name',
|
|
445
|
+
scheme: 'your scheme name',
|
|
381
446
|
}
|
|
382
447
|
}
|
|
383
448
|
```
|
|
@@ -441,7 +506,7 @@ Now let's make a request with this body: `{ "id": 1 }`
|
|
|
441
506
|
|
|
442
507
|
AWS parses the event as such:
|
|
443
508
|
|
|
444
|
-
```
|
|
509
|
+
```js
|
|
445
510
|
{
|
|
446
511
|
"payload": {
|
|
447
512
|
"id": 1
|
|
@@ -453,7 +518,7 @@ AWS parses the event as such:
|
|
|
453
518
|
|
|
454
519
|
Whereas Offline parses:
|
|
455
520
|
|
|
456
|
-
```
|
|
521
|
+
```js
|
|
457
522
|
{
|
|
458
523
|
"payload": {
|
|
459
524
|
"id": 1
|
|
@@ -505,7 +570,7 @@ Works out of the box. See examples in the manual_test directory.
|
|
|
505
570
|
|
|
506
571
|
Example of enabling proxy:
|
|
507
572
|
|
|
508
|
-
```
|
|
573
|
+
```yml
|
|
509
574
|
custom:
|
|
510
575
|
serverless-offline:
|
|
511
576
|
resourceRoutes: true
|
|
@@ -513,18 +578,18 @@ custom:
|
|
|
513
578
|
|
|
514
579
|
or
|
|
515
580
|
|
|
516
|
-
```
|
|
581
|
+
```yml
|
|
517
582
|
YourCloudFormationMethodId:
|
|
518
|
-
Type: AWS::ApiGateway::Method
|
|
519
583
|
Properties:
|
|
520
584
|
......
|
|
521
585
|
Integration:
|
|
522
586
|
Type: HTTP_PROXY
|
|
523
587
|
Uri: 'https://s3-${self:custom.region}.amazonaws.com/${self:custom.yourBucketName}/{proxy}'
|
|
524
588
|
......
|
|
589
|
+
Type: AWS::ApiGateway::Method
|
|
525
590
|
```
|
|
526
591
|
|
|
527
|
-
```
|
|
592
|
+
```yml
|
|
528
593
|
custom:
|
|
529
594
|
serverless-offline:
|
|
530
595
|
resourceRoutes:
|
|
@@ -542,7 +607,7 @@ May not work properly. Please PR. (Difficulty: hard?)
|
|
|
542
607
|
|
|
543
608
|
Example response velocity template:
|
|
544
609
|
|
|
545
|
-
```
|
|
610
|
+
```js
|
|
546
611
|
"responseParameters": {
|
|
547
612
|
"method.response.header.X-Powered-By": "Serverless", // a string
|
|
548
613
|
"method.response.header.Warning": "integration.response.body", // the whole response
|
|
@@ -559,7 +624,9 @@ Usage in order to send messages back to clients:
|
|
|
559
624
|
Or,
|
|
560
625
|
|
|
561
626
|
```js
|
|
562
|
-
const
|
|
627
|
+
const { ApiGatewayManagementApi } = require('aws-sdk')
|
|
628
|
+
|
|
629
|
+
const apiGatewayManagementApi = new ApiGatewayManagementApi({
|
|
563
630
|
apiVersion: '2018-11-29',
|
|
564
631
|
endpoint: 'http://localhost:3001',
|
|
565
632
|
});
|
|
@@ -648,7 +715,7 @@ You can change this profile directly in the code or by setting proper environmen
|
|
|
648
715
|
## Simulation quality
|
|
649
716
|
|
|
650
717
|
This plugin simulates API Gateway for many practical purposes, good enough for development - but is not a perfect simulator.
|
|
651
|
-
Specifically, Lambda currently runs on Node.js
|
|
718
|
+
Specifically, Lambda currently runs on Node.js v12.x, v14.x and v16.x ([AWS Docs](https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html)), whereas _Offline_ runs on your own runtime where no memory limits are enforced.
|
|
652
719
|
|
|
653
720
|
## Usage with other plugins
|
|
654
721
|
|
|
@@ -661,7 +728,7 @@ Plugins are executed in order, so plugins that process your code or add resource
|
|
|
661
728
|
|
|
662
729
|
For example:
|
|
663
730
|
|
|
664
|
-
```
|
|
731
|
+
```yml
|
|
665
732
|
plugins:
|
|
666
733
|
- serverless-middleware # modifies some of your handler based on configuration
|
|
667
734
|
- serverless-webpack # package your javascript handlers using webpack
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dedicatedTo": "Blue, a great migrating bird.",
|
|
3
3
|
"name": "serverless-offline",
|
|
4
|
-
"version": "9.1.
|
|
4
|
+
"version": "9.1.1",
|
|
5
5
|
"description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "./src/index.js",
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
"@hapi/boom": "^10.0.0",
|
|
195
195
|
"@hapi/h2o2": "^9.1.0",
|
|
196
196
|
"@hapi/hapi": "^20.2.2",
|
|
197
|
-
"aws-sdk": "^2.
|
|
197
|
+
"aws-sdk": "^2.1184.0",
|
|
198
198
|
"boxen": "^7.0.0",
|
|
199
199
|
"chalk": "^5.0.1",
|
|
200
200
|
"execa": "^6.1.0",
|
package/src/config/constants.js
CHANGED
|
@@ -9,7 +9,7 @@ export const DEFAULT_LAMBDA_RUNTIME = 'nodejs14.x'
|
|
|
9
9
|
// https://docs.aws.amazon.com/lambda/latest/dg/limits.html
|
|
10
10
|
export const DEFAULT_LAMBDA_MEMORY_SIZE = 1024
|
|
11
11
|
// default function timeout in seconds
|
|
12
|
-
export const DEFAULT_LAMBDA_TIMEOUT =
|
|
12
|
+
export const DEFAULT_LAMBDA_TIMEOUT = 6 // 6 seconds
|
|
13
13
|
|
|
14
14
|
// timeout for all connections to be closed
|
|
15
15
|
export const SERVER_SHUTDOWN_TIMEOUT = 5000
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
} from '../config/index.js'
|
|
16
16
|
import { createUniqueId, splitHandlerPathAndName } from '../utils/index.js'
|
|
17
17
|
|
|
18
|
-
const { entries, fromEntries } = Object
|
|
19
18
|
const { ceil } = Math
|
|
19
|
+
const { entries, fromEntries } = Object
|
|
20
20
|
|
|
21
21
|
export default class LambdaFunction {
|
|
22
22
|
#artifact = null
|
|
@@ -41,14 +41,18 @@ export default class ChildProcessRunner {
|
|
|
41
41
|
},
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let message
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
message = new Promise((res, rej) => {
|
|
48
|
+
childProcess.on('message', (data) => {
|
|
49
|
+
if (data.error) rej(data.error)
|
|
50
|
+
else res(data)
|
|
51
|
+
})
|
|
48
52
|
})
|
|
49
|
-
}
|
|
53
|
+
} finally {
|
|
50
54
|
childProcess.kill()
|
|
51
|
-
}
|
|
55
|
+
}
|
|
52
56
|
|
|
53
57
|
childProcess.send({
|
|
54
58
|
context,
|
|
@@ -12,6 +12,8 @@ import pRetry from 'p-retry'
|
|
|
12
12
|
import DockerImage from './DockerImage.js'
|
|
13
13
|
|
|
14
14
|
const { stringify } = JSON
|
|
15
|
+
const { floor, log: mathLog } = Math
|
|
16
|
+
const { parseFloat } = Number
|
|
15
17
|
const { entries, hasOwn } = Object
|
|
16
18
|
|
|
17
19
|
export default class DockerContainer {
|
|
@@ -402,7 +404,7 @@ export default class DockerContainer {
|
|
|
402
404
|
const dm = decimals < 0 ? 0 : decimals
|
|
403
405
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
404
406
|
|
|
405
|
-
const i =
|
|
407
|
+
const i = floor(mathLog(bytes) / mathLog(k))
|
|
406
408
|
|
|
407
409
|
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`
|
|
408
410
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { mkdir, readFile, rm, rmdir, writeFile } from 'node:fs/promises'
|
|
2
2
|
import { EOL } from 'node:os'
|
|
3
|
-
import { sep, resolve, parse as pathParse } from 'node:path'
|
|
4
3
|
import process, { chdir, cwd } from 'node:process'
|
|
4
|
+
import { parse as pathParse, resolve, sep } from 'node:path'
|
|
5
5
|
import { log } from '@serverless/utils/log.js'
|
|
6
|
-
import { execa
|
|
6
|
+
import { execa } from 'execa'
|
|
7
7
|
|
|
8
8
|
const { parse, stringify } = JSON
|
|
9
9
|
|
|
@@ -18,10 +18,10 @@ export default class GoRunner {
|
|
|
18
18
|
|
|
19
19
|
#handlerPath = null
|
|
20
20
|
|
|
21
|
-
#tmpPath = null
|
|
22
|
-
|
|
23
21
|
#tmpFile = null
|
|
24
22
|
|
|
23
|
+
#tmpPath = null
|
|
24
|
+
|
|
25
25
|
constructor(funOptions, env) {
|
|
26
26
|
const { handlerPath, codeDir } = funOptions
|
|
27
27
|
|
|
@@ -34,8 +34,10 @@ export default class GoRunner {
|
|
|
34
34
|
try {
|
|
35
35
|
// refresh go.mod
|
|
36
36
|
await rm(this.#tmpFile)
|
|
37
|
-
|
|
38
|
-
await rmdir(this.#tmpPath, {
|
|
37
|
+
await execa('go', ['mod', 'tidy'])
|
|
38
|
+
await rmdir(this.#tmpPath, {
|
|
39
|
+
recursive: true,
|
|
40
|
+
})
|
|
39
41
|
} catch {
|
|
40
42
|
// @ignore
|
|
41
43
|
}
|
|
@@ -122,8 +124,11 @@ export default class GoRunner {
|
|
|
122
124
|
chdir(cwdPath.substring(0, cwdPath.indexOf('main.go')))
|
|
123
125
|
|
|
124
126
|
// Make sure we have the mock-lambda runner
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
await execa('go', [
|
|
128
|
+
'get',
|
|
129
|
+
'github.com/icarus-sullivan/mock-lambda@e065469',
|
|
130
|
+
])
|
|
131
|
+
await execa('go', ['build'])
|
|
127
132
|
} catch {
|
|
128
133
|
// @ignore
|
|
129
134
|
}
|
|
@@ -3,6 +3,7 @@ import { performance } from 'node:perf_hooks'
|
|
|
3
3
|
import process from 'node:process'
|
|
4
4
|
import { log } from '@serverless/utils/log.js'
|
|
5
5
|
|
|
6
|
+
const { floor } = Math
|
|
6
7
|
const { assign } = Object
|
|
7
8
|
|
|
8
9
|
const require = createRequire(import.meta.url)
|
|
@@ -88,11 +89,11 @@ export default class InProcessRunner {
|
|
|
88
89
|
...context,
|
|
89
90
|
done: (err, data) => callback(err, data),
|
|
90
91
|
fail: (err) => callback(err),
|
|
91
|
-
getRemainingTimeInMillis
|
|
92
|
+
getRemainingTimeInMillis() {
|
|
92
93
|
const timeLeft = executionTimeout - performance.now()
|
|
93
94
|
|
|
94
95
|
// just return 0 for now if we are beyond alotted time (timeout)
|
|
95
|
-
return timeLeft > 0 ? timeLeft : 0
|
|
96
|
+
return timeLeft > 0 ? floor(timeLeft) : 0
|
|
96
97
|
},
|
|
97
98
|
succeed: (res) => callback(null, res),
|
|
98
99
|
}
|
|
@@ -2,10 +2,10 @@ import { env } from 'node:process'
|
|
|
2
2
|
import { parentPort, workerData } from 'node:worker_threads'
|
|
3
3
|
import InProcessRunner from '../in-process-runner/index.js'
|
|
4
4
|
|
|
5
|
-
const { functionKey, handlerName, handlerPath } = workerData
|
|
5
|
+
const { functionKey, handlerName, handlerPath, timeout } = workerData
|
|
6
6
|
|
|
7
7
|
parentPort.on('message', async (messageData) => {
|
|
8
|
-
const { context, event, port
|
|
8
|
+
const { context, event, port } = messageData
|
|
9
9
|
|
|
10
10
|
// TODO we could probably cache this in the module scope?
|
|
11
11
|
const inProcessRunner = new InProcessRunner(
|