调试脚本增加停止,修复调试交互

This commit is contained in:
whyour 2021-12-23 23:25:39 +08:00
parent a29392bb08
commit 2e6ca5419d
4 changed files with 87 additions and 12 deletions

View File

@ -266,4 +266,30 @@ export default (app: Router) => {
} }
}, },
); );
route.put(
'/stop',
celebrate({
body: Joi.object({
filename: Joi.string().required(),
path: Joi.string().optional().allow(''),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
let { filename, path } = req.body as {
filename: string;
path: string;
};
const filePath = join(path, filename);
const scriptService = Container.get(ScriptService);
const result = await scriptService.stopScript(filePath);
res.send(result);
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
}; };

View File

@ -241,7 +241,7 @@ export default class CronService {
}); });
} }
private async killTask(name: string) { public async killTask(name: string) {
let taskCommand = `ps -ef | grep "${name}" | grep -v grep | awk '{print $1}'`; let taskCommand = `ps -ef | grep "${name}" | grep -v grep | awk '{print $1}'`;
const execAsync = promisify(exec); const execAsync = promisify(exec);
try { try {

View File

@ -2,21 +2,19 @@ import { Service, Inject } from 'typedi';
import winston from 'winston'; import winston from 'winston';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import SockService from './sock'; import SockService from './sock';
import CronService from './cron';
@Service() @Service()
export default class ScriptService { export default class ScriptService {
constructor( constructor(
@Inject('logger') private logger: winston.Logger, @Inject('logger') private logger: winston.Logger,
private sockService: SockService, private sockService: SockService,
private cronService: CronService,
) {} ) {}
public async runScript(path: string) { public async runScript(path: string) {
const cp = spawn(`task -l ${path} now`, { shell: '/bin/bash' }); const cp = spawn(`task -l ${path} now`, { shell: '/bin/bash' });
this.sockService.sendMessage({
type: 'manuallyRunScript',
message: `开始执行脚本`,
});
cp.stdout.on('data', (data) => { cp.stdout.on('data', (data) => {
this.sockService.sendMessage({ this.sockService.sendMessage({
type: 'manuallyRunScript', type: 'manuallyRunScript',
@ -38,6 +36,26 @@ export default class ScriptService {
}); });
}); });
cp.on('close', (err) => {
this.sockService.sendMessage({
type: 'manuallyRunScript',
message: `执行结束`,
});
});
return { code: 200 };
}
public async stopScript(path: string) {
const err = await this.cronService.killTask(`task -l ${path} now`);
const str = err ? `\n${err}` : '';
this.sockService.sendMessage({
type: 'manuallyRunScript',
message: `${str}\n## 执行结束... ${new Date()
.toLocaleString('zh', { hour12: false })
.replace(' 24:', ' 00:')} `,
});
return { code: 200 }; return { code: 200 };
} }
} }

View File

@ -47,6 +47,7 @@ const EditModal = ({
const [log, setLog] = useState<string>(''); const [log, setLog] = useState<string>('');
const { theme } = useTheme(); const { theme } = useTheme();
const editorRef = useRef<any>(null); const editorRef = useRef<any>(null);
const [isRunning, setIsRunning] = useState(false);
const cancel = () => { const cancel = () => {
handleCancel(); handleCancel();
@ -80,7 +81,22 @@ const EditModal = ({
path: cNode.parent || '', path: cNode.parent || '',
}, },
}) })
.then((data) => {}); .then((data) => {
setIsRunning(true);
});
};
const stop = () => {
request
.put(`${config.apiPrefix}scripts/stop`, {
data: {
filename: cNode.value,
path: cNode.parent || '',
},
})
.then((data) => {
setIsRunning(false);
});
}; };
useEffect(() => { useEffect(() => {
@ -94,6 +110,13 @@ const EditModal = ({
return; return;
} }
if (_message === '执行结束') {
_message = '';
setTimeout(() => {
setIsRunning(false);
}, 300);
}
if (log) { if (log) {
_message = `\n${_message}`; _message = `\n${_message}`;
} }
@ -135,8 +158,12 @@ const EditModal = ({
<Option value="shell">shell</Option> <Option value="shell">shell</Option>
<Option value="python">python</Option> <Option value="python">python</Option>
</Select> </Select>
<Button type="primary" style={{ marginRight: 8 }} onClick={run}> <Button
type="primary"
style={{ marginRight: 8 }}
onClick={isRunning ? stop : run}
>
{isRunning ? '停止' : '运行'}
</Button> </Button>
<Button <Button
type="primary" type="primary"
@ -169,6 +196,7 @@ const EditModal = ({
type="primary" type="primary"
style={{ marginRight: 8 }} style={{ marginRight: 8 }}
onClick={() => { onClick={() => {
stop();
handleCancel(); handleCancel();
}} }}
> >
@ -181,7 +209,12 @@ const EditModal = ({
onClose={cancel} onClose={cancel}
visible={visible} visible={visible}
> >
<SplitPane split="vertical" minSize={200} defaultSize="50%"> <SplitPane
split="vertical"
minSize={200}
defaultSize="50%"
style={{ height: 'calc(100vh - 55px)' }}
>
<Editor <Editor
language={language} language={language}
value={value} value={value}
@ -196,9 +229,7 @@ const EditModal = ({
editorRef.current = editor; editorRef.current = editor;
}} }}
/> />
<div> <pre style={{ height: '100%', whiteSpace: 'break-spaces' }}>{log}</pre>
<pre>{log}</pre>
</div>
</SplitPane> </SplitPane>
<SaveModal <SaveModal
visible={saveModalVisible} visible={saveModalVisible}