|
Pythomnic » Documentation » Persistent storage
For network services the goal of persistency is to be able to keep
some state between separate client requests. Persistent storage can be
used for many things, but the ultimate goal is the same - to keep some
data available, so that it survives not only across requests, but
between service or server restarts.
You could have added a connection to a full-blown database and store
your data there. But that would require too much hassle of bringing
up and configuring the database and shoehorning the data you want
to keep into relational tables or hooking up to an ORM. Besides, you
will have to decide on how different cages and different modules will
share the same database.
Instead, for quick-and-easy persistency Pythomnic offers a facility called
"module safe". This is a small database only visible inside an application
module, each module thus has its own private safe. Technically, module
safe is an instance of a shelf,
standard Python mechanism for serializing objects backed up by embedded
BerkeleyDB database.
Your application modules access their safes using the pmnc_safe construct
pmnc_safe[key] = value value = pmnc_safe[key] value = pmnc_safe.get(key, default) del pmnc_safe[key]
which behaves like dict, providing keyed access to a set of records (inheriting
this behaviour from a shelf). A shelf also allows storing all sorts of data,
thus pmnc_safe can contain nearly everything, for example:
pmnc_safe["foo"] = { (None, ): [ 1, "bar", Decimal("1.0") ] }
Each module's safe files are stored in safe/node.cage.module/ directory - one
file with data and several files with transaction logs. BerkeleyDB is a "real"
database supporting transactions and everything, therefore pmnc_safe among
other things enjoys atomicity and durability - a safe operation cannot fail
halfway through, leaving the data corrupt, and having returned from
pmnc_safe["foo"] = "bar"
your code can be certain the data is stored for good.
The pmnc_safe facility does not support explicit transactions spanning multiple
safe accesses. Instead, each access to the safe is performed in a separate
implicit transaction with auto-commit. Therefore in
pmnc_safe["foo"] = "bar" pmnc_safe["biz"] = "baz"
each assignment is a separate transaction, and if there is a failure between
the two, the safe will contain only the first record. Moreover, a concurrent
thread may only see only the first record, but not the second. This is by
design and your application modules should account for that.
|
Features Download Documentation Tutorial |