scaleway / serverless-scaleway-functions

Plugin for Serverless Framework to allow users to deploy their serverless applications on Scaleway Functions
MIT License
78 stars 25 forks source link

fix(deploy): API rate-limiting when deploying many functions #210

Closed norbjd closed 8 months ago

norbjd commented 8 months ago

Summary

What's changed?

Why do we need this?

When deploying many functions at the same time (e.g. 50 functions), we would receive a 429 error (rate limit) thrown by Scaleway API. To avoid this, do not run all API requests concurrently, but 1 by 1 (for creation because it's a fast operation) or 5 by 5 (for deployment, as this takes more time).

BTW, this is similar to how Terraform deploy resources (10 by 10), I'm not reinventing something new here.

How have you tested it?

With this serverless.yaml containing 50 functions:

service: test
configValidationMode: off
provider:
  name: scaleway
  runtime: node18
plugins:
  - serverless-scaleway-functions
package:
  patterns:
    - "!node_modules/**"
functions:
  func1:
    handler: handler.handle
    minScale: 1
    maxScale: 1
  func2:
    handler: handler.handle
    minScale: 1
    maxScale: 1
  #...
  func50:
    handler: handler.handle
    minScale: 1
    maxScale: 1

Then, run serverless deploy.

Before (interesting logs only):
Creating function func1...
Creating function func2...
[...]
Error:
Error: AxiosError: Request failed with status code 429
    at manageError (/app/node_modules/serverless-scaleway-functions/shared/api/utils.js:20:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ScalewayDeploy.updateSingleFunction (/app/node_modules/serverless-scaleway-functions/deploy/lib/createFunctions.js:224:31)
    at async Promise.all (index 6)
Now (interesting logs only):
[...]
Creating function func1...
Creating function func2...
Creating function func4...
[...]
Uploading source code...
Deploying Functions...
Deploying func2...
Deploying func1...
Deploying func4...
[...]
Function func4 has been deployed to https://<redacted>.scw.cloud
Waiting for func4 domains deployment...
Domains for func4 have been deployed!
Function func3 has been deployed to https://<redacted>.scw.cloud
Waiting for func3 domains deployment...
Domains for func3 have been deployed!
[...]

And command serverless deploy succeeds.

Checklist

Details

norbjd commented 8 months ago

The checks are marked as "failing" just because I had to cancel npmtest / test (containers, 20.x). After running it three times, thing is this one never finishes (logs):

Jest did not exit one second after the test run has completed.

'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

It looks like an async operation is blocking stopping the test. I don't understand why it happens only one node 20. Anyway, as you can see in the logs, all tests are passing, it's just it's blocked forever. We can tackle this flaky test in another PR.

norbjd commented 8 months ago

Even if some checks are not passing, I'll merge it. See https://github.com/scaleway/serverless-scaleway-functions/pull/210#issuecomment-1889271508.