Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): parallel asset publishing #19367

Merged
merged 3 commits into from Mar 14, 2022

Conversation

misterjoshua
Copy link
Contributor

@misterjoshua misterjoshua commented Mar 12, 2022

Adds parallel asset publishing. In a 60-asset/60-Lambda test project, this change decreases the total hot-swap time from 57 seconds to 18 seconds.

Fixes #19193


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@gitpod-io
Copy link

gitpod-io bot commented Mar 12, 2022

@github-actions github-actions bot added the package/tools Related to AWS CDK Tools or CLI label Mar 12, 2022
@misterjoshua
Copy link
Contributor Author

misterjoshua commented Mar 12, 2022

Here's what publishing looks like on my test project:

Parallel Asset Publishing (18 seconds)

publish-parallel.mp4

@misterjoshua misterjoshua marked this pull request as ready for review March 12, 2022 17:03
@misterjoshua misterjoshua changed the title feat(cli): add parallel asset publishing fix(cli): speed up asset publishing by parallelizing it Mar 12, 2022
@rix0rrr rix0rrr changed the title fix(cli): speed up asset publishing by parallelizing it feat(cli): parallel asset publishing Mar 14, 2022
@rix0rrr rix0rrr added the pr-linter/exempt-readme The PR linter will not require README changes label Mar 14, 2022
@mergify
Copy link
Contributor

mergify bot commented Mar 14, 2022

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

1 similar comment
@mergify
Copy link
Contributor

mergify bot commented Mar 14, 2022

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject89A8053A-LhjRyN9kxr8o
  • Commit ID: ad36df7
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit c8cafef into aws:master Mar 14, 2022
@mergify
Copy link
Contributor

mergify bot commented Mar 14, 2022

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@misterjoshua misterjoshua deleted the add-parallel-publish branch March 14, 2022 23:35
@brianfrantz
Copy link

It appears that this change has exposed a race condition when publishing multiple ECS images from a Mac. It is causing our deployments to fail with:

[83%] fail: docker login --username AWS --password-stdin https://285872988623.dkr.ecr.us-east-1.amazonaws.com exited with error code 1: Error saving credentials: error storing credentials - err: exit status 1, out: The specified item already exists in the keychain.

It appears that this issue is caused by a combination of the CDK performing a “docker login” on each published asset, along with specific logic in the docker project for storing credentials in the OSX keychain.

The source code for docker-credentials-osxkeychain doesn’t update existing OSX keychain entries if present. Instead it always does a SecKeychainAddInternetPassword call, which fails if the entry is already in the keychain. That error isn’t caught and handled. Instead the code attempts to avoid this issue by deleting the entry in the keychain before each add attempt. This logic works fine for the normal use case of doing a single login and then making multiple authenticated docker calls (single-threaded or in parallel). In fact, the logic has been in place for five-plus years.

Unfortunately, the CDK calls “docker login” before each “docker push” call instead of once for the batch. Two publish calls started at the same time will (most of the time) result in a credentials sequence of “delete, delete, add, add” such that the second add will fail because the first add created the entry.

The best method for fixing this issue in the CDK would involve refactoring the publishing code to perform a single “docker login” for the batch of container assets. Unfortunately this would be a significant redesign as the logic is shared between lambda assets and container assets.

Another option might be to catch the failed login and try again after a small delay, with or without detecting the specific error message. This doesn’t feel super clean, but is less effort and is less likely to cause side effects. That said, while it should work fine for small numbers of container assets, it may become problematic when there are many publish calls all logging in and retrying all at once.

@misterjoshua
Copy link
Contributor Author

misterjoshua commented Apr 19, 2022

Unfortunately, the CDK calls “docker login” before each “docker push” call instead of once for the batch. Two publish calls started at the same time will (most of the time) result in a credentials sequence of “delete, delete, add, add” such that the second add will fail because the first add created the entry.

The best method for fixing this issue in the CDK would involve refactoring the publishing code to perform a single “docker login” for the batch of container assets. Unfortunately this would be a significant redesign as the logic is shared between lambda assets and container assets.

I wonder whether we could track logins here and only run docker login the first time login is called for a given endpoint. cc @rix0rrr any ideas?

@mitchlloyd
Copy link
Contributor

mitchlloyd commented Apr 27, 2022

This is blocking my upgrade to CDK 2. Is there a workaround for this issue? If not, perhaps this change could be rolled back until it's fixed?

Update: Downgrading to version 2.16.0 lets me continue the 2.0 upgrade.

@misterjoshua
Copy link
Contributor Author

@mitchlloyd @brianfrantz I've created a dedicated bug report issue to track this issue: #20116

I've also proposed a change that seems to resolve this problem on a mac I can access. #20117. It would benefit from your review and testing.

rix0rrr added a commit that referenced this pull request Oct 20, 2022
Once again, any change to anything anywhere broke someone. In this
particular case, parallel asset publishing (#19367, and in particular
building) broke a use case where someone uses a tool to build assets
that is not concurrency-safe. So -- now we need to make that
configurable.

Command line:

```
cdk deploy --no-asset-parallelism
```

cdk.json:

```
{
  "assetParallelism": false
}
```

Environment variables:

```
export CDK_ASSET_PARALLELISM=false
```
mergify bot pushed a commit that referenced this pull request Oct 26, 2022
Once again, any change to anything anywhere broke someone. In this particular case, parallel asset publishing (#19367, and in particular building) broke a use case where someone uses a tool to build assets that is not concurrency-safe. So -- now we need to make that configurable.

Command line:

```
cdk deploy --no-asset-parallelism
```

cdk.json:

```
{
  "assetParallelism": false
}
```

Environment variables:

```
export CDK_ASSET_PARALLELISM=false
```


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package/tools Related to AWS CDK Tools or CLI pr-linter/exempt-readme The PR linter will not require README changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(assets): publish Assets in parallel
5 participants