Skip to content

Commit a261957

Browse files
committed
fix: add rate limit for Tiles findSingleRow action
1 parent 1a0066c commit a261957

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

packages/backend/src/apps/tiles/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IApp } from '@plumber/types'
33
import getTransferDetails from './common/get-transfer-details'
44
import actions from './actions'
55
import dynamicData from './dynamic-data'
6+
import queue from './queue'
67

78
const app: IApp = {
89
name: 'Tiles',
@@ -17,6 +18,7 @@ const app: IApp = {
1718
actions,
1819
dynamicData,
1920
getTransferDetails,
21+
queue,
2022
}
2123

2224
export default app
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { IAppQueue } from '@plumber/types'
2+
3+
import { TILES_INTERVAL_BETWEEN_FIND_SINGLE_ROW_MS } from '@/config/app-env-vars/tiles'
4+
import Step from '@/models/step'
5+
6+
// Define actions that should be queued
7+
const QUEUED_ACTIONS = new Set(['findSingleRow'])
8+
9+
//
10+
// This config sets up a per-Tile findSingleRow action queue, i.e., only findSingleRow
11+
// actions are grouped and rate limited.
12+
// All other Tile actions are not grouped and do not need to be rate limited.
13+
//
14+
// This is necessary because the findSingleRow action is the most expensive
15+
// operation in the Tile app, due to the need to scan the entire DynamoDB table.
16+
//
17+
18+
const getGroupConfigForJob: IAppQueue['getGroupConfigForJob'] = async (
19+
jobData,
20+
) => {
21+
const step = await Step.query().findById(jobData.stepId).throwIfNotFound()
22+
const tableId = step.parameters['tableId'] as string
23+
24+
if (QUEUED_ACTIONS.has(step.key)) {
25+
return {
26+
id: `${tableId}-${step.key}`,
27+
}
28+
}
29+
30+
// All other Tile actions are not grouped and do not need to be rate limited
31+
// as the write operations are fast and less expensive.
32+
return null
33+
}
34+
35+
const queueSettings = {
36+
getGroupConfigForJob,
37+
groupLimits: {
38+
type: 'concurrency',
39+
concurrency: 1,
40+
},
41+
isQueueDelayable: true,
42+
queueRateLimit: {
43+
max: 1,
44+
duration: TILES_INTERVAL_BETWEEN_FIND_SINGLE_ROW_MS,
45+
},
46+
} satisfies IAppQueue
47+
48+
export default queueSettings

packages/backend/src/config/app-env-vars/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@
2424
import './m365'
2525
import './formsg'
2626
import './postman-sms'
27+
import './tiles'
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Default to 1 action per second.
2+
export const TILES_INTERVAL_BETWEEN_FIND_SINGLE_ROW_MS = Number(
3+
process.env.TILES_INTERVAL_BETWEEN_FIND_SINGLE_ROW_MS ?? '1000',
4+
)

0 commit comments

Comments
 (0)