Một khả năng là chuỗi của bạn không bị treo, nó thực sự là chết. Đây là những gì bạn nên làm để tìm ra những gì đang xảy ra. Thêm này trước khi tạo thread công nhân của bạn:
Thread.abort_on_exception = true
Khi một ngoại lệ xảy ra bên trong chủ đề của bạn mà không bao giờ bị bắt, toàn bộ quá trình bạn bị chấm dứt, và bạn có thể xem những ngoại lệ được nâng lên. Nếu không (và đây là mặc định), chủ đề của bạn bị giết.
Nếu đây quay ra không là vấn đề, hãy đọc tiếp ...
thi hành timeouts Ruby là khá ngây thơ. Nó thiết lập một chuỗi riêng biệt để ngủ cho n giây, sau đó mù quáng làm tăng ngoại lệ Thời gian chờ bên trong chuỗi ban đầu.
Bây giờ, mã gốc thực sự có thể ở giữa khối rescue
hoặc ensure
. Việc đưa ra một ngoại lệ trong một khối như vậy sẽ âm thầm hủy bỏ bất kỳ loại mã dọn dẹp nào. Điều này có thể để lại mã mà lần trong trạng thái không đúng. Nó khá khó để nói nếu đây là vấn đề của bạn chính xác, nhưng nhìn thấy cách xử lý cơ sở dữ liệu có thể làm một chút công bằng của khóa và xử lý ngoại lệ, nó có thể rất có thể. Here's an article that explains the issue in more depth.
Có cách nào bạn có thể sử dụng tính năng xử lý hết thời gian chờ tích hợp sẵn của thư viện cơ sở dữ liệu không? Nó có thể được thực hiện ở mức thấp hơn, không sử dụng thời gian chờ của Ruby.
Cách thay thế đơn giản là lên lịch cuộc gọi cơ sở dữ liệu trong một quy trình riêng biệt. Bạn có thể ngã ba quá trình chính mỗi khi bạn làm việc nâng cơ sở dữ liệu nặng nề. Hoặc bạn có thể thiết lập một cronjob đơn giản để thực thi một kịch bản thực thi nó. Điều này sẽ hơi khó khăn hơn nếu bạn cần giao tiếp với chủ đề chính của bạn. Vui lòng để lại một số chi tiết khác nếu bạn muốn bất kỳ lời khuyên nào về tùy chọn nào có thể phù hợp với nhu cầu của bạn.
Dựa trên nhận xét của bạn, chuỗi đang sắp chết. Đây có thể là lỗi trong các thư viện hoặc mã ứng dụng mà bạn có thể hoặc không thể khắc phục được.Nếu bạn muốn bẫy bất kỳ lỗi tùy ý được tạo ra bởi mã xử lý cơ sở dữ liệu và sau đó thử lại, bạn có thể thử một cái gì đó như sau:
t = Thread.new do
loop do
sleep INTERVAL
begin
# Execute database queries and process data
rescue StandardError
# Log error or recover from error situation before retrying
end
end
end
Bạn cũng có thể sử dụng từ khóa retry
trong khối rescue
để thử lại ngay lập tức, nhưng bạn có thể nên giữ một bộ đếm để đảm bảo rằng bạn không vô tình thử lại vô thời hạn khi lỗi không thể khôi phục tiếp tục xảy ra.
Vì vậy, nó không ném Timeout :: Lỗi? Là nó ném bất kỳ lỗi nào cả? –
Chính xác, không có gì xảy ra, nó chỉ đóng băng ngay tại vị trí của nó. Ít nhất, đó là những gì tôi đã xác định từ đặt quá nhiều 'đặt' ở khắp mọi nơi để xác định nơi/nếu thực hiện được chọn sao lưu. –
Tại sao điều đó lại làm việc ném? Toàn bộ thời gian chờ sẽ là nó gây ra lỗi nếu khối nó được cho chạy quá lâu. Tôi đã thử datamapper và mysql2 trực tiếp, hy vọng hoặc sẽ làm một kết nối lại tự động và giải quyết vấn đề theo cách đó, nhưng không có may mắn. Nếu các chi tiết cụ thể giúp đỡ, hãy nói đó là kết nối mysql2 mà trên đó tôi thực hiện một '.query (...)'. Không có gì được bao giờ ném từ đó, anyways, và một điều khoản 'rescue' chung bên ngoài nó sẽ bắt nó trong bất kỳ sự kiện nào. –