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()