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: add support for retry strategies #830

Merged
merged 3 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/cli/src/constructs/check-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ApiCheckDefaultConfig } from './api-check'
import { pathToPosix } from '../services/util'
import type { Region } from '..'
import type { Frequency } from './frequency'
import type { RetryStrategy } from './retry-strategy'

const defaultApiCheckDefaults: ApiCheckDefaultConfig = {
headers: [],
Expand Down Expand Up @@ -93,6 +94,10 @@ export interface CheckGroupProps {
*/
localTearDownScript?: string
apiCheckDefaults?: ApiCheckDefaultConfig
/**
* Sets a retry policy for the group. Use RetryStrategyBuilder to create a retry policy.
*/
retryStrategy?: RetryStrategy
}

/**
Expand All @@ -119,6 +124,7 @@ export class CheckGroup extends Construct {
localTearDownScript?: string
apiCheckDefaults: ApiCheckDefaultConfig
browserChecks?: BrowserCheckConfig
retryStrategy?: RetryStrategy

static readonly __checklyType = 'check-group'

Expand Down Expand Up @@ -156,6 +162,7 @@ export class CheckGroup extends Construct {
this.alertChannels = props.alertChannels ?? []
this.localSetupScript = props.localSetupScript
this.localTearDownScript = props.localTearDownScript
this.retryStrategy = props.retryStrategy
// `browserChecks` is not a CheckGroup resource property. Not present in synthesize()
this.browserChecks = props.browserChecks
const fileAbsolutePath = Session.checkFileAbsolutePath!
Expand Down Expand Up @@ -247,6 +254,7 @@ export class CheckGroup extends Construct {
localTearDownScript: this.localTearDownScript,
apiCheckDefaults: this.apiCheckDefaults,
environmentVariables: this.environmentVariables,
retryStrategy: this.retryStrategy,
}
}
}
8 changes: 8 additions & 0 deletions packages/cli/src/constructs/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { Region } from '..'
import type { CheckGroup } from './check-group'
import { PrivateLocation } from './private-location'
import { PrivateLocationCheckAssignment } from './private-location-check-assignment'
import { RetryStrategy } from './retry-strategy'

export interface CheckProps {
/**
Expand Down Expand Up @@ -80,6 +81,10 @@ export interface CheckProps {
* Determines if the check is available only when 'test' runs (not included when 'deploy' is executed).
*/
testOnly?: boolean
/**
* Sets a retry policy for the check. Use RetryStrategyBuilder to create a retry policy.
*/
retryStrategy?: RetryStrategy
}

// This is an abstract class. It shouldn't be used directly.
Expand All @@ -99,6 +104,7 @@ export abstract class Check extends Construct {
groupId?: Ref
alertChannels?: Array<AlertChannel>
testOnly?: boolean
retryStrategy?: RetryStrategy
__checkFilePath?: string // internal variable to filter by check file name from the CLI

static readonly __checklyType = 'check'
Expand Down Expand Up @@ -134,6 +140,7 @@ export abstract class Check extends Construct {
// alertSettings, useGlobalAlertSettings, groupId, groupOrder

this.testOnly = props.testOnly ?? false
this.retryStrategy = props.retryStrategy
this.__checkFilePath = Session.checkFilePath
}

Expand Down Expand Up @@ -209,6 +216,7 @@ export abstract class Check extends Construct {
frequencyOffset: this.frequencyOffset,
groupId: this.groupId,
environmentVariables: this.environmentVariables,
retryStrategy: this.retryStrategy,
}
}
}
1 change: 1 addition & 0 deletions packages/cli/src/constructs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from './private-location-group-assignment'
export * from './check'
export * from './dashboard'
export * from './phone-call-alert-channel'
export * from './retry-strategy'
67 changes: 67 additions & 0 deletions packages/cli/src/constructs/retry-strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export type RetryStrategyType = 'LINEAR' | 'EXPONENTIAL' | 'FIXED'

export interface RetryStrategy {
type: RetryStrategyType,
/**
* The number of seconds to wait before the first retry attempt.
*/
baseBackoffSeconds?: number,
/**
* The maximum number of attempts to retry the check. Value must be between 1 and 10.
*/
maxAttempts?: number,
/**
* The total amount of time to continue retrying the check (maximum 600 seconds).
*/
maxDurationSeconds?: number,
/**
* Whether retries should be run in the same region as the initial check run.
*/
sameRegion?: boolean,
}

export type RetryStrategyOptions = Pick<RetryStrategy, 'baseBackoffSeconds' | 'maxAttempts' | 'maxDurationSeconds' | 'sameRegion'>

export class RetryStrategyBuilder {
private static readonly DEFAULT_BASE_BACKOFF_SECONDS = 60
private static readonly DEFAULT_MAX_ATTEMPTS = 2
private static readonly DEFAULT_MAX_DURATION_SECONDS = 60 * 10
private static readonly DEFAULT_SAME_REGION = false

/**
* Each retry is run with the same backoff between attempts.
*/
static fixedStrategy (options: RetryStrategyOptions): RetryStrategy {
return RetryStrategyBuilder.retryStrategy('FIXED', options)
}

/**
* The delay between retries increases linearly
*
* The delay between retries is calculated using `baseBackoffSeconds * attempt`.
* For example, retries will be run with a backoff of 10s, 20s, 30s, and so on.
*/
static linearStrategy (options: RetryStrategyOptions): RetryStrategy {
return RetryStrategyBuilder.retryStrategy('LINEAR', options)
}

/**
* The delay between retries increases exponentially
*
* The delay between retries is calculated using `baseBackoffSeconds ^ attempt`.
* For example, retries will be run with a backoff of 10s, 100s, 1000s, and so on.
*/
static exponentialStrategy (options: RetryStrategyOptions): RetryStrategy {
return RetryStrategyBuilder.retryStrategy('EXPONENTIAL', options)
}

private static retryStrategy (type: RetryStrategyType, options: RetryStrategyOptions): RetryStrategy {
return {
type,
baseBackoffSeconds: options.baseBackoffSeconds ?? RetryStrategyBuilder.DEFAULT_BASE_BACKOFF_SECONDS,
maxAttempts: options.maxAttempts ?? RetryStrategyBuilder.DEFAULT_MAX_ATTEMPTS,
maxDurationSeconds: options.maxDurationSeconds ?? RetryStrategyBuilder.DEFAULT_MAX_DURATION_SECONDS,
sameRegion: options.sameRegion ?? RetryStrategyBuilder.DEFAULT_SAME_REGION,
}
}
}
Loading