Skip to content

Commit 26e616a

Browse files
gspletzereatondustin1OfTheDelmer
authored
feat: Add query time to Operator view (#3809)
* WIP * ✨ Add queryTime to Operator UI limits display Co-authored-by: Delmer Reed <delmer814+1@gmail.com> * MERGE CONFLICT: Resolve conflict of openAPI sha * ♻️ remove incorrect reference to queryTime in testIds * ♻️ Remove query time from non operator view Co-authored-by: Delmer Reed <delmer814+1@gmail.com> * ♻️ Add timeHelper tests and correct org limit type in operator * ♻️ update openAPI sha with merged changes Co-authored-by: Dustin Eaton <deaton@influxdata.com> Co-authored-by: Delmer Reed <delmer814+1@gmail.com>
1 parent 5e12471 commit 26e616a

File tree

12 files changed

+135
-38
lines changed

12 files changed

+135
-38
lines changed

cypress/e2e/cloud/operatorRO.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ describe('Operator Page', () => {
105105
'rate.readKBs',
106106
'rate.writeKBs',
107107
'rate.cardinality',
108+
'rate.queryTime',
108109
'bucket.maxBuckets',
109110
'bucket.maxRetentionDuration',
110111
'notificationRule.maxNotifications',

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"cy": "CYPRESS_dexUrl=https://$INGRESS_HOST:$PORT_HTTPS CYPRESS_baseUrl=http://localhost:9999 cypress open",
5353
"cy:dev": "source ../monitor-ci/.env && CYPRESS_dexUrl=CLOUD CYPRESS_baseUrl=https://$INGRESS_HOST:$PORT_HTTPS cypress open --config testFiles='{cloud,shared}/**/*.*'",
5454
"cy:dev-oss": "source ../monitor-ci/.env && CYPRESS_dexUrl=OSS CYPRESS_baseUrl=https://$INGRESS_HOST:$PORT_HTTPS cypress open --config testFiles='{oss,shared}/**/*.*'",
55-
"generate": "export SHA=2670263b84efd14387ffcaa01102db328cded3e4 && export REMOTE=https://raw.githubusercontent.com/influxdata/openapi/${SHA}/ && yarn generate-meta",
55+
"generate": "export SHA=1db94907acd4f8cb1eea002980af72edb2822990 && export REMOTE=https://raw.githubusercontent.com/influxdata/openapi/${SHA}/ && yarn generate-meta",
5656
"generate-local": "export REMOTE=../openapi/ && yarn generate-meta",
5757
"generate-meta": "if [ -z \"${CLOUD_URL}\" ]; then yarn generate-meta-oss; else yarn generate-meta-cloud; fi",
5858
"generate-meta-oss": "yarn oss-api && yarn notebooks && yarn unity && yarn annotations-oss && yarn pinned && yarn mapsd-oss && yarn cloudPriv",

src/billing/components/Free/OrgLimits.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,21 @@ const OrgLimits: FC = () => {
4343
})
4444
}
4545
if (name === 'rate') {
46-
return Object.entries(value).map(([n, v]: [string, Limit]) => {
47-
return (
48-
<Grid.Column
49-
key={n}
50-
widthXS={Columns.Twelve}
51-
widthSM={Columns.Six}
52-
widthMD={Columns.Four}
53-
widthLG={Columns.Three}
54-
>
55-
<OrgLimitStat name={n} value={v.maxAllowed} />
56-
</Grid.Column>
57-
)
58-
})
46+
return Object.entries(value)
47+
.filter(([n]) => n !== 'queryTime')
48+
.map(([n, v]: [string, Limit]) => {
49+
return (
50+
<Grid.Column
51+
key={n}
52+
widthXS={Columns.Twelve}
53+
widthSM={Columns.Six}
54+
widthMD={Columns.Four}
55+
widthLG={Columns.Three}
56+
>
57+
<OrgLimitStat name={n} value={v.maxAllowed} />
58+
</Grid.Column>
59+
)
60+
})
5961
}
6062
return (
6163
<Grid.Column

src/billing/utils/timeHelpers.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import {
2-
nsToHours,
32
hoursToDays,
43
hoursToNs,
5-
nsToDays,
64
minToSeconds,
5+
nsToDays,
6+
nsToHours,
7+
nsToSeconds,
8+
secondsToNs,
79
} from './timeHelpers'
810

911
it('converts nanoseconds to hours', () => {
@@ -26,10 +28,20 @@ it('converts hours to nanoseconds', () => {
2628
expect(hoursToNs(720)).toEqual(2592000000000000)
2729
})
2830

31+
it('converts nanoseconds to seconds', () => {
32+
expect(nsToSeconds(1500000000000)).toEqual(1500)
33+
})
34+
35+
it('converts seconds to nanoseconds', () => {
36+
expect(secondsToNs(1500)).toEqual(1500000000000)
37+
})
38+
2939
it('does not convert -1 (disabled)', () => {
3040
expect(nsToHours(-1)).toEqual(-1)
3141
expect(hoursToDays(-1)).toEqual(-1)
3242
expect(nsToDays(-1)).toEqual(-1)
3343
expect(minToSeconds(-1)).toEqual(-1)
3444
expect(hoursToNs(-1)).toEqual(-1)
45+
expect(nsToSeconds(-1)).toEqual(-1)
46+
expect(secondsToNs(-1)).toEqual(-1)
3547
})

src/billing/utils/timeHelpers.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ const hoursPerDay = 24
77

88
const secondsPerHour = minutesPerHour * secondsPerMinute
99

10-
const nanoPerHour =
11-
secondsPerHour * milliPerSecond * microPerMilli * nanoPerMicro
10+
const nanoPerSecond = milliPerSecond * microPerMilli * nanoPerMicro
11+
12+
const nanoPerHour = secondsPerHour * nanoPerSecond
1213

1314
export const nsToHours = (ns: number): number => {
1415
if (ns === -1) {
@@ -58,3 +59,19 @@ export const minToSeconds = (min: number) => {
5859
}
5960
return min * secondsPerMinute
6061
}
62+
63+
export const nsToSeconds = (ns: number): number => {
64+
if (ns === -1) {
65+
return ns
66+
}
67+
68+
return ns / nanoPerSecond
69+
}
70+
71+
export const secondsToNs = (seconds: number): number => {
72+
if (seconds === -1) {
73+
return seconds
74+
}
75+
76+
return seconds * nanoPerSecond
77+
}

src/cloud/actions/limits.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export enum ActionTypes {
5858
SetChecksLimitStatus = 'SET_CHECKS_LIMIT_STATUS',
5959
SetRulesLimitStatus = 'SET_RULES_LIMIT_STATUS',
6060
SetEndpointsLimitStatus = 'SET_ENDPOINTS_LIMIT_STATUS',
61+
SetQueryTimeRateLimitStatus = 'SET_QUERY_TIME_RATE_LIMIT_STATUS',
6162
SetReadRateLimitStatus = 'SET_READ_RATE_LIMIT_STATUS',
6263
SetWriteRateLimitStatus = 'SET_WRITE_RATE_LIMIT_STATUS',
6364
SetCardinalityLimitStatus = 'SET_CARDINALITY_LIMIT_STATUS',
@@ -72,6 +73,7 @@ export type Actions =
7273
| SetChecksLimitStatus
7374
| SetRulesLimitStatus
7475
| SetEndpointsLimitStatus
76+
| SetQueryTimeRateLimitStatus
7577
| SetReadRateLimitStatus
7678
| SetWriteRateLimitStatus
7779
| SetCardinalityLimitStatus
@@ -172,6 +174,20 @@ export const setEndpointsLimitStatus = (
172174
}
173175
}
174176

177+
export interface SetQueryTimeRateLimitStatus {
178+
type: ActionTypes.SetQueryTimeRateLimitStatus
179+
payload: {limitStatus: LimitStatus['status']}
180+
}
181+
182+
export const SetQueryTimeRateLimitStatus = (
183+
limitStatus: LimitStatus['status']
184+
): SetQueryTimeRateLimitStatus => {
185+
return {
186+
type: ActionTypes.SetQueryTimeRateLimitStatus,
187+
payload: {limitStatus},
188+
}
189+
}
190+
175191
export interface SetReadRateLimitStatus {
176192
type: ActionTypes.SetReadRateLimitStatus
177193
payload: {limitStatus: LimitStatus['status']}

src/cloud/reducers/limits.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface LimitsState {
1919
endpoints: LimitWithBlocked
2020
rate: {
2121
readKBs: Limit
22+
queryTime: Limit
2223
writeKBs: Limit
2324
cardinality: Limit
2425
}
@@ -41,6 +42,7 @@ export const defaultState: LimitsState = {
4142
endpoints: defaultLimitWithBlocked,
4243
rate: {
4344
readKBs: defaultLimit,
45+
queryTime: defaultLimit,
4446
writeKBs: defaultLimit,
4547
cardinality: defaultLimit,
4648
},
@@ -102,8 +104,9 @@ export const limitsReducer = (
102104
}
103105

104106
if (limits.rate) {
105-
const {readKBs, writeKBs, cardinality} = limits.rate
107+
const {queryTime, readKBs, writeKBs, cardinality} = limits.rate
106108

109+
draftState.rate.queryTime.maxAllowed = queryTime / 1e9
107110
draftState.rate.readKBs.maxAllowed = readKBs
108111
draftState.rate.writeKBs.maxAllowed = writeKBs
109112
draftState.rate.cardinality.maxAllowed = cardinality
@@ -142,6 +145,11 @@ export const limitsReducer = (
142145
return
143146
}
144147

148+
case ActionTypes.SetQueryTimeRateLimitStatus: {
149+
draftState.rate.queryTime.limitStatus = action.payload.limitStatus
150+
return
151+
}
152+
145153
case ActionTypes.SetReadRateLimitStatus: {
146154
draftState.rate.readKBs.limitStatus = action.payload.limitStatus
147155
return

src/operator/OrgOverlay.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ const OrgOverlay: FC = () => {
145145
/>
146146
</Grid.Column>
147147
</Grid.Row>
148+
<Grid.Row>
149+
<Grid.Column widthMD={Columns.Three}>
150+
<Form.Label label="Query Time (seconds)" />
151+
<LimitsField
152+
type={InputType.Number}
153+
name="rate.queryTime"
154+
limits={limits}
155+
onChangeLimits={setLimits}
156+
/>
157+
</Grid.Column>
158+
</Grid.Row>
148159
<Grid.Row>
149160
<Grid.Column widthMD={Columns.Three}>
150161
<Form.Label label="Max Buckets" />

src/operator/context/overlay.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,34 @@ import {
1818
import {toDisplayLimits} from 'src/operator/utils'
1919

2020
// Types
21-
import {OrgLimits, OperatorOrg} from 'src/types'
21+
import {OperatorOrgLimits, OperatorOrg} from 'src/types'
2222
import {RemoteDataState} from 'src/types'
2323

2424
export type Props = {
2525
children: JSX.Element
2626
}
2727

2828
export interface OverlayContextType {
29-
limits: OrgLimits
29+
limits: OperatorOrgLimits
3030
limitsStatus: RemoteDataState
3131
handleGetLimits: (id: string) => void
3232
handleGetOrg: (id: string) => void
33-
handleUpdateLimits: (id: string, limits: OrgLimits) => void
33+
handleUpdateLimits: (id: string, limits: OperatorOrgLimits) => void
3434
organization: OperatorOrg
3535
orgStatus: RemoteDataState
36-
setLimits: (_: OrgLimits) => void
36+
setLimits: (_: OperatorOrgLimits) => void
3737
updateLimitStatus: RemoteDataState
3838
}
3939

4040
export const DEFAULT_CONTEXT: OverlayContextType = {
4141
handleGetLimits: (_: string) => {},
4242
handleGetOrg: (_: string) => {},
43-
handleUpdateLimits: (_id: string, _limits: OrgLimits) => {},
43+
handleUpdateLimits: (_id: string, _limits: OperatorOrgLimits) => {},
4444
limits: null,
4545
limitsStatus: RemoteDataState.NotStarted,
4646
organization: null,
4747
orgStatus: RemoteDataState.NotStarted,
48-
setLimits: (_: OrgLimits) => {},
48+
setLimits: (_: OperatorOrgLimits) => {},
4949
updateLimitStatus: RemoteDataState.NotStarted,
5050
}
5151

@@ -111,7 +111,7 @@ export const OverlayProvider: FC<Props> = React.memo(({children}) => {
111111
)
112112

113113
const handleUpdateLimits = useCallback(
114-
async (id: string, updatedLimits: OrgLimits) => {
114+
async (id: string, updatedLimits: OperatorOrgLimits) => {
115115
try {
116116
setUpdateLimitStatus(RemoteDataState.Loading)
117117
await putOperatorOrgsLimits({orgId: id, data: updatedLimits})

src/operator/utils.test.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import {OrgLimits} from 'src/types'
1+
import {OperatorOrgLimits} from 'src/types'
22
import {fromDisplayLimits, toDisplayLimits} from 'src/operator/utils'
33

44
describe('converting limits for display', () => {
5-
const limits: OrgLimits = {
5+
const limits: OperatorOrgLimits = {
66
bucket: {
77
maxBuckets: 2,
88
maxRetentionDuration: 86400000000000,
@@ -23,6 +23,7 @@ describe('converting limits for display', () => {
2323
orgID: 'ID',
2424
rate: {
2525
cardinality: 10000,
26+
queryTime: 1500000000000,
2627
readKBs: 100000,
2728
writeKBs: 1000,
2829
},
@@ -31,20 +32,24 @@ describe('converting limits for display', () => {
3132
},
3233
}
3334

34-
it('converts max retention duration from ns to hours', () => {
35+
it('converts max retention duration from ns to hours and query time from ns to seconds', () => {
3536
const actual = toDisplayLimits(limits)
3637
const expected = {
3738
...limits,
3839
bucket: {
3940
...limits.bucket,
4041
maxRetentionDuration: 24,
4142
},
43+
rate: {
44+
...limits.rate,
45+
queryTime: 1500,
46+
},
4247
}
4348

4449
expect(actual).toEqual(expected)
4550
})
4651

47-
it('converts max retention duration from hours to ns', () => {
52+
it('converts max retention duration from hours to ns and query time from seconds to ns', () => {
4853
const displayLimits = toDisplayLimits(limits)
4954

5055
expect(fromDisplayLimits(displayLimits)).toEqual(limits)

0 commit comments

Comments
 (0)