1. Stop process of Process details dialog not working.

2. When a server of an in progress cloud deployment is expanded, it is throwing a failed error.
3. Close the process notification on clicking View Processes.

Fixes #3709
pull/90/head
Aditya Toshniwal 2022-08-16 17:58:02 +05:30 committed by Akshay Joshi
parent ef91207669
commit b12c1f8740
7 changed files with 32 additions and 11 deletions

View File

@ -133,6 +133,7 @@ def register_browser_preferences(self):
self.table_row_count_threshold = self.preference.register( self.table_row_count_threshold = self.preference.register(
'processes', 'process_retain_days', 'processes', 'process_retain_days',
gettext("Process details/logs retention days"), 'integer', 5, gettext("Process details/logs retention days"), 'integer', 5,
min_val=1,
category_label=gettext('Processes'), category_label=gettext('Processes'),
help_str=gettext( help_str=gettext(
'After this many days, the process info and logs ' 'After this many days, the process info and logs '

View File

@ -545,7 +545,8 @@ class BatchProcess(object):
cloud_instance['instance']['status'] = True cloud_instance['instance']['status'] = True
cloud_instance['instance']['pid'] = _pid cloud_instance['instance']['pid'] = _pid
return update_server(cloud_instance) return update_server(cloud_instance)
elif err_completed and _process.exit_code > 0: elif err_completed and _process.exit_code is not None and \
_process.exit_code > 0:
cloud_instance = {'instance': {}} cloud_instance = {'instance': {}}
cloud_instance['instance']['sid'] = _process.server_id cloud_instance['instance']['sid'] = _process.server_id
cloud_instance['instance']['status'] = False cloud_instance['instance']['status'] = False

View File

@ -140,7 +140,7 @@ export default class BgProcessManager {
stopProcess(jobId) { stopProcess(jobId) {
this.procList.find((p)=>p.id == jobId).process_state = BgProcessManagerProcessState.PROCESS_TERMINATING; this.procList.find((p)=>p.id == jobId).process_state = BgProcessManagerProcessState.PROCESS_TERMINATING;
this._eventManager.fireEvent(BgProcessManagerEvents.LIST_UPDATED); this._eventManager.fireEvent(BgProcessManagerEvents.LIST_UPDATED);
this.api.put(url_for('bgprocess.stop_process', { return this.api.put(url_for('bgprocess.stop_process', {
pid: jobId, pid: jobId,
})) }))
.then(()=>{ .then(()=>{

View File

@ -56,7 +56,10 @@ function ProcessNotifyMessage({title, desc, onClose, onViewProcess, success=true
<Box className={classes.containerBody}> <Box className={classes.containerBody}>
<Box>{desc}</Box> <Box>{desc}</Box>
<Box marginTop={'1rem'} display="flex"> <Box marginTop={'1rem'} display="flex">
<DefaultButton startIcon={<DescriptionOutlinedIcon />} onClick={onViewProcess}>View Processes</DefaultButton> <DefaultButton startIcon={<DescriptionOutlinedIcon />} onClick={()=>{
onViewProcess();
onClose();
}}>View Processes</DefaultButton>
</Box> </Box>
</Box> </Box>
</Box> </Box>

View File

@ -86,15 +86,23 @@ export default function ProcessDetails({data}) {
const [[outPos, errPos], setOutErrPos] = useState([0, 0]); const [[outPos, errPos], setOutErrPos] = useState([0, 0]);
const [exitCode, setExitCode] = useState(data.exit_code); const [exitCode, setExitCode] = useState(data.exit_code);
const [timeTaken, setTimeTaken] = useState(data.execution_time); const [timeTaken, setTimeTaken] = useState(data.execution_time);
const [stopping, setStopping] = useState(false);
let notifyType = MESSAGE_TYPE.INFO; let notifyType = MESSAGE_TYPE.INFO;
let notifyText = gettext('Not started'); let notifyText = gettext('Not started');
const process_state = pgAdmin.Browser.BgProcessManager.evaluateProcessState({ let process_state = pgAdmin.Browser.BgProcessManager.evaluateProcessState({
...data, ...data,
exit_code: exitCode, exit_code: exitCode,
}); });
if(process_state == BgProcessManagerProcessState.PROCESS_STARTED && stopping) {
process_state = BgProcessManagerProcessState.PROCESS_TERMINATING;
}
if(process_state == BgProcessManagerProcessState.PROCESS_FAILED && stopping) {
process_state = BgProcessManagerProcessState.PROCESS_TERMINATED;
}
if(process_state == BgProcessManagerProcessState.PROCESS_STARTED) { if(process_state == BgProcessManagerProcessState.PROCESS_STARTED) {
notifyText = gettext('Running...'); notifyText = gettext('Running...');
} else if(process_state == BgProcessManagerProcessState.PROCESS_FINISHED) { } else if(process_state == BgProcessManagerProcessState.PROCESS_FINISHED) {
@ -133,6 +141,11 @@ export default function ProcessDetails({data}) {
}, completed ? -1 : 1000); }, completed ? -1 : 1000);
const onStopProcess = ()=>{
setStopping(true);
pgAdmin.Browser.BgProcessManager.stopProcess(data.id);
};
const errRe = new RegExp(': (' + gettext('error') + '|' + gettext('fatal') + '):', 'i'); const errRe = new RegExp(': (' + gettext('error') + '|' + gettext('fatal') + '):', 'i');
return ( return (
<Box display="flex" flexDirection="column" className={classes.container} data-test="process-details"> <Box display="flex" flexDirection="column" className={classes.container} data-test="process-details">
@ -153,7 +166,10 @@ export default function ProcessDetails({data}) {
pgAdmin.Tools.FileManager.openStorageManager(data.current_storage_dir); pgAdmin.Tools.FileManager.openStorageManager(data.current_storage_dir);
}} style={{marginRight: '4px'}} />} }} style={{marginRight: '4px'}} />}
<DefaultButton disabled={process_state != BgProcessManagerProcessState.PROCESS_STARTED || data.server_id != null} <DefaultButton disabled={process_state != BgProcessManagerProcessState.PROCESS_STARTED || data.server_id != null}
startIcon={<HighlightOffRoundedIcon />} className={classes.terminateBtn}>Stop Process</DefaultButton></Box> startIcon={<HighlightOffRoundedIcon />} className={classes.terminateBtn} onClick={onStopProcess}>
Stop Process
</DefaultButton>
</Box>
</Box> </Box>
<Box flexGrow={1} className={classes.logs}> <Box flexGrow={1} className={classes.logs}>
{logs == null && <span data-test="loading-logs">{gettext('Loading process logs...')}</span>} {logs == null && <span data-test="loading-logs">{gettext('Loading process logs...')}</span>}

View File

@ -218,7 +218,7 @@ export default function Processes() {
}, },
}, },
{ {
Header: gettext('Time Taken'), Header: gettext('Time Taken (sec)'),
accessor: 'execution_time', accessor: 'execution_time',
sortable: true, sortable: true,
resizable: true, resizable: true,

View File

@ -40,8 +40,8 @@ const useStyles = makeStyles((theme)=>({
height: 'unset', height: 'unset',
}, },
errorMargin: { errorMargin: {
/* Error footer margin */ /* Error footer space */
marginBottom: '36px', paddingBottom: '36px',
}, },
sqlTabInput: { sqlTabInput: {
border: 0, border: 0,
@ -382,13 +382,13 @@ export default function FormView({
</Tabs> </Tabs>
</Box> </Box>
{Object.keys(finalTabs).map((tabName, i)=>{ {Object.keys(finalTabs).map((tabName, i)=>{
let contentClassName = null; let contentClassName = [stateUtils.formErr.message ? classes.errorMargin : null];
if(fullTabs.indexOf(tabName) == -1) { if(fullTabs.indexOf(tabName) == -1) {
contentClassName = clsx(classes.nestedControl, stateUtils.formErr.message ? classes.errorMargin : null); contentClassName.push(classes.nestedControl);
} }
return ( return (
<TabPanel key={tabName} value={tabValue} index={i} classNameRoot={clsx(tabsClassname[tabName], isNested ? classes.nestedTabPanel : null)} <TabPanel key={tabName} value={tabValue} index={i} classNameRoot={clsx(tabsClassname[tabName], isNested ? classes.nestedTabPanel : null)}
className={contentClassName}> className={clsx(contentClassName)}>
{finalTabs[tabName]} {finalTabs[tabName]}
</TabPanel> </TabPanel>
); );