Skip to content

Commit 04c816d

Browse files
committed
Retrying poller initialization.
1 parent 7d440e5 commit 04c816d

File tree

4 files changed

+51
-6
lines changed

4 files changed

+51
-6
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
[![npm version][npm-badge]][npm-url]
44
[![Build Status - GitHub Actions][gha-badge]][gha-ci]
55

6-
A wrapper around @aws-sdk/client-appconfigdata to provide background polling and caching.
6+
This library polls AWS AppConfig on a background thread so your app has instant access to a cached version of your configuration.
7+
It relies on the official @aws-sdk/client-appconfigdata library to fetch the data.
78

89
Although AWS seems to recommend their [simplified retrieval methods](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-retrieving-simplified-methods.html) for fetching AppConfig, i.e. running an agent in a separate process, you may prefer to use this library:
910

1011
- You don't need to set up a lambda extension.
1112
- You easily get parity between your local development server and prod.
1213
- The parsed version of your config is conveniently cached.
13-
- You get convenient reporting of transient errors while the library works in the background to recover.
14+
- You get reporting of transient errors while the library works in the background to recover.
1415

1516
## Usage
1617

__tests__/poller.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,46 @@ describe('Poller', () => {
180180
standardConfig.configParser(configValue2),
181181
);
182182
});
183+
184+
it('Retries start session if first one fails', async () => {
185+
const configValue = 'worked once';
186+
187+
appConfigClientMock.on(StartConfigurationSessionCommand)
188+
.rejectsOnce({
189+
message: 'Failed to start',
190+
})
191+
.resolves({
192+
InitialConfigurationToken: 'initialToken',
193+
});
194+
195+
appConfigClientMock
196+
.on(GetLatestConfigurationCommand)
197+
.resolves({
198+
Configuration: Uint8ArrayBlobAdapter.fromString(configValue),
199+
});
200+
201+
const dataClient = new AppConfigDataClient();
202+
203+
poller = new Poller({
204+
dataClient: dataClient,
205+
...standardConfig,
206+
});
207+
208+
const initialResponse = await poller.start();
209+
expect(initialResponse.error).toBeDefined();
210+
expect(initialResponse.isInitiallySuccessful).toBeFalsy();
211+
212+
const latest = poller.getConfigurationString();
213+
214+
expect(latest.latestValue).toBeUndefined();
215+
expect(latest.errorCausingStaleValue).toBeUndefined();
216+
217+
await wait(standardConfig.pollIntervalSeconds * 1000 + 100);
218+
219+
const updated = poller.getConfigurationObject();
220+
expect(updated.errorCausingStaleValue).toBeUndefined();
221+
expect(updated.latestValue).toEqual(
222+
standardConfig.configParser(configValue),
223+
);
224+
});
183225
});

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aws-appconfig-poller",
3-
"version": "0.0.4",
3+
"version": "0.0.5",
44
"description": "A wrapper around @aws-sdk/client-appconfigdata to provide background polling and caching.",
55
"repository": {
66
"type": "git",
@@ -41,7 +41,7 @@
4141
"test": "jest --coverage",
4242
"prettier": "prettier --config .prettierrc --write .",
4343
"test:watch": "jest --watch",
44-
"infinite": "tsc && node build/examples/infinitePoller.js"
44+
"infinite": "tsc && node dist/examples/infinitePoller.js"
4545
},
4646
"author": "Tyler Arehart <tarehart@users.noreply.github.com>",
4747
"license": "MIT",

src/poller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ export interface Outcome {
2828

2929
type PollingPhase = 'ready' | 'starting' | 'active' | 'stopped';
3030

31+
const DEFAULT_POLL_INTERVAL_SECONDS = 60;
32+
3133
export class Poller<T> {
32-
private readonly DEFAULT_POLL_INTERVAL_SECONDS = 60;
3334

3435
private readonly config: PollerConfig<T>;
3536

@@ -130,6 +131,7 @@ export class Poller<T> {
130131

131132
return await this.fetchLatestConfiguration();
132133
} catch (e) {
134+
this.timeoutHandle = setTimeout(this.startPolling.bind(this), this.config.pollIntervalSeconds || DEFAULT_POLL_INTERVAL_SECONDS)
133135
return {
134136
isInitiallySuccessful: false,
135137
error: e,
@@ -248,7 +250,7 @@ export class Poller<T> {
248250
return (
249251
this.config.pollIntervalSeconds ||
250252
awsSuggestedSeconds ||
251-
this.DEFAULT_POLL_INTERVAL_SECONDS
253+
DEFAULT_POLL_INTERVAL_SECONDS
252254
);
253255
}
254256
}

0 commit comments

Comments
 (0)