2010-01-20 24 views
7

Tôi đã viết một tập lệnh python để xử lý một số dữ liệu từ các tệp CSV. Tập lệnh mất từ ​​3 đến 30 phút để hoàn thành, tùy thuộc vào kích thước của CSV.Tạo giao diện web cho tập lệnh mất 30 phút để thực thi

Bây giờ tôi muốn đưa vào giao diện web với điều này, vì vậy tôi có thể tải lên tệp dữ liệu CSV từ bất kỳ đâu. Tôi đã viết một trang tải lên HTTP POST cơ bản và sử dụng mô-đun CGI của Python - nhưng tập lệnh chỉ hết thời gian sau một thời gian.

Tập lệnh sẽ xuất ra các tiêu đề HTTP ngay từ đầu và xuất ra các bit dữ liệu sau khi lặp qua tất cả các dòng của CSV. Ví dụ, câu lệnh in này sẽ kích hoạt sau mỗi 30 giây.

# 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 />" 

Tôi giả định trình duyệt sẽ nhận được tiêu đề và chờ vì nó tiếp tục nhận được một chút dữ liệu. Nhưng những gì thực sự dường như xảy ra là nó không nhận được bất kỳ dữ liệu nào cả, và Error 504 lần ra khi đưa ra một CSV với nhiều dòng.

Có thể có một số bộ nhớ đệm xảy ra ở đâu đó? Từ nhật ký,

[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 

Cách tốt nhất để giải quyết vấn đề này là gì, hoặc không thích hợp để chạy các tập lệnh như vậy trong trình duyệt?

Edit: Đây là một kịch bản để sử dụng riêng của tôi - Tôi thường có ý định sử dụng nó trên máy tính của tôi, nhưng tôi nghĩ một giao diện dựa trên web có thể có ích khi đi du lịch, hoặc ví dụ từ một chiếc điện thoại. Ngoài ra, thực sự không có gì để tải xuống - kịch bản hầu hết có thể sẽ gửi báo cáo ở cuối email.

+3

Bạn có nghĩ rằng bất kỳ ai trên trái đất này đủ kiên nhẫn chờ 30 phút để tải trang web trong trình duyệt, thay vì tải xuống dưới dạng dữ liệu? – YOU

+0

Đây là tập lệnh để tôi sử dụng - tôi thường có ý định sử dụng nó trên máy tính của mình, nhưng tôi nghĩ giao diện dựa trên web có thể hữu ích khi di chuyển hoặc ví dụ từ điện thoại. Ngoài ra, thực sự không có gì để tải xuống - kịch bản sẽ gửi báo cáo qua email ở cuối. – Pranab

+0

@Pranab: "Đây là tập lệnh để tôi sử dụng." Vậy bạn có vấn đề gì? Tại sao không chỉ để nó chạy? Tại sao lộn xộn xung quanh? Nếu nó dành cho bạn - và nó chỉ gửi một email - nó thậm chí không phải là một trang web? Tại sao không chỉ viết một kịch bản Python đơn giản? –

Trả lời

12

Tôi sẽ tách công việc như thế này:

  1. URL ứng dụng web chấp nhận tệp CSV đã đăng. Ứng dụng web đặt nội dung CSV vào hàng đợi ngoại tuyến, ví dụ: bảng cơ sở dữ liệu. Phản hồi của ứng dụng web phải là một ID duy nhất cho mục được xếp hàng đợi (ví dụ: sử dụng cột ID tăng tự động). Khách hàng phải lưu trữ ID này cho phần 3.

  2. Ứng dụng dịch vụ độc lập kiểm tra hàng đợi công việc và thực hiện quá trình xử lý. Sau khi hoàn thành quá trình xử lý, lưu trữ các kết quả trong một bảng cơ sở dữ liệu khác, sử dụng ID duy nhất làm khóa.

  3. URL ứng dụng web có thể nhận kết quả được xử lý, http://server/getresults/uniqueid/. Nếu quá trình xử lý kết thúc (tức là ID duy nhất được tìm thấy trong bảng cơ sở dữ liệu kết quả), sau đó trả lại kết quả. Nếu không hoàn thành, phản hồi phải là mã chỉ ra điều này. Ví dụ: tiêu đề HTTP tùy chỉnh, phản hồi trạng thái HTTP, nội dung phản hồi 'ĐANG CHỜ' hoặc tương tự.

5

Tôi đã có tình huống này trước đây và tôi đã sử dụng cronjobs. Tập lệnh HTTP sẽ chỉ viết trong hàng đợi một công việc được thực hiện (một DB hoặc một tệp trong một thư mục) và cronjob sẽ đọc nó và thực hiện công việc đó.

+0

+1; Người dùng có thể được thông báo qua email khi công việc của mình kết thúc, với liên kết để tải xuống nó –

+0

Bạn cũng có thể làm cho cronjob ghi tiến trình của nó định kỳ trong một tệp và sử dụng ajax để đọc giá trị từ máy chủ web và hiển thị nó cho người dùng trong trình duyệt của mình . – sharjeel

+0

Nếu bạn cần quy trình công việc để chạy với tư cách người dùng khác, sử dụng cronjob chắc chắn là một cách tốt. Khác, nó thường chỉ là dễ dàng để chỉ bắt đầu xử lý thread trực tiếp từ ứng dụng CGI. – Wim

1

imho cách tốt nhất là chạy một tập lệnh độc lập cập nhật ở đâu đó (tệp phẳng, cơ sở dữ liệu, v.v ...). Tôi không biết làm thế nào để ngã ba một quá trình độc lập từ python vì vậy tôi không thể đưa ra bất kỳ ví dụ mã.

Để hiển thị tiến trình trên WebSite, hãy thực hiện yêu cầu ajax đến trang đọc các cập nhật trạng thái đó và ví dụ hiển thị thanh tiến trình tốt đẹp.

Thêm một cái gì đó giống như setTimeout ("refreshProgressBar [...]) hoặc meta refresh để tự động refresh.

4

Có thể bạn sẽ cần phải làm một stdout.flush(), như kịch bản là không thực sự viết bất cứ điều gì chưa tới máy chủ web cho đến khi bạn ghi dữ liệu của bộ đệm trang - điều này không xảy ra trước khi hết thời gian chờ.

Nhưng cách thích hợp để giải quyết vấn đề này là những người khác đã đề xuất, xử lý trong một chuỗi riêng biệt/xử lý và hiển thị cho người dùng trang được làm mới tự động hiển thị trạng thái, với thanh tiến trình hoặc một số hình ảnh ưa thích khác để giữ cho chúng không bị nhàm chán.

+0

Thêm sys.stdout.flush() ngay sau khi một câu lệnh in trong vòng lặp dường như giải quyết được vấn đề. – Pranab

2

Câu hỏi tương tự here. Tôi đề nghị sinh ra quá trình dài dòng và trả về thanh tiến trình dựa trên ajax cho người dùng. Bằng cách này, người dùng của họ có sự sang trọng của giao diện web và bạn có sự sang trọng không có thời gian chờ.

Các vấn đề liên quan