Version-based consistency is used on a per-operation basis. It ensures that a read performed on a replica is at least as current as some previous write performed on the master.
An example of how this might be used is a web application that collects some information from a customer (such as her name). It then customizes all subsequent pages presented to the customer with her name. The storage of the customer's name is a write operation that can only be performed by the master node, while subsequent page creation is performed as a read-only operation that can occur at any node in the store.
Use of this consistency policy might require that version information be transferred between processes in your application.
To create a version-based consistency policy,
use the VersionConsistency
class.
When you do this, you must provide the following information:
ONDB_VERSION
The Version
that the read must
match.
ONDB_TIMEOUT
The number of milliseconds
that describes how long the replica is permitted to
wait in an attempt to meet the version requirement.
That is, if the replica cannot immediately meet the
version requirement, then it will wait this amount of
time to see if it is updated with the required data
from the master. If the replica cannot meet the
requirement within the timeout period, a
ConsistencyException
is
thrown.
For example, the following code performs a store write, collects the version information, then uses it to construct a version-based consistency policy.
from nosqldb import Consistency from nosqldb import DurabilityException from nosqldb import Factory from nosqldb import IllegalArgumentException from nosqldb import ProxyConfig from nosqldb import ReadOptions #### constant needed for ReadOptions from nosqldb import ONDB_CONSISTENCY from nosqldb import ONDB_VERSION_CONSISTENCY from nosqldb import ONDB_TIMEOUT from nosqldb import RequestTimeoutException from nosqldb import Row from nosqldb import StoreConfig from nosqldb import WriteOptions ##### Constants needed for the write options from nosqldb import ONDB_RETURN_CHOICE from nosqldb import VersionConsistency ### Constants needed for the VersionConsistency from nosqldb import ONDB_TIMEOUT from nosqldb import ONDB_VERSION import logging import os import sys # locations where our store and proxy can be found kvlite = 'localhost:5000' proxy = 'localhost:7010' # set logging level to debug and log to stdout def setup_logging(): rootLogger = logging.getLogger() rootLogger.setLevel(logging.DEBUG) logger = logging.StreamHandler(sys.stdout) logger.setLevel(logging.DEBUG) formatter = logging.Formatter('\t%(levelname)s - %(message)s') logger.setFormatter(formatter) rootLogger.addHandler(logger) # configure and open the store def open_store(): kvstoreconfig = StoreConfig('kvstore', [kvlite]) return Factory.open(proxy, kvstoreconfig) def write_row(store): row_d = { 'item' : 'bolts', 'description' : "Hex head, stainless", 'count' : 5, 'percentage' : 0.2173913} row = Row(row_d) ## Create the write options wo = WriteOptions({ONDB_RETURN_CHOICE : 'VERSION'}) try: matchVersion = store.put("myTable", row, wo) ## matchVersion is actually a tuple, the second element of ## which identifies the table that the row was written to. return matchVersion[0] except IllegalArgumentException, iae: logging.error("Could not write table.") logging.error(iae.message) except DurabilityException, de: logging.error("Could not write table. Durability failure.") logging.error(de.message) except RequestTimeoutException, rte: logging.error("Could not write table. Exceeded timeout.") logging.error(rte.message)
At some other point in this application's code, or perhaps in
another application entirely, we use the
matchVersion
captured above to create a
version-based consistency policy.
def display_row(row): try: print "Retrieved row:" print "\tItem: %s" % row['item'] print "\tDescription: %s" % row['description'] print "\tCount: %s" % row['count'] print "\tPercentage: %s" % row['percentage'] print "\n" except KeyError, ke: logging.error("Row display failed. Bad key: %s" % ke.message) def read_row(store, matchVersion): vc = VersionConsistency({ONDB_VERSION : matchVersion, ONDB_TIMEOUT : 1000}) consistency = Consistency({ONDB_VERSION_CONSISTENCY: vc}) ro = ReadOptions({ONDB_CONSISTENCY : consistency, ONDB_TIMEOUT : 1000}) try: primary_key_d = {"item" : "bolts"} row = store.get("myTable", primary_key_d, ro) if not row: logging.debug("Row retrieval failed") else: logging.debug("Row retrieval succeeded.") display_row(row) except IllegalArgumentException, iae: logging.error("Row retrieval failed.") logging.error(iae.message) return except ConsistencyException, ce: logging.error("Row retrieval failed due to Consistency.") logging.error(ce.message) except RequestTimeoutException, rte: logging.error("Row retrieval failed, exceeded timeout value.") logging.error(rte.message) if __name__ == '__main__': setup_logging() store = open_store() matchVersion = write_row(store) read_row(store, matchVersion) store.close()