From 4296eba6143fd58477ddd077ca9efa714c9403af Mon Sep 17 00:00:00 2001 From: "Michael Barney, Jr" Date: Tue, 14 May 2024 15:36:17 -0400 Subject: [PATCH] feat(cfn): use exponential backoff with jitter for cfn api calls --- CHANGELOG.md | 6 ++++++ flake.lock | 27 +++++++++++++++++++++++++++ flake.nix | 28 ++++++++++++++++++++++++++++ index.mjs | 27 ++++++++++++++++++++------- package.json | 2 +- 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/CHANGELOG.md b/CHANGELOG.md index c9b6cdd..7065627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # cfn-changeset-viewer +## 0.0.5 + +### Patch Changes + +- add exponential backoff to cfn api call + ## 0.0.4 ### Patch Changes diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..501f0a7 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1715691446, + "narHash": "sha256-4UUvzMzEKkyhmj+iu5wD4RiZz6hjOJyqbHea3y3HyKs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c7da9d305628d92202eb475048129cb86a89e9d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..ec91bf8 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "cfn-changeset-viewer"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/release-23.11"; + }; + outputs = { nixpkgs, ... }: + let + shell = { system }: + let + pkgs = import nixpkgs { + system = system; + }; + in + pkgs.mkShell { + buildInputs = [ + pkgs.awscli2 + pkgs.nodejs_20 + ]; + }; + in + { + devShells.aarch64-darwin.default = shell { system = "aarch64-darwin"; }; + devShells.x86_64-darwin.default = shell { system = "x86_64-darwin"; }; + devShells.aarch64-linux.default = shell { system = "aarch64-linux"; }; + devShells.x86_64-linux.default = shell { system = "x86_64-linux"; }; + }; +} diff --git a/index.mjs b/index.mjs index bcaa705..76cafc8 100755 --- a/index.mjs +++ b/index.mjs @@ -41,13 +41,26 @@ async function printChangeSet(changeSetId, stackName, path, showUnchangedPropert Dynamic: 0, }; if (!path) path = ""; - const response = await cfn.send( - new DescribeChangeSetCommand({ - ChangeSetName: changeSetId, - StackName: stackName, - IncludePropertyValues: true, - }), - ); + let response; + let attempts = 0; + + while (!response) { + try { + response = await cfn.send( + new DescribeChangeSetCommand({ + ChangeSetName: changeSetId, + StackName: stackName, + IncludePropertyValues: true, + }), + ); + } catch (err) { + if (!(err instanceof Error)) throw err; + if (err.name !== "Throttling") throw err; + if (attempts++ > 5) throw err; + // exponential backoff sleep with jitter + await new Promise((resolve) => setTimeout(resolve, 2 ** attempts * 1000 + Math.random() * 1000)); + } + } for (let change of response.Changes ?? []) { const resourceChange = change.ResourceChange; diff --git a/package.json b/package.json index ae4bb97..c47431b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cfn-changeset-viewer", - "version": "0.0.4", + "version": "0.0.5", "description": "View the details of a CloudFormation ChangeSet (including nested ones!) in a human-friendly way", "main": "index.mjs", "type": "module",