2016-07-18 3 views
2

Небольшой проект железной дороги вызывает Command в некотором маршруте и возвращает Response. Вот соответствующий код функции обработчика маршрута:Как избежать процессов зомби при запуске команды?

fn convert(req: &mut Request) -> IronResult<Response> { 

    // ... 
    // init some bindings like destination_html and destination_pdf 
    // ... 

    convert_to_pdf(destination_html, destination_pdf); 

    Ok(Response::with((status::Ok, "Done"))) 
} 

И код вызываемой функции:

fn convert_to_pdf(destination_html: &str, destination_pdf: &str) { 
    Command::new("xvfb-run") 
     .arg("-a") 
     .arg("wkhtmltopdf") 
     .arg(destination_html) 
     .arg(destination_pdf) 
     .stdout(Stdio::null()) 
     .stderr(Stdio::null()) 
     .spawn() 
     .expect("failed to execute process"); 
} 

Процесс работает (файл преобразуется из HTML в PDF) и ответ вернулся в браузер. Все это хорошо, но процесс зомби все еще там, как ребенок моего приложения:

enter image description here

Я не знаю, почему и я не знаю, как избежать этого. Что мне делать?

Команда wkhtmltopdf - это долгий процесс, я не хочу называть его синхронно и ждать его возвращения. И я не хочу перезапускать мою программу Rust (родителя ребенка-зомби) два раза в день, чтобы убить зомби.

+0

Не ответ на ваш вопрос, но я начал работать с привязками wkhtmltopdf к C-lib, где нереста отдельного процесса вообще не понадобится. Не готово к производству, но вы можете найти доказательство концепции здесь: https://github.com/anowell/wkhtmltopdf-rs – anowell

+0

Хорошо! Я посмотрю и, возможно, буду использовать его для этого проекта! –

ответ

1

Ваша проблема в том, что вы не ожидаете завершения процесса, поэтому операционная система не освобождает ресурсы (см. man pages for proper explanation). Ваши зомби берут память, что приведет к истощению ресурсов. Убийство родительского процесса ничего не сделает, вам нужно убить каждого зомби вручную (если вы используете wkhtmltopdf в потоке, он будет работать).


За что ...

Вы пытаетесь нерест команду и ответить на ваши клиенты ... даже не проверяя код состояния wkhtmltopdf. Более того, вы работаете как root, что является ПЛОЩАДЕЙ ПРАКТИКОЙ (независимо от того, развиваетесь ли вы как root или нет). И ваше приложение восприимчиво к DDoS (если у вас много клиентов, создающих PDF-файлы, ваш сервер столкнется с исчерпанием ресурсов).

(ИМХО) Вы должны разбить проект на две частях:

  1. сервер без процесса визуализации
  2. Ф движка рендеринга

Первого будет отправить сообщение на второй " создайте PDF со следующими параметрами (..) ». Второй будет смотреть на очередь сообщений, взять первый, сгенерировать PDF и дождаться завершения/ошибок. Вы даже можете добавить в сообщение уникальный #ID и создать конечную точку в механизме рендеринга для фактического запроса статуса #ID задания.

Что вы пытаетесь сделать, это очередь заданий, например, Celery, но она написана на Python и использует стороннее программное обеспечение (Redis).

+2

Хорошо, мой вопрос не в том, «как сделать мой веб-сервис», но «Как избежать процесса зомби в команде Rust Iron running». В любом случае, спасибо за ваш ответ. PDF, корень и дизайн не важны. Мой настоящий вопрос касается команды Rust, Iron и обработки вывода, вы отвечаете за дизайн приложения. –

+0

Я ответил во втором абзаце. Вы должны подождать детского процесса. –

+0

Хорошо, спасибо! Я не хочу делать это синхронно и ждать (это цель икры). –

Смежные вопросы