Tôi viết mã cho trang blog/tin tức. Trang chính có 10 bài viết gần đây nhất và cũng có một phần lưu trữ với tất cả các bài báo được sắp xếp theo thời gian sửa đổi giảm dần. Trong phần lưu trữ, tôi sử dụng phân trang dựa trên con trỏ và kết quả bộ nhớ cache của tôi bắt đầu từ trang thứ hai vì các trang được thay đổi chỉ khi bài viết mới được xuất bản hoặc hiện tại đi vào bản nháp vì lý do nào đó. Mỗi trang có 10 bài viết. Vì vậy, khi người dùng truy cập một trang lưu trữ với một số số (không phải là trang đầu tiên), memcache sẽ được kiểm tra cho kết quả số trang đó trước tiên. Nếu trang không có, memcache được kiểm tra cho con trỏ cho trang đó và sau đó kết quả được lấy từ kho dữ liệu sử dụng mà con trỏ:Đọc trễ trong App Engine Datastore sau khi đặt()
class archivePage:
def GET(self, page):
if not page:
articles = memcache.get('archivePage')
if not articles:
articles = fetchArticles()
memcache.set('archivePage', articles)
else:
if int(page) == 0 or int(page) == 1:
raise web.seeother('/archive')
articles = memcache.get('archivePage'+page)
if not articles:
pageCursor = memcache.get('ArchivePageMapping'+page)
if not pageCursor:
pageMapping = ArchivePageMapping.query(ArchivePageMapping.page == int(page)).get()
pageCursor = pageMapping.cursor
memcache.set('ArchivePageMapping'+page, pageCursor)
articles = fetchArticles(cursor=Cursor(urlsafe=pageCursor))
memcache.set('archivePage'+page, articles)
Mỗi lần một bài viết mới được tạo ra hoặc tình trạng của một bài báo hiện đang thay đổi (dự thảo/xuất bản) Tôi làm mới bộ nhớ cache cho các kết quả trang lưu trữ và con trỏ. Tôi làm điều đó sau khi tiết kiệm một bài báo để các kho dữ liệu:
class addArticlePage:
def POST(self):
formData = web.input()
if formData.title and formData.content:
article = Article(title=formData.title,
content=formData.content,
status=int(formData.status))
key = article.put()
if int(formData.status) == 1:
cacheArchivePages()
raise web.seeother('/article/%s' % key.id())
def cacheArchivePages():
articles, cursor, moreArticles = fetchArticlesPage()
memcache.set('archivePage', articles)
pageNumber=2
while moreArticles:
pageMapping = ArchivePageMapping.query(ArchivePageMapping.page == pageNumber).get()
if pageMapping:
pageMapping.cursor = cursor.urlsafe()
else:
pageMapping = ArchivePageMapping(page=pageNumber,
cursor=cursor.urlsafe())
pageMapping.put()
memcache.set('ArchivePageMapping'+str(pageNumber), cursor.urlsafe())
articles, cursor, moreArticles = fetchArticlesPage(cursor=cursor)
memcache.set('archivePage'+str(pageNumber), articles)
pageNumber+=1
Và ở đây có vấn đề. Đôi khi (không có luật, nó xảy ra ngẫu nhiên) sau khi làm mới bộ nhớ cache tôi nhận được kết quả tương tự và con trỏ cho các trang lưu trữ như trước khi làm mới. Ví dụ tôi thêm một bài viết mới. Nó được lưu trong kho dữ liệu và nó xuất hiện trên trang đầu và trên trang đầu tiên trong kho lưu trữ (trang đầu tiên của kho lưu trữ không được lưu trữ). Nhưng các trang lưu trữ khác không được cập nhật. Tôi đã thử nghiệm hàm cacheArchivePages() của mình và nó hoạt động như mong đợi. Nó có thể được như vậy mà quá ít thời gian đã trôi qua sau khi tôi đặt() một bản cập nhật cho kho dữ liệu và trước khi tôi fetchArticlesPage() trong cacheArchivePages() chức năng? Có lẽ giao dịch viết chưa kết thúc và vì vậy tôi nhận được kết quả cũ? Tôi đã cố gắng sử dụng time.sleep() và chờ một vài giây trước khi gọi cacheArchivePages() và trong trường hợp đó tôi không thể tái tạo hành vi đó, nhưng dường như với tôi rằng time.sleep() không phải là một ý tưởng hay. Dù sao thì tôi cũng cần phải biết chính xác nguyên nhân của hành vi đó và cách giải quyết nó.
Cảm ơn bạn Guido! Tôi nên chú ý hơn đến tính nhất quán của dữ liệu và ghi nhớ các đặc điểm của kho dữ liệu HR. Trong trường hợp cụ thể này, tôi dễ dàng so sánh các kết quả cũ và các kết quả mới và nếu chúng giống nhau để khởi động lại truy vấn. – wombatonfire
Tôi upvoted vì "sử dụng truy vấn tổ tiên" là chính xác những gì giải quyết vấn đề chậm trễ trong ứng dụng của tôi, cảm ơn bạn Guido. – Deleplace