mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 06:56:38 +00:00
Update autoscale throughput limits (#1229)
* Change minimum autoscale throughput and default autoscale throughput for free tier account to 1000 * Fix unit tests * Update snapshot * Fix cassandra add collection panel * Address comments * Add feature flag/flight * Remove console.log
This commit is contained in:
parent
7a809cd2bc
commit
605117c62d
@ -99,6 +99,7 @@ export class Flights {
|
||||
public static readonly PhoenixNotebooks = "phoenixnotebooks";
|
||||
public static readonly PhoenixFeatures = "phoenixfeatures";
|
||||
public static readonly NotebooksDownBanner = "notebooksdownbanner";
|
||||
public static readonly FreeTierAutoscaleThroughput = "freetierautoscalethroughput";
|
||||
}
|
||||
|
||||
export class AfecFeatures {
|
||||
|
@ -19,7 +19,7 @@ import { Action, ActionModifiers } from "../../../../../Shared/Telemetry/Telemet
|
||||
import * as TelemetryProcessor from "../../../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../../../UserContext";
|
||||
import * as AutoPilotUtils from "../../../../../Utils/AutoPilotUtils";
|
||||
import { minAutoPilotThroughput } from "../../../../../Utils/AutoPilotUtils";
|
||||
import { autoPilotThroughput1K, autoPilotThroughput4K } from "../../../../../Utils/AutoPilotUtils";
|
||||
import { calculateEstimateNumber, usageInGB } from "../../../../../Utils/PricingUtils";
|
||||
import { Int32 } from "../../../../Panes/Tables/Validators/EntityPropertyValidationCommon";
|
||||
import {
|
||||
@ -540,7 +540,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
step={AutoPilotUtils.autoPilotIncrementStep}
|
||||
value={this.overrideWithProvisionedThroughputSettings() ? "" : this.props.maxAutoPilotThroughput?.toString()}
|
||||
onChange={this.onAutoPilotThroughputChange}
|
||||
min={minAutoPilotThroughput}
|
||||
min={userContext.features.freetierAutoscaleThroughput ? autoPilotThroughput1K : autoPilotThroughput4K}
|
||||
errorMessage={this.props.throughputError}
|
||||
/>
|
||||
{!this.overrideWithProvisionedThroughputSettings() && this.getAutoPilotUsageCost()}
|
||||
|
@ -5,6 +5,7 @@ const props = {
|
||||
isDatabase: false,
|
||||
showFreeTierExceedThroughputTooltip: true,
|
||||
isSharded: true,
|
||||
isFreeTier: false,
|
||||
setThroughputValue: () => jest.fn(),
|
||||
setIsAutoscale: () => jest.fn(),
|
||||
setIsThroughputCapExceeded: () => jest.fn(),
|
||||
|
@ -14,6 +14,7 @@ import "./ThroughputInput.less";
|
||||
export interface ThroughputInputProps {
|
||||
isDatabase: boolean;
|
||||
isSharded: boolean;
|
||||
isFreeTier: boolean;
|
||||
showFreeTierExceedThroughputTooltip: boolean;
|
||||
setThroughputValue: (throughput: number) => void;
|
||||
setIsAutoscale: (isAutoscale: boolean) => void;
|
||||
@ -23,15 +24,20 @@ export interface ThroughputInputProps {
|
||||
|
||||
export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
isDatabase,
|
||||
isSharded,
|
||||
isFreeTier,
|
||||
showFreeTierExceedThroughputTooltip,
|
||||
setThroughputValue,
|
||||
setIsAutoscale,
|
||||
setIsThroughputCapExceeded,
|
||||
isSharded,
|
||||
onCostAcknowledgeChange,
|
||||
}: ThroughputInputProps) => {
|
||||
const [isAutoscaleSelected, setIsAutoScaleSelected] = useState<boolean>(true);
|
||||
const [throughput, setThroughput] = useState<number>(AutoPilotUtils.minAutoPilotThroughput);
|
||||
const [throughput, setThroughput] = useState<number>(
|
||||
isFreeTier && userContext.features.freetierAutoscaleThroughput
|
||||
? AutoPilotUtils.autoPilotThroughput1K
|
||||
: AutoPilotUtils.autoPilotThroughput4K
|
||||
);
|
||||
const [isCostAcknowledged, setIsCostAcknowledged] = useState<boolean>(false);
|
||||
const [throughputError, setThroughputError] = useState<string>("");
|
||||
const [totalThroughputUsed, setTotalThroughputUsed] = useState<number>(0);
|
||||
@ -151,11 +157,15 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
|
||||
const handleOnChangeMode = (event: React.ChangeEvent<HTMLInputElement>, mode: string): void => {
|
||||
if (mode === "Autoscale") {
|
||||
setThroughput(AutoPilotUtils.minAutoPilotThroughput);
|
||||
const defaultThroughput =
|
||||
isFreeTier && userContext.features.freetierAutoscaleThroughput
|
||||
? AutoPilotUtils.autoPilotThroughput1K
|
||||
: AutoPilotUtils.autoPilotThroughput4K;
|
||||
setThroughput(defaultThroughput);
|
||||
setIsAutoScaleSelected(true);
|
||||
setThroughputValue(AutoPilotUtils.minAutoPilotThroughput);
|
||||
setThroughputValue(defaultThroughput);
|
||||
setIsAutoscale(true);
|
||||
checkThroughputCap(AutoPilotUtils.minAutoPilotThroughput);
|
||||
checkThroughputCap(defaultThroughput);
|
||||
} else {
|
||||
setThroughput(SharedConstants.CollectionCreation.DefaultCollectionRUs400);
|
||||
setIsAutoScaleSelected(false);
|
||||
@ -226,7 +236,11 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
}}
|
||||
onChange={(event, newInput?: string) => onThroughputValueChange(newInput)}
|
||||
step={AutoPilotUtils.autoPilotIncrementStep}
|
||||
min={AutoPilotUtils.minAutoPilotThroughput}
|
||||
min={
|
||||
userContext.features.freetierAutoscaleThroughput
|
||||
? AutoPilotUtils.autoPilotThroughput1K
|
||||
: AutoPilotUtils.autoPilotThroughput4K
|
||||
}
|
||||
value={throughput.toString()}
|
||||
aria-label="Max request units per second"
|
||||
required={true}
|
||||
|
@ -3,6 +3,7 @@
|
||||
exports[`ThroughputInput Pane should render Default properly 1`] = `
|
||||
<ThroughputInput
|
||||
isDatabase={false}
|
||||
isFreeTier={false}
|
||||
isSharded={true}
|
||||
onCostAcknowledgeChange={[Function]}
|
||||
setIsAutoscale={[Function]}
|
||||
|
@ -249,6 +249,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
showFreeTierExceedThroughputTooltip={this.isFreeTierAccount() && !isFirstResourceCreated}
|
||||
isDatabase={true}
|
||||
isSharded={this.state.isSharded}
|
||||
isFreeTier={this.isFreeTierAccount()}
|
||||
setThroughputValue={(throughput: number) => (this.newDatabaseThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (this.isNewDatabaseAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isThroughputCapExceeded: boolean) =>
|
||||
@ -483,6 +484,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
showFreeTierExceedThroughputTooltip={this.isFreeTierAccount() && !isFirstResourceCreated}
|
||||
isDatabase={false}
|
||||
isSharded={this.state.isSharded}
|
||||
isFreeTier={this.isFreeTierAccount()}
|
||||
setThroughputValue={(throughput: number) => (this.collectionThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (this.isCollectionAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isThroughputCapExceeded: boolean) =>
|
||||
|
@ -146,9 +146,10 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
// TODO add feature flag that disables validation for customers with custom accounts
|
||||
if (isAutoscaleSelected) {
|
||||
if (!AutoPilotUtils.isValidAutoPilotThroughput(throughput)) {
|
||||
setFormErrors(
|
||||
`Please enter a value greater than ${AutoPilotUtils.minAutoPilotThroughput} for autopilot throughput`
|
||||
);
|
||||
const minAutoPilotThroughput = userContext.features.freetierAutoscaleThroughput
|
||||
? AutoPilotUtils.autoPilotThroughput1K
|
||||
: AutoPilotUtils.autoPilotThroughput4K;
|
||||
setFormErrors(`Please enter a value greater than ${minAutoPilotThroughput} for autopilot throughput`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -241,6 +242,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !useDatabases.getState().isFirstResourceCreated()}
|
||||
isDatabase={true}
|
||||
isSharded={databaseCreateNewShared}
|
||||
isFreeTier={isFreeTierAccount}
|
||||
setThroughputValue={(newThroughput: number) => (throughput = newThroughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (isAutoscaleSelected = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isCapExceeded: boolean) => setIsThroughputCapExceeded(isCapExceeded)}
|
||||
|
@ -262,6 +262,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
}
|
||||
isDatabase
|
||||
isSharded
|
||||
isFreeTier={isFreeTierAccount}
|
||||
setThroughputValue={(throughput: number) => (newKeySpaceThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (isNewKeySpaceAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isCapExceeded: boolean) => setIsThroughputCapExceeded(isCapExceeded)}
|
||||
@ -335,6 +336,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
showFreeTierExceedThroughputTooltip={isFreeTierAccount && !useDatabases.getState().isFirstResourceCreated()}
|
||||
isDatabase={false}
|
||||
isSharded
|
||||
isFreeTier={isFreeTierAccount}
|
||||
setThroughputValue={(throughput: number) => (tableThroughput = throughput)}
|
||||
setIsAutoscale={(isAutoscale: boolean) => (isTableAutoscale = isAutoscale)}
|
||||
setIsThroughputCapExceeded={(isCapExceeded: boolean) => setIsThroughputCapExceeded(isCapExceeded)}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export type Features = {
|
||||
// set only via feature flags
|
||||
readonly canExceedMaximumValue: boolean;
|
||||
readonly cosmosdb: boolean;
|
||||
readonly enableChangeFeedPolicy: boolean;
|
||||
@ -8,12 +9,6 @@ export type Features = {
|
||||
readonly enableReactPane: boolean;
|
||||
readonly enableRightPanelV2: boolean;
|
||||
readonly enableSchema: boolean;
|
||||
autoscaleDefault: boolean;
|
||||
partitionKeyDefault: boolean;
|
||||
partitionKeyDefault2: boolean;
|
||||
phoenixNotebooks: boolean;
|
||||
phoenixFeatures: boolean;
|
||||
notebooksDownBanner: boolean;
|
||||
readonly enableSDKoperations: boolean;
|
||||
readonly enableSpark: boolean;
|
||||
readonly enableTtl: boolean;
|
||||
@ -34,11 +29,22 @@ export type Features = {
|
||||
readonly mongoProxyEndpoint?: string;
|
||||
readonly mongoProxyAPIs?: string;
|
||||
readonly enableThroughputCap: boolean;
|
||||
|
||||
// can be set via both flight and feature flag
|
||||
autoscaleDefault: boolean;
|
||||
partitionKeyDefault: boolean;
|
||||
partitionKeyDefault2: boolean;
|
||||
phoenixNotebooks: boolean;
|
||||
phoenixFeatures: boolean;
|
||||
notebooksDownBanner: boolean;
|
||||
freetierAutoscaleThroughput: boolean;
|
||||
};
|
||||
|
||||
export function extractFeatures(given = new URLSearchParams(window.location.search)): Features {
|
||||
const downcased = new URLSearchParams();
|
||||
const set = (value: string, key: string) => downcased.set(key.toLowerCase(), value);
|
||||
const set = (value: string, key: string) => {
|
||||
downcased.set(key.toLowerCase(), value);
|
||||
};
|
||||
const get = (key: string, defaultValue?: string) =>
|
||||
downcased.get("feature." + key) ?? downcased.get(key) ?? defaultValue;
|
||||
|
||||
@ -86,6 +92,7 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
|
||||
phoenixFeatures: "true" === get("phoenixfeatures"),
|
||||
notebooksDownBanner: "true" === get("notebooksDownBanner"),
|
||||
enableThroughputCap: "true" === get("enablethroughputcap"),
|
||||
freetierAutoscaleThroughput: "true" === get("freetierautoscalethroughput"),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,16 @@
|
||||
export const minAutoPilotThroughput = 4000;
|
||||
import { userContext } from "UserContext";
|
||||
|
||||
export const autoPilotThroughput1K = 1000;
|
||||
export const autoPilotIncrementStep = 1000;
|
||||
export const autoPilotThroughput4K = 4000;
|
||||
|
||||
export function isValidAutoPilotThroughput(maxThroughput: number): boolean {
|
||||
if (!maxThroughput) {
|
||||
return false;
|
||||
}
|
||||
const minAutoPilotThroughput = userContext.features.freetierAutoscaleThroughput
|
||||
? autoPilotThroughput4K
|
||||
: autoPilotThroughput1K;
|
||||
if (maxThroughput < minAutoPilotThroughput) {
|
||||
return false;
|
||||
}
|
||||
|
@ -373,6 +373,9 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
|
||||
if (inputs.flights.indexOf(Flights.NotebooksDownBanner) !== -1) {
|
||||
userContext.features.notebooksDownBanner = true;
|
||||
}
|
||||
if (inputs.flights.indexOf(Flights.FreeTierAutoscaleThroughput) !== -1) {
|
||||
userContext.features.freetierAutoscaleThroughput = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user