-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #8 - add circuit breaker to update exchange rate lambda
- Loading branch information
1 parent
be45ee2
commit 0abf4b7
Showing
10 changed files
with
216 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export enum CircuitBreakerEnum { | ||
EXCHANGE_RATE_EXTERNAL_API = 'EXCHANGE_RATE_EXTERNAL_API' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { CircuitBreakerEnum } from '../enums/circuitBreaker' | ||
import { CircuitBreakerState, CircuitBreakerData } from '../utils/circuitBreaker' | ||
|
||
export interface ICircuitBreakerRepository { | ||
get (key: CircuitBreakerEnum): Promise<CircuitBreakerData> | ||
update (key: CircuitBreakerEnum, state: CircuitBreakerState, nextAvailabilityCheckTimestamp: number): Promise<CircuitBreakerData> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { CircuitBreakerEnum } from '../enums/circuitBreaker' | ||
import { ICircuitBreakerRepository } from '../repositories/iCircuitBreakerRepository' | ||
|
||
export interface CircuitBreakerData { | ||
key: string | ||
state: CircuitBreakerState | ||
options: CircuitBreakerOptions | ||
nextAvailabilityCheckTimestamp: number | ||
} | ||
|
||
export type CircuitBreakerOptions = { | ||
openBreakerTimeoutInMs: number | ||
closedBreakerTimeoutInMs: number | ||
minFailedRequestThreshold: number | ||
} | ||
|
||
export enum CircuitBreakerState { | ||
OPENED = 'OPENED', | ||
CLOSED = 'CLOSED', | ||
HALF = 'HALF' | ||
} | ||
|
||
export interface ICircuitBreaker { | ||
get (key: CircuitBreakerEnum): Promise<CircuitBreakerData> | ||
fire (key: CircuitBreakerEnum): Promise<void> | ||
checkState (key: CircuitBreakerEnum): Promise<boolean> | ||
sendFailObservabilityEvent (key: CircuitBreakerEnum, circuitBreaker: CircuitBreakerData): void | ||
sendSuccessObservabilityEvent (key: CircuitBreakerEnum, circuitBreaker: CircuitBreakerData): void | ||
} | ||
|
||
export class CircuitBreaker implements ICircuitBreaker { | ||
private readonly logPrefix = 'CircuitBreaker' | ||
|
||
constructor ( | ||
private readonly circuitBreakerRepository: ICircuitBreakerRepository | ||
) {} | ||
|
||
async get (key: CircuitBreakerEnum): Promise<CircuitBreakerData> { | ||
console.log(`${this.logPrefix} :: get state`) | ||
return this.circuitBreakerRepository.get(key) | ||
} | ||
|
||
async fire (key: CircuitBreakerEnum) { | ||
console.log(`${this.logPrefix} :: close cicuit for key :: ${key}`) | ||
|
||
const circuitBreakerOptions = await this.get(key) | ||
|
||
const currentDate = +new Date() | ||
const nextAvailabilityCheckTimestamp = currentDate + circuitBreakerOptions.options.closedBreakerTimeoutInMs | ||
await this.circuitBreakerRepository.update(key, CircuitBreakerState.CLOSED, nextAvailabilityCheckTimestamp) | ||
this.sendFailObservabilityEvent(key, circuitBreakerOptions) | ||
} | ||
|
||
async checkState (key: CircuitBreakerEnum): Promise<boolean> { | ||
const circuitBreakerOptions = await this.get(CircuitBreakerEnum.EXCHANGE_RATE_EXTERNAL_API) | ||
|
||
if (circuitBreakerOptions.state === CircuitBreakerState.OPENED) { | ||
this.sendSuccessObservabilityEvent(key, circuitBreakerOptions) | ||
return true | ||
} | ||
|
||
const currentDate = +new Date() | ||
if (circuitBreakerOptions.state === CircuitBreakerState.CLOSED && circuitBreakerOptions.nextAvailabilityCheckTimestamp < currentDate) { | ||
await this.circuitBreakerRepository.update(key, CircuitBreakerState.OPENED, 0) | ||
return true | ||
} | ||
|
||
this.sendFailObservabilityEvent(key, circuitBreakerOptions) | ||
return false | ||
} | ||
|
||
sendFailObservabilityEvent (key: CircuitBreakerEnum, circuitBreaker: CircuitBreakerData): void { | ||
console.log(`${this.logPrefix} :: CLOSED event sent to New Relic :: ${JSON.stringify(circuitBreaker)}`) | ||
} | ||
|
||
sendSuccessObservabilityEvent (key: CircuitBreakerEnum, circuitBreaker: CircuitBreakerData): void { | ||
console.log(`${this.logPrefix} :: OPENED event sent to New Relic :: ${JSON.stringify(circuitBreaker)}`) | ||
} | ||
} | ||
|
||
export default CircuitBreaker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import dynamoose, { Schema } from 'dynamoose' | ||
import { Document } from 'dynamoose/dist/Document' | ||
import { SchemaDefinition } from 'dynamoose/dist/Schema' | ||
import { Model, ModelOptionsOptional } from 'dynamoose/dist/Model' | ||
import { CircuitBreakerData } from '../../../2-business/utils/circuitBreaker' | ||
|
||
export interface CircuitBreakerEntity extends Document, CircuitBreakerData { } | ||
|
||
const schemaDefinition: SchemaDefinition = { | ||
key: { | ||
type: String, | ||
hashKey: true | ||
}, | ||
state: { | ||
type: String, | ||
required: true | ||
}, | ||
options: { | ||
type: Object, | ||
required: true | ||
}, | ||
nextAvailabilityCheckTimestamp: { | ||
type: Number, | ||
required: true | ||
} | ||
} | ||
|
||
const schema = new Schema(schemaDefinition, { | ||
timestamps: true, | ||
saveUnknown: true | ||
}) | ||
|
||
const modelOptions: ModelOptionsOptional = { | ||
throughput: 'ON_DEMAND', | ||
create: false, | ||
waitForActive: false | ||
} | ||
|
||
export const CircuitBreakerModel: Model<CircuitBreakerEntity> = | ||
dynamoose.model('CircuitBreaker', schema, modelOptions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { CircuitBreakerState, CircuitBreakerData } from '../../2-business/utils/circuitBreaker' | ||
import { CircuitBreakerModel } from '../models/dynamo/circuitBreaker' | ||
import { ICircuitBreakerRepository } from '../../2-business/repositories/iCircuitBreakerRepository' | ||
import { CurrencyEnum } from '../../2-business/enums/currencyEnum' | ||
import { CircuitBreakerEnum } from '../../2-business/enums/circuitBreaker' | ||
|
||
export class CircuitBreakerRepository implements ICircuitBreakerRepository { | ||
get (key: CircuitBreakerEnum): Promise<CircuitBreakerData> { | ||
return CircuitBreakerModel.get({ key }) | ||
} | ||
|
||
update (key: CircuitBreakerEnum, state: CircuitBreakerState, nextAvailabilityCheckTimestamp: number): Promise<CircuitBreakerData> { | ||
return CircuitBreakerModel.update(key, { | ||
state, | ||
nextAvailabilityCheckTimestamp | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters