Tôi có một trình xử lý yêu cầu cập nhật một thực thể, lưu nó vào kho dữ liệu, sau đó cần thực hiện một số công việc bổ sung trước khi trở về (như xếp hàng tác vụ nền và tuần tự hóa một số kết quả). Tôi muốn song song mã này, để công việc bổ sung được thực hiện trong khi thực thể đang được lưu.Làm thế nào để ngăn chặn ndb từ đợt một cuộc gọi put_async() và làm cho nó phát hành RPC ngay lập tức?
Đây là những gì mã xử lý của tôi nắm xuống:
class FooHandler(webapp2.RequestHandler):
@ndb.toplevel
def post(self):
foo = yield Foo.get_by_id_async(some_id)
# Do some work with foo
# Don't yield, as I want to perform the code that follows
# while foo is being saved to the datastore.
# I'm in a toplevel, so the handler will not exit as long as
# this async request is not finished.
foo.put_async()
taskqueue.add(...)
json_result = generate_result()
self.response.headers["Content-Type"] = "application/json; charset=UTF-8"
self.response.write(json_result)
Tuy nhiên, Appstats cho thấy datastore.Put
RPC đang được thực hiện nối tiếp, sau khi taskqueue.Add
:
Một chút đào xung quanh trong ndb.context.py
cho thấy rằng cuộc gọi put_async()
sẽ được thêm vào AutoBatcher
thay vì RPC được phát hành ngay lập tức.
Vì vậy, tôi giả sử rằng sẽ bị xóa khi hết toplevel
chờ tất cả các cuộc gọi không đồng bộ được hoàn thành.
Tôi hiểu rằng việc đặt hàng loạt có lợi ích thực trong một số trường hợp, nhưng trong trường hợp của tôi ở đây tôi thực sự muốn RPC được gửi ngay lập tức, vì vậy tôi có thể thực hiện công việc khác trong khi thực thể đang được lưu.
Nếu tôi làm yield foo.put_async()
, sau đó tôi nhận được thác nước cùng trong Appstats, nhưng với datastore.Put
được thực hiện trước phần còn lại:
này là để được mong đợi, như yield
làm handler tôi chờ đợi Gọi put_async()
để hoàn thành trước khi thực hiện phần còn lại của mã.
Tôi cũng đã thử thêm một cuộc gọi đến ndb.get_context().flush()
ngay sau foo.put_async()
, nhưng các cuộc gọi datastore.Put
và taskqueue.BulkAdd
vẫn không được thực hiện song song theo Appstats.
Vì vậy, câu hỏi của tôi là: làm thế nào tôi có thể buộc cuộc gọi đến put_async()
để bỏ qua bộ nạp tự động và phát hành RPC ngay lập tức?
Sản phẩm có đang được sản xuất hoặc tại địa phương không? – Lipis
Nó đang được sản xuất. –