From 6df1fe68bdfc1296f91086a04a1c165d47b25188 Mon Sep 17 00:00:00 2001 From: gautami uttarwar Date: Tue, 16 May 2023 17:54:09 -0500 Subject: [PATCH 1/4] added retry & timeout fields --- src/mainviews/create-job.tsx | 73 +++++++++++++++++++++++++++++++- src/model.ts | 13 +++++- src/util/job-name-validation.tsx | 61 ++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 3 deletions(-) diff --git a/src/mainviews/create-job.tsx b/src/mainviews/create-job.tsx index 9b2ea81c0..17925e830 100644 --- a/src/mainviews/create-job.tsx +++ b/src/mainviews/create-job.tsx @@ -20,7 +20,7 @@ import { Scheduler, SchedulerService } from '../handler'; import { useTranslator } from '../hooks'; import { ICreateJobModel, IJobParameter, JobsView } from '../model'; import { Scheduler as SchedulerTokens } from '../tokens'; -import { NameError } from '../util/job-name-validation'; +import { NameError, MaxRetryAttemptsError, MaxRunTimeError, MaxWaitTimeError } from '../util/job-name-validation'; import { caretDownIcon } from '@jupyterlab/ui-components'; @@ -191,6 +191,26 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { } }; + const handleNumericInputChange = (event: ChangeEvent) => { + const target = event.target; + + const parameterNameIdx = parameterNameMatch(target.name); + const parameterValueIdx = parameterValueMatch(target.name); + const newParams = props.model.parameters || []; + + if (parameterNameIdx !== null) { + newParams[parameterNameIdx].name = target.value; + props.handleModelChange({ ...props.model, parameters: newParams }); + } else if (parameterValueIdx !== null) { + newParams[parameterValueIdx].value = +target.value; + props.handleModelChange({ ...props.model, parameters: newParams }); + } else { + const value = +target.value; + const name = target.name; + props.handleModelChange({ ...props.model, [name]: isNaN(value)? target.value: value }); + } + }; + const handleSelectChange = (event: SelectChangeEvent) => { const target = event.target; @@ -495,6 +515,57 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { environmentList={environmentList} value={props.model.environment} /> + { + // Validate name + setErrors({ + ...errors, + maxRetryAttempts: MaxRetryAttemptsError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxRetryAttempts']} + helperText={errors['maxRetryAttempts'] ?? ''} + value={props.model.maxRetryAttempts} + id={`${formPrefix}maxRetryAttempts`} + name="maxRetryAttempts" + /> + { + // Validate name + setErrors({ + ...errors, + maxRunTime: MaxRunTimeError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxRunTime']} + helperText={errors['maxRunTime'] ?? ''} + value={props.model.maxRunTime} + id={`${formPrefix}maxRunTime`} + name="maxRunTime" + /> + { + // Validate name + setErrors({ + ...errors, + maxWaitTime: MaxWaitTimeError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxWaitTime']} + helperText={errors['maxWaitTime'] ?? ''} + value={props.model.maxWaitTime} + id={`${formPrefix}maxWaitTime`} + name="maxWaitTime" + /> 30) { + return trans.__('Max retry attempts must be between 1 and 30'); + } + + return ''; +} + +export function MaxRunTimeError(maxRunTime: string, trans: TranslationBundle): string { + // Check for blank + if (maxRunTime === '') { + return trans.__('You must specify max run time'); + } + + if (!validIntegerRregex.test(maxRunTime)) { + return trans.__( + 'Max run time must be an integer' + ); + } + const integerValue = +maxRunTime + // Check for length. + if (integerValue < 1) { + return trans.__('Max run time must be greater than 1'); + } + + return ''; +} + +export function MaxWaitTimeError(maxWaitTime: string, trans: TranslationBundle): string { + // Check for blank + if (maxWaitTime === '') { + return trans.__('You must specify max run time'); + } + + if (!validIntegerRregex.test(maxWaitTime)) { + return trans.__( + 'Max wait time must be an integer' + ); + } + const integerValue = +maxWaitTime + // Check for length. + if (integerValue < 1) { + return trans.__('Max wait time must be greater than 1'); + } + + return ''; +} From 6850f50a5d29905a6fcfe283d5807cdba8b9fdb3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 22:56:35 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/mainviews/create-job.tsx | 4 ++-- src/model.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainviews/create-job.tsx b/src/mainviews/create-job.tsx index 17925e830..5be2e53e0 100644 --- a/src/mainviews/create-job.tsx +++ b/src/mainviews/create-job.tsx @@ -197,7 +197,7 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { const parameterNameIdx = parameterNameMatch(target.name); const parameterValueIdx = parameterValueMatch(target.name); const newParams = props.model.parameters || []; - + if (parameterNameIdx !== null) { newParams[parameterNameIdx].name = target.value; props.handleModelChange({ ...props.model, parameters: newParams }); @@ -208,7 +208,7 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { const value = +target.value; const name = target.name; props.handleModelChange({ ...props.model, [name]: isNaN(value)? target.value: value }); - } + } }; const handleSelectChange = (event: SelectChangeEvent) => { diff --git a/src/model.ts b/src/model.ts index a88c78a9c..20d3ec933 100644 --- a/src/model.ts +++ b/src/model.ts @@ -74,9 +74,9 @@ export type ModelWithScheduleFields = { scheduleMinute: string; maxRetryAttempts: number; - + maxRunTime: number; - + maxWaitTime: number; }; From 3095ed2e961c43385552c4dff3487f53b41fabfc Mon Sep 17 00:00:00 2001 From: gautami uttarwar Date: Thu, 18 May 2023 12:40:47 -0500 Subject: [PATCH 3/4] moved retry & timeout inputs inside additional options --- src/handler.ts | 9 +++ src/mainviews/create-job.tsx | 131 +++++++++++++++++-------------- src/model.ts | 7 +- src/util/job-name-validation.tsx | 17 ++-- 4 files changed, 95 insertions(+), 69 deletions(-) diff --git a/src/handler.ts b/src/handler.ts index c852fab85..590bd483c 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -363,6 +363,9 @@ export namespace Scheduler { compute_type?: string; schedule?: string; timezone?: string; + maxRetryAttempts: number; + maxRunTime: number; + maxWaitTime: number; } export interface IUpdateJobDefinition { @@ -389,6 +392,9 @@ export namespace Scheduler { create_time: number; update_time: number; active: boolean; + maxRetryAttempts: number; + maxRunTime: number; + maxWaitTime: number; } export interface IEmailNotifications { @@ -415,6 +421,9 @@ export namespace Scheduler { output_filename_template?: string; output_formats?: string[]; compute_type?: string; + maxRetryAttempts: number; + maxRunTime: number; + maxWaitTime: number; } export interface ICreateJobFromDefinition { diff --git a/src/mainviews/create-job.tsx b/src/mainviews/create-job.tsx index 5be2e53e0..efa891b4f 100644 --- a/src/mainviews/create-job.tsx +++ b/src/mainviews/create-job.tsx @@ -205,7 +205,7 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { newParams[parameterValueIdx].value = +target.value; props.handleModelChange({ ...props.model, parameters: newParams }); } else { - const value = +target.value; + const value = parseInt(target.value); const name = target.name; props.handleModelChange({ ...props.model, [name]: isNaN(value)? target.value: value }); } @@ -308,11 +308,11 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { if (jobParameters[name] !== undefined) { console.error( 'Parameter ' + - name + - ' already set to ' + - jobParameters[name] + - ' and is about to be set again to ' + - value + name + + ' already set to ' + + jobParameters[name] + + ' and is about to be set again to ' + + value ); } else { jobParameters[name] = value; @@ -339,7 +339,10 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { compute_type: props.model.computeType, idempotency_token: props.model.idempotencyToken, tags: props.model.tags, - runtime_environment_parameters: props.model.runtimeEnvironmentParameters + runtime_environment_parameters: props.model.runtimeEnvironmentParameters, + maxRetryAttempts: props.model.maxRetryAttempts, + maxRunTime: props.model.maxRunTime, + maxWaitTime: props.model.maxWaitTime, }; if (props.model.parameters !== undefined) { @@ -384,7 +387,10 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { tags: props.model.tags, runtime_environment_parameters: props.model.runtimeEnvironmentParameters, schedule: props.model.schedule, - timezone: props.model.timezone + timezone: props.model.timezone, + maxRetryAttempts: props.model.maxRetryAttempts, + maxRunTime: props.model.maxRunTime, + maxWaitTime: props.model.maxWaitTime, }; if (props.model.parameters !== undefined) { @@ -515,57 +521,7 @@ export function CreateJob(props: ICreateJobProps): JSX.Element { environmentList={environmentList} value={props.model.environment} /> - { - // Validate name - setErrors({ - ...errors, - maxRetryAttempts: MaxRetryAttemptsError(e.target.value, trans) - }); - handleNumericInputChange(e as ChangeEvent); - }} - error={!!errors['maxRetryAttempts']} - helperText={errors['maxRetryAttempts'] ?? ''} - value={props.model.maxRetryAttempts} - id={`${formPrefix}maxRetryAttempts`} - name="maxRetryAttempts" - /> - { - // Validate name - setErrors({ - ...errors, - maxRunTime: MaxRunTimeError(e.target.value, trans) - }); - handleNumericInputChange(e as ChangeEvent); - }} - error={!!errors['maxRunTime']} - helperText={errors['maxRunTime'] ?? ''} - value={props.model.maxRunTime} - id={`${formPrefix}maxRunTime`} - name="maxRunTime" - /> - { - // Validate name - setErrors({ - ...errors, - maxWaitTime: MaxWaitTimeError(e.target.value, trans) - }); - handleNumericInputChange(e as ChangeEvent); - }} - error={!!errors['maxWaitTime']} - helperText={errors['maxWaitTime'] ?? ''} - value={props.model.maxWaitTime} - id={`${formPrefix}maxWaitTime`} - name="maxWaitTime" - /> + +
+ { + // Validate name + setErrors({ + ...errors, + maxRetryAttempts: MaxRetryAttemptsError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxRetryAttempts']} + helperText={errors['maxRetryAttempts'] ?? ''} + value={props.model.maxRetryAttempts} + id={`${formPrefix}maxRetryAttempts`} + name="maxRetryAttempts" + /> +
+
+ { + // Validate name + setErrors({ + ...errors, + maxRunTime: MaxRunTimeError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxRunTime']} + helperText={errors['maxRunTime'] ?? ''} + value={props.model.maxRunTime} + id={`${formPrefix}maxRunTime`} + name="maxRunTime" + /> +
+
+ { + // Validate name + setErrors({ + ...errors, + maxWaitTime: MaxWaitTimeError(e.target.value, trans) + }); + handleNumericInputChange(e as ChangeEvent); + }} + error={!!errors['maxWaitTime']} + helperText={errors['maxWaitTime'] ?? ''} + value={props.model.maxWaitTime} + id={`${formPrefix}maxWaitTime`} + name="maxWaitTime" + /> +
30) { return trans.__('Max retry attempts must be between 1 and 30'); @@ -92,12 +92,13 @@ export function MaxRunTimeError(maxRunTime: string, trans: TranslationBundle): s return trans.__('You must specify max run time'); } - if (!validIntegerRregex.test(maxRunTime)) { + const integerValue = parseInt(maxRunTime) + if (isNaN(integerValue)) { return trans.__( 'Max run time must be an integer' ); } - const integerValue = +maxRunTime + // Check for length. if (integerValue < 1) { return trans.__('Max run time must be greater than 1'); @@ -111,13 +112,13 @@ export function MaxWaitTimeError(maxWaitTime: string, trans: TranslationBundle): if (maxWaitTime === '') { return trans.__('You must specify max run time'); } - - if (!validIntegerRregex.test(maxWaitTime)) { + const integerValue = parseInt(maxWaitTime) + if (isNaN(integerValue)) { return trans.__( 'Max wait time must be an integer' ); } - const integerValue = +maxWaitTime + // Check for length. if (integerValue < 1) { return trans.__('Max wait time must be greater than 1'); From 144b82c8b86b78752b05b8c15aaa99d728f1b103 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 17:41:00 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/util/job-name-validation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/job-name-validation.tsx b/src/util/job-name-validation.tsx index 58b4b9434..0fcbfb1c9 100644 --- a/src/util/job-name-validation.tsx +++ b/src/util/job-name-validation.tsx @@ -118,7 +118,7 @@ export function MaxWaitTimeError(maxWaitTime: string, trans: TranslationBundle): 'Max wait time must be an integer' ); } - + // Check for length. if (integerValue < 1) { return trans.__('Max wait time must be greater than 1');