Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Unified Diff: appengine/findit/model/versioned_model.py

Issue 2488113005: [Findit] Re-org code. (Closed)
Patch Set: Rebase. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/findit/model/versioned_config.py ('k') | appengine/findit/model/wf_config.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/findit/model/versioned_model.py
diff --git a/appengine/findit/model/versioned_model.py b/appengine/findit/model/versioned_model.py
deleted file mode 100644
index d4d614488f960cd164cbc7c343f2b5320f695b0e..0000000000000000000000000000000000000000
--- a/appengine/findit/model/versioned_model.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides a model to support versioned entities in datastore.
-
-Idea: use a root model entity to keep track of the most recent version of a
-versioned entity, and make the versioned entities and the root model entity in
-the same entity group so that they could be read and written in a transaction.
-"""
-
-import logging
-
-from google.appengine.api import datastore_errors
-from google.appengine.ext import ndb
-from google.appengine.runtime import apiproxy_errors
-
-
-class _GroupRoot(ndb.Model):
- """Root entity of a group to support versioned children."""
- # Key id of the most recent child entity in the datastore. It is monotonically
- # increasing and is 0 if no child is present.
- current = ndb.IntegerProperty(indexed=False, default=0)
-
-
-class VersionedModel(ndb.Model):
- """A model that supports versioning.
-
- Subclasses will automatically be versioned. To create the first instance of a
- versioned entity, use Create(key) with optional key to differentiate between
- multiple unique entities of the same subclass. Use GetVersion() to read and
- Save() to write.
- """
-
- @property
- def _root_id(self):
- return self.key.pairs()[0][1] if self.key else None
-
- @property
- def version_number(self):
- # Ndb treats key.integer_id() of 0 as None, so default to 0.
- return self.key.integer_id() or 0 if self.key else 0
-
- @classmethod
- def Create(cls, key=None):
- """Creates an instance of cls that is to become the first version.
-
- The calling function of Create() should be responsible first for checking
- no previous version of the proposed entity already exists.
-
- Args:
- key: Any user-specified value that will serve as the id for the root
- entity's key.
-
- Returns:
- An instance of cls meant to be the first version. Note for this instance
- to be committed to the datastore Save() would need to be called on the
- instance returned by this method.
- """
- return cls(key=ndb.Key(cls, 0, parent=cls._GetRootKey(key)))
-
- @classmethod
- def GetVersion(cls, key=None, version=None):
- """Returns a version of the entity, the latest if version=None."""
- assert not ndb.in_transaction()
-
- root_key = cls._GetRootKey(key)
- root = root_key.get()
-
- if not root or not root.current:
- return None
-
- if version is None:
- version = root.current
- elif version < 1:
- # Return None for versions < 1, which causes exceptions in ndb.Key()
- return None
-
- return ndb.Key(cls, version, parent=root_key).get()
-
- @classmethod
- def GetLatestVersionNumber(cls, key=None):
- root_entity = cls._GetRootKey(key).get()
- if not root_entity:
- return -1
- return root_entity.current
-
- def Save(self, retry_on_conflict=True):
- """Saves the current entity, but as a new version.
-
- Args:
- retry_on_conflict (bool): Whether or not the next version number should
- automatically be tried in case another transaction writes the entity
- first with the same proposed new version number.
-
- Returns:
- The key of the newly written version, and a boolean whether or not this
- call to Save() was responsible for creating it.
- """
- root_key = self._GetRootKey(self._root_id)
- root = root_key.get() or self._GetRootModel()(key=root_key)
-
- def SaveData():
- if self.key.get():
- return False # The entity exists, should retry.
-
- ndb.put_multi([self, root])
- return True
-
- def SetNewKey():
- root.current += 1
- self.key = ndb.Key(self.__class__, root.current, parent=root_key)
-
- SetNewKey()
- while True:
- while self.key.get():
- if retry_on_conflict:
- SetNewKey()
- else:
- # Another transaction had already written the proposed new version, so
- # return that version's key and False indicating this call to Save()
- # was not responsible for creating it.
- return self.key, False
-
- try:
- if ndb.transaction(SaveData, retries=0):
- return self.key, True
- except (
- datastore_errors.InternalError,
- datastore_errors.Timeout,
- datastore_errors.TransactionFailedError) as e:
- # https://cloud.google.com/appengine/docs/python/datastore/transactions
- # states the result is ambiguous, it could have succeeded.
- logging.info('Transaction likely failed: %s', e)
- except (
- apiproxy_errors.CancelledError,
- datastore_errors.BadRequestError,
- RuntimeError) as e:
- logging.info('Transaction failure: %s', e)
- else:
- if retry_on_conflict:
- SetNewKey()
- else:
- # Another transaction had already written the proposed new version, so
- # return that version's key and False indicating this call to Save()
- # was not responsible for creating it.
- return self.key, False
-
- @classmethod
- def _GetRootModel(cls):
- """Returns a root model that can be used for versioned entities."""
- root_model_name = '%sRoot' % cls.__name__
-
- class _RootModel(_GroupRoot):
-
- @classmethod
- def _get_kind(cls):
- return root_model_name
-
- return _RootModel
-
- @classmethod
- def _GetRootKey(cls, key=None):
- return ndb.Key(cls._GetRootModel(), key if key is not None else 1)
« no previous file with comments | « appengine/findit/model/versioned_config.py ('k') | appengine/findit/model/wf_config.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698