我正在实现一个文件存储系统,其中多个人可以共享上传到blobstore的文件,但是一旦他们全部删除了文件,它就会从blobstore中删除。
我使用引用计数实体执行此操作,当其计数设置为0时将删除。我还使用google.appengine.ext.ndb.blobstore
中定义的BlobInfo ndb模型,因为我需要获取一堆BlobInfos几点,并希望能够异步地做到这一点。
当删除引用计数实体时,会调用其_post_delete_hook方法,我将其与BlobKey一起调用blobstore.delete_async,并且它还在ndb BlobInfo实例上调用BlobInfo._key.delete_async()。
class FileCounter(ndb.Model):
count = ndb.IntegerProperty(default=1)
@classmethod
def _post_delete_hook(cls, key, future):
blob_key = cls.blob_key_for_key(key)
blobinfo_extension.delete(blobstore.BlobInfo.get(blob_key))
和blobinfo_extension.delete定义为:
@ndb.tasklet
def delete_async(blobinfo):
""" Delete both the blob info and the blob in the blobstore it refers to. """
yield blobstore.delete_async(blobinfo.key()), blobinfo._key.delete_async()
def delete(blobinfo):
delete_async(blobinfo).wait()
我正在获取计数实体,递减计数,然后检查它是否为0.如果为0,则删除它。这都是在交易中完成的。是否在事务之外调用_post_delete_hook方法?如您所见,它正在访问BlobInfo实体并删除需要跨组事务的实体。
我将尝试这个,看看它是否有效,但由于无法找到任何答案,我在此处发布了它,所以它可能在将来帮助其他人。
这是解决此问题的一个很好的解决方案,或者我应该在计数递减时只是“手动”清理blobstore / blobinfo?我想也许我在滥用post delete hook!
答案 0 :(得分:2)
也许你可以在事务提交时使用ndb.get_context().call_on_commit(<callback>)
做一些工作?您可以将它与常规_post_delete_hook结合使用,只需为提交后清理步骤添加实体。