2010-01-20 3 views
7

CSV 파일의 일부 데이터를 처리하는 파이썬 스크립트를 작성했습니다. 스크립트는 CSV의 크기에 따라 완료하는 데 3 ~ 30 분이 걸립니다.스크립트 실행에 30 분이 걸리는 웹 인터페이스 만들기

이제는 웹 인터페이스를 사용하고 싶으므로 어느 곳에서나 CSV 데이터 파일을 업로드 할 수 있습니다. 기본 HTTP POST 업로드 페이지를 작성하고 Python의 CGI 모듈을 사용했지만 스크립트가 잠시 후에 시간 초과되었습니다.

스크립트는 시작시 HTTP 헤더를 출력하고 CSV의 모든 행을 반복하여 데이터 비트를 출력합니다. 예를 들어,이 print 문은 30 초마다 트리거됩니다.

# at the very top, with the 'import's 
print "Content-type: text/html\n\n Processing ... <br />" 

# the really long loop. 
for currentRecord in csvRecords: 
    count = count + 1 
    print "On line " + str(count) + " <br />" 

나는 브라우저가 헤더를 수신하고 약간의 데이터 비트를 수신 할 때까지 기다릴 것이라고 가정했습니다. 실제로 실제로는 어떤 데이터도 수신되지 않으며 많은 행이있는 CSV가 제공되면 Error 504 시간이 초과됩니다.

아마도 어딘가에 캐싱이 발생 했나요? 로그에서

[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm 
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm 

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 아니면 브라우저에서 이러한 스크립트를 실행하는 것이 적절하지 않습니까?

편집 : 이 내 자신의 사용을위한 스크립트입니다 - 나는 일반적으로 내 컴퓨터에 사용하려는, 그러나 나는 웹 기반 인터페이스를 여행하는 동안 편리하게, 또는 휴대 전화에서, 예를 들어 수 있다고 생각. 또한 실제로 다운로드 할 것이 없습니다. 스크립트는 결국 보고서를 전자 메일로 보냅니다.

+3

당신은이 지구상의 환자가 데이터로 다운로드하는 대신 브라우저에서 웹 페이지를로드하는 데 30 분을 충분히 대기한다고 생각하십니까? – YOU

+0

이것은 내 자신을위한 스크립트입니다. 저는 보통 내 컴퓨터에서이 스크립트를 사용하려고 합니다만, 여행 중 또는 웹에서 인터페이스를 사용하는 것이 편리 할 수 ​​있다고 생각했습니다. 또한 실제로 다운로드 할 것이 없습니다. 스크립트는 결국 보고서를 전자 메일로 보냅니다. – Pranab

+0

@Pranab : "이것은 내 사용을위한 스크립트입니다." 그렇다면 어떤 문제가 있습니까? 왜 그냥 달아나지 않는거야? 왜 엉망이 되니? 그것이 당신을위한 것이라면 - 그것은 단지 이메일을 보냅니다 - 그것은 심지어 웹 페이지가 아닙니다. 왜 간단한 파이썬 스크립트를 작성하지 않는가? –

답변

12

나는이 같은 일을 분리하는 것 :

  1. 게시 된 CSV 파일을 받아 웹 응용 프로그램의 URL입니다. 웹 앱은 오프라인 테이블 (예 : 데이터베이스 테이블)에 CSV 콘텐츠를 저장합니다. 웹 응용 프로그램의 응답은 대기중인 항목의 고유 ID 여야합니다 (예 : 자동 증가 ID 열 사용). 클라이언트는 파트 3에 대해이 ID를 저장해야합니다.

  2. 대기열을 폴링하여 작업을 처리하는 독립형 서비스 앱. 처리가 완료되면 고유 ID를 키로 사용하여 다른 데이터베이스 테이블에 결과를 저장하십시오.

  3. 처리 결과를 얻을 수있는 웹 앱 URL은 http://server/getresults/uniqueid/입니다. 처리가 완료되면 (즉, 고유 ID가 결과 데이터베이스 테이블에서 발견 된 경우) 결과를 리턴하십시오. 완료되지 않은 경우 응답은이를 나타내는 코드 여야합니다. 예를 들어, 사용자 정의 HTTP 헤더, HTTP 상태 응답, 응답 본문 'PENDING'또는 유사합니다.

5

나는 전에 이런 상황에 처해 있었고 나는 cronjob을 사용했다. HTTP 스크립트는 수행 할 작업 (DB 또는 디렉토리의 파일)을 대기열에 기록하기 만하면 cronjob이 해당 작업을 읽고 실행합니다.

+0

+1; 사용자는 작업이 끝나면 이메일을 통해 알림을받을 수 있습니다. –

+0

cronjob을 파일로 주기적으로 작성하고 ajax를 사용하여 웹 서버에서 값을 읽은 다음 브라우저에서 사용자에게 표시 할 수도 있습니다 . – sharjeel

+0

작업 프로세스가 다른 사용자로 실행해야하는 경우 cronjob을 사용하는 것이 좋습니다. 그렇지 않으면 대개 CGI 앱에서 직접 처리 스레드를 시작하는 것만 큼 쉽습니다. – Wim

1

imho 가장 좋은 방법은 플랫 파일, 데이터베이스 등 어딘가에 업데이트를 게시하는 독립 스크립트를 실행하는 것입니다. 파이썬에서 독립적 인 프로세스를 포크하는 법을 모르므로 코드 예제를 제공 할 수 없습니다.

웹 사이트의 진행 상황을 표시하려면 해당 상태 업데이트를 읽는 페이지에 대한 ajax 요청을 구현해야합니다. 예를 들어 좋은 진행률 표시 줄을 보여줍니다.

의 setTimeout 같은 추가 ("refreshProgressBar [...]) 또는 자동 새로 고침에 대한 메타 새로 고침.

4

을 스크립트가 정말 아직 아무것도 작성하지 않는 한 당신은 아마하는 stdout.flush()을 수행해야합니다 페이지 버퍼의 값을 쓸 때까지는 웹 서버에 보내지 말아야한다 .-

그러나 이것을 해결할 수있는 적절한 방법은 다른 스레드와 마찬가지로 별도의 스레드/진행률 막대 또는 지루함을 방지하기위한 다른 멋진 비주얼을 사용하여 상태를 보여주는 자동 새로 고침 페이지를 사용자에게 표시하십시오.

+0

루프에서 print 문 바로 뒤에 sys.stdout.flush()를 추가하면 문제가 해결되는 것 같습니다. – Pranab

2

매우 비슷한 질문 here. 나는 오랜 프로세스를 시작하고 ajax 기반의 진행률 표시 줄을 사용자에게 반환하는 것이 좋습니다. 이러한 방식으로 사용자는 웹 인터페이스의 고급 스러움을 누릴 수 있으며 타임 아웃이 없어도 고급 스러움을 누릴 수 있습니다.

관련 문제