기술적으로 다른 비동기 파이썬 하위 프로세스를 생성하는 파이썬 하위 프로세스를 생성하지만 제목이 이미 길었습니다. Node/ExpressJS는 첫 번째 Python 하위 프로세스가 성공적으로 실행되었는지 확인하기 위해 대기해야하지만 하위 프로세스는 완료되지 않으므로 완료하는 데 몇 분이 걸릴 수 있습니다. 그러나 겉보기에 올바른 설정을 했음에도 불구하고 브라우저를 통해 API 요청을하면 하위 프로세스의 하위 프로세스를 기다리는 중 끊어지는 것처럼 보입니다.비동기 파이썬 하위 프로세스를 생성하는 노드/익스프레스 API 만들기
는 배경 :는
여기에 기본 목표는 다음 출력을 얻을 모델을 실행하는 데 사용할 수있는 노드/ExpressJS 기반 API를 만드는 것입니다. 모델을 실행하는 데 몇 분이 걸릴 수 있으므로 한 번의 API 요청으로 응답을 기다리는 대신 내 전략은 요청을 두 개로 분할하는 것입니다. 하나는 모델을 준비/실행하고 두 번째는 결과를 검색하는 것입니다.
prep 통화는 모델을 시작하고 userid에 의한 점검 등을 통해 언제든지 한 모델에 대해서만 실행이 활성화되도록 할 수 있습니다. 모델 실행이 성공적으로 시작되었거나 현재 실행 중이므로 새 실행을 시작할 수 없다는 메시지를 반환합니다.
검색 호출은 데이터 검색을 시도합니다. 출력이 계속 실행 중임을 나타내는 메시지, 실행이 실패한 경우 오류 또는 모델 실행이 완료되면 통계와 숫자 및 기타 등등을 반환 할 수 있습니다.
문제 :
문제는 준비 통화에 있습니다. Node/Express는 prep.py 스크립트를 호출합니다. prep.py 스크립트는 다른 하위 프로세스 (run.py)를 생성하지만 Node/Express 또는 prep.py는 해당 하위 프로세스가 완료 될 때까지 대기하지 않아야합니다. 그렇지 않으면 REST API를 호출하면 모델이 완료 될 때까지 기다릴 수 있습니다.
sp = subprocess.Popen([
"python",
os.path.join(this_dir, "run.py"),
userid,
processid
])
print json.dumps({'response': 'success'})
# end of script
명령 행 (즉, CMD)를 통해이 실행이 잘 작동 다음과 같이
그래서이 파이썬에서 수행되는 방식이다. 나는 prep.py를 호출하고 즉시 JSON을 덤프하고 CMD는 다른 입력/명령에 대한 준비가되었습니다. 작업 관리자에서 파이썬이 백그라운드에서 실행되고 결국 모델 출력 파일이 필요할 때 나타납니다.
그러나 브라우저를 통해 Node/ExpressJS를 통해 호출 할 때 API는 run.py가 완료 될 때까지 기다리는 것처럼 계속 작동합니다. (결과적으로 타임 아웃되고 브라우저가 자동으로 새로 고쳐지고 페이지에 "오류가 발생했습니다. 모델이 이미 실행 중입니다."- 스팸 방지 모델 작업을 방지하기위한 장애 조치 작업을 확인하는 것이 좋습니다.)
여기 API의 준비 호출이되는 통해 경로입니다 :
router.route('/prep/:userid/:key')
.get(throttle(tOptions), function(req, res, next) {
var error = null;
RunPy(
// path to script
path.join(process.env.PYSCRIPTDIR, "prep.py"),
// parameters/arguments
[req.params.userid, req.params.key],
// on complete callback
function(ret) {
if(error) {
next({message: error});
} else {
res.send(ret);
}
},
// on error callback
function(err) { error = getPythonError(err); }
);
});
RunPy 단지 파이썬 하위 프로세스 실행 할 수있는 편리한 래퍼 인 :
const spawn = require("child_process").spawn;
module.exports = function(pyPath, args, onComplete, onError, onData) {
var py = spawn('python', [pyPath].concat(args));
var ret = "";
py.stdout.on('data', function(data) {
ret += data.toString();
if(onData) onData(data.toString());
});
py.stderr.on('data', function(data) {
onError(data.toString());
});
py.stdout.on('end', function() {
onComplete(ret);
})
};
나는 아마 파이썬 스크립트를 보장 할 수 만 출력 번 에 대한 완전한 콜백 발사가 있습니다. 첫 번째 py.stdout.on('data', ..)
하지만 그게 멋져 보이지 않고 몇 분이 걸리는이 python 스크립트를 기다리는 매달려있는 자바 스크립트 스레드를 그냥 놓는 아이디어가 마음에 들지 않습니다.
subprocess.Popen의 작동 방식을 잘못 이해했을 수도 있지만 호출 한 스크립트가 대기 할 필요가없는 비동기 프로세스가 발생한다고 생각했습니다. 적어도 CMD에서이를 실행하면 { "response": "success"} (Express가 반환해야하는 것)을 인쇄하고 새 명령에 대한 터미널을 즉시 재설정합니다. [아, 오타가 있었는데 원래의 게시물에 "인쇄"명령을 추가했습니다] – wowohweewah