Skip to content
Open
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
14 changes: 11 additions & 3 deletions packages/cli/src/constructs/check-group-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ApiCheckDefaultConfig } from './api-check'
import type { Region } from '..'
import { type Frequency } from './frequency'
import {
type RetryStrategy,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type RetryStrategyBuilder, // Used for @links in comments.
} from './retry-strategy'
Expand All @@ -28,6 +27,8 @@ import { PrivateLocationGroupAssignment } from './private-location-group-assignm
import { Ref } from './ref'
import { Session } from './project'
import { validateDeprecatedDoubleCheck } from './internal/common-diagnostics'
import { CheckRetryStrategy } from './check'
import { MonitorRetryStrategy } from './monitor'

const defaultApiCheckDefaults: ApiCheckDefaultConfig = {
headers: [],
Expand All @@ -53,6 +54,13 @@ type MultiStepCheckConfig = CheckConfigDefaults & {
testMatch: string | string[],
}

/**
* Retry strategies supported by groups.
*/
export type GroupRetryStrategy =
| CheckRetryStrategy
| MonitorRetryStrategy

export interface CheckGroupV1Props {
/**
* The name of the check group.
Expand Down Expand Up @@ -236,7 +244,7 @@ export interface CheckGroupV1Props {
*
* If not set, retries are disabled for all checks in the group.
*/
retryStrategy?: RetryStrategy
retryStrategy?: GroupRetryStrategy

/**
* Determines whether the checks in the group should run on all selected
Expand Down Expand Up @@ -298,7 +306,7 @@ export class CheckGroupV1 extends Construct {
apiCheckDefaults: ApiCheckDefaultConfig
browserChecks?: BrowserCheckConfig
multiStepChecks?: MultiStepCheckConfig
retryStrategy?: RetryStrategy
retryStrategy?: GroupRetryStrategy
runParallel?: boolean
alertSettings?: AlertEscalation
useGlobalAlertSettings?: boolean
Expand Down
5 changes: 2 additions & 3 deletions packages/cli/src/constructs/check-group-v2.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PrivateLocation, PrivateLocationRef } from './private-location'
import type { Region } from '..'
import {
type RetryStrategy,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type RetryStrategyBuilder, // Used for @links in comments.
} from './retry-strategy'
Expand All @@ -11,7 +10,7 @@ import {
type AlertEscalationBuilder, // Used for @links in comments.
} from './alert-escalation-policy'
import { Diagnostics } from './diagnostics'
import { CheckGroupV1, CheckGroupV1Props } from './check-group-v1'
import { CheckGroupV1, CheckGroupV1Props, GroupRetryStrategy } from './check-group-v1'
import { validateRemovedDoubleCheck } from './internal/common-diagnostics'

export interface CheckGroupV2Props extends Omit<CheckGroupV1Props, 'alertEscalationPolicy'> {
Expand Down Expand Up @@ -73,7 +72,7 @@ export interface CheckGroupV2Props extends Omit<CheckGroupV1Props, 'alertEscalat
*
* If not set, individual check settings are used.
*/
retryStrategy?: RetryStrategy
retryStrategy?: GroupRetryStrategy

/**
* Determines whether the checks in the group should run on all selected
Expand Down
22 changes: 19 additions & 3 deletions packages/cli/src/constructs/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,29 @@ import type { Region } from '..'
import type { CheckGroupV1, CheckGroupV2, CheckGroupRef } from './check-group'
import { PrivateLocation, PrivateLocationRef } from './private-location'
import { PrivateLocationCheckAssignment } from './private-location-check-assignment'
import { RetryStrategy } from './retry-strategy'
import {
ExponentialRetryStrategy,
FixedRetryStrategy,
LinearRetryStrategy,
NoRetriesRetryStrategy,
SingleRetryStrategy,
} from './retry-strategy'
import { AlertEscalation } from './alert-escalation-policy'
import { IncidentTrigger } from './incident'
import { ConfigDefaultsGetter, makeConfigDefaultsGetter } from './check-config'
import { Diagnostics } from './diagnostics'
import { validateDeprecatedDoubleCheck } from './internal/common-diagnostics'

/**
* Retry strategies supported by checks.
*/
export type CheckRetryStrategy =
| LinearRetryStrategy
| ExponentialRetryStrategy
| FixedRetryStrategy
| SingleRetryStrategy
| NoRetriesRetryStrategy

/**
* Base configuration properties for all check types.
* These properties are inherited by ApiCheck, BrowserCheck, and other check types.
Expand Down Expand Up @@ -194,7 +210,7 @@ export interface CheckProps {
* })
* ```
*/
retryStrategy?: RetryStrategy
retryStrategy?: CheckRetryStrategy

/**
* Determines whether the check should run on all selected locations in parallel or round-robin.
Expand Down Expand Up @@ -227,7 +243,7 @@ export abstract class Check extends Construct {
groupId?: Ref
alertChannels?: Array<AlertChannel|AlertChannelRef>
testOnly?: boolean
retryStrategy?: RetryStrategy
retryStrategy?: CheckRetryStrategy
alertSettings?: AlertEscalation
useGlobalAlertSettings?: boolean
runParallel?: boolean
Expand Down
46 changes: 44 additions & 2 deletions packages/cli/src/constructs/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ import { CheckGroupV2 } from './check-group-v2'
import { Frequency } from './frequency'
import { IncidentTrigger } from './incident'
import { PrivateLocation, PrivateLocationRef } from './private-location'
import { RetryStrategy } from './retry-strategy'
import { NoRetriesRetryStrategy, RetryStrategyType, SingleRetryStrategy } from './retry-strategy'
import { Check, CheckProps } from './check'
import { Diagnostics } from './diagnostics'
import { validateRemovedDoubleCheck } from './internal/common-diagnostics'
import { InvalidPropertyValueDiagnostic } from './construct-diagnostics'

/**
* Retry strategies supported by monitors.
*/
export type MonitorRetryStrategy =
| SingleRetryStrategy
| NoRetriesRetryStrategy

export interface MonitorProps extends Omit<CheckProps, 'doubleCheck'> {
/**
Expand Down Expand Up @@ -74,8 +82,19 @@ export interface MonitorProps extends Omit<CheckProps, 'doubleCheck'> {
/**
* Sets a retry policy for the monitor. Use RetryStrategyBuilder to create a
* suitable retry strategy.
*
* Note that monitors only support a single retry.
*
* @example
* ```typescript
* // Single retry
* RetryStrategyBuilder.singleRetry()
*
* // No retries
* RetryStrategyBuilder.noRetries()
* ```
*/
retryStrategy?: RetryStrategy
retryStrategy?: MonitorRetryStrategy
/**
* Determines whether the monitor should create and resolve an incident
* based on its alert configuration.
Expand All @@ -95,6 +114,29 @@ export abstract class Monitor extends Check {
await validateRemovedDoubleCheck(diagnostics, this)
}

async validate (diagnostics: Diagnostics): Promise<void> {
await super.validate(diagnostics)

if (this.retryStrategy) {
const supported: RetryStrategyType[] = ['SINGLE', 'NO_RETRIES']
if (!supported.includes(this.retryStrategy.type)) {
diagnostics.add(new InvalidPropertyValueDiagnostic(
'retryStrategy',
new Error(
`Monitors only support a single retry. The following options ` +
`are available:` +
`\n\n` +
` // Single retry\n` +
` RetryStrategyBuilder.singleRetry()` +
`\n\n` +
` // No retries\n` +
` RetryStrategyBuilder.noRetries()`,
),
))
}
}
}

synthesize() {
return {
...super.synthesize(),
Expand Down
37 changes: 36 additions & 1 deletion packages/cli/src/constructs/retry-strategy-codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,52 @@ export type RetryStrategyResource = RetryStrategy
export function valueForRetryStrategy (genfile: GeneratedFile, strategy?: RetryStrategyResource | null): Value {
genfile.namedImport('RetryStrategyBuilder', 'checkly/constructs')

function buildCommonOptions (
function buildBaseBackoffSecondsOption (
options: RetryStrategyOptions,
builder: ObjectValueBuilder,
): void {
if (options.baseBackoffSeconds) {
builder.number('baseBackoffSeconds', options.baseBackoffSeconds)
}
}

function buildMaxRetriesOption (
options: RetryStrategyOptions,
builder: ObjectValueBuilder,
): void {
if (options.maxRetries) {
builder.number('maxRetries', options.maxRetries)
}
}

function buildMaxDurationSecondsOption (
options: RetryStrategyOptions,
builder: ObjectValueBuilder,
): void {
if (options.maxDurationSeconds) {
builder.number('maxDurationSeconds', options.maxDurationSeconds)
}
}

function buildSameRegionOption (
options: RetryStrategyOptions,
builder: ObjectValueBuilder,
): void {
if (options.sameRegion !== undefined) {
builder.boolean('sameRegion', options.sameRegion)
}
}

function buildCommonOptions (
options: RetryStrategyOptions,
builder: ObjectValueBuilder,
): void {
buildBaseBackoffSecondsOption(options, builder)
buildMaxRetriesOption(options, builder)
buildMaxDurationSecondsOption(options, builder)
buildSameRegionOption(options, builder)
}

if (strategy === null || strategy === undefined) {
return expr(ident('RetryStrategyBuilder'), builder => {
builder.member(ident('noRetries'))
Expand Down Expand Up @@ -64,6 +89,16 @@ export function valueForRetryStrategy (genfile: GeneratedFile, strategy?: RetryS
})
})
})
case 'SINGLE':
return expr(ident('RetryStrategyBuilder'), builder => {
builder.member(ident('singleRetry'))
builder.call(builder => {
builder.object(builder => {
buildBaseBackoffSecondsOption(strategy, builder)
buildSameRegionOption(strategy, builder)
})
})
})
case 'NO_RETRIES':
return expr(ident('RetryStrategyBuilder'), builder => {
builder.member(ident('noRetries'))
Expand Down
Loading
Loading