Add programatic introspection of drivers characteristic(s)
Change-Id: Icf187db9ba7d076b1a0f3cc9343acb0eaa1862cb
This commit is contained in:
parent
9f5290ea9c
commit
a3f22fe90c
|
@ -4,13 +4,17 @@ Drivers
|
|||
|
||||
Tooz is provided with several drivers implementing the provided coordination
|
||||
API. While all drivers provides the same set of features with respect to the
|
||||
API, some of them have different properties.
|
||||
API, some of them have different characteristics:
|
||||
|
||||
Zookeeper
|
||||
---------
|
||||
|
||||
**Driver:** :py:class:`tooz.drivers.zookeeper.KazooDriver`
|
||||
|
||||
**Characteristics:**
|
||||
|
||||
:py:attr:`tooz.drivers.zookeeper.KazooDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``zookeeper`` or ``kazoo``
|
||||
|
||||
**Summary:**
|
||||
|
@ -21,6 +25,10 @@ resilient towards network partitions for example.
|
|||
|
||||
**Test driver:** :py:class:`tooz.drivers.zake.ZakeDriver`
|
||||
|
||||
**Characteristics:**
|
||||
|
||||
:py:attr:`tooz.drivers.zake.ZakeDriver.CHARACTERISTICS`
|
||||
|
||||
**Test driver entrypoint name:** ``zake``
|
||||
|
||||
Considerations
|
||||
|
@ -35,6 +43,10 @@ Memcached
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.memcached.MemcachedDriver`
|
||||
|
||||
**Characteristics:**
|
||||
|
||||
:py:attr:`tooz.drivers.memcached.MemcachedDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``memcached``
|
||||
|
||||
**Summary:**
|
||||
|
@ -58,6 +70,10 @@ Redis
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.redis.RedisDriver`
|
||||
|
||||
**Characteristics:**
|
||||
|
||||
:py:attr:`tooz.drivers.redis.RedisDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``redis``
|
||||
|
||||
**Summary:**
|
||||
|
@ -79,6 +95,8 @@ IPC
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.ipc.IPCDriver`
|
||||
|
||||
**Characteristics:** :py:attr:`tooz.drivers.ipc.IPCDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``ipc``
|
||||
|
||||
**Summary:**
|
||||
|
@ -98,6 +116,8 @@ File
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.file.FileDriver`
|
||||
|
||||
**Characteristics:** :py:attr:`tooz.drivers.file.FileDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``file``
|
||||
|
||||
**Summary:**
|
||||
|
@ -118,6 +138,10 @@ PostgreSQL
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.pgsql.PostgresDriver`
|
||||
|
||||
**Characteristics:**
|
||||
|
||||
:py:attr:`tooz.drivers.pgsql.PostgresDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``postgresql``
|
||||
|
||||
**Summary:**
|
||||
|
@ -140,6 +164,8 @@ MySQL
|
|||
|
||||
**Driver:** :py:class:`tooz.drivers.mysql.MySQLDriver`
|
||||
|
||||
**Characteristics:** :py:attr:`tooz.drivers.mysql.MySQLDriver.CHARACTERISTICS`
|
||||
|
||||
**Entrypoint name:** ``mysql``
|
||||
|
||||
**Summary:**
|
||||
|
@ -157,6 +183,11 @@ Considerations
|
|||
- Does **not** work when MySQL replicates from one server to another (locks
|
||||
are local to the server that they were created from).
|
||||
|
||||
Characteristics
|
||||
---------------
|
||||
|
||||
.. autoclass:: tooz.coordination.Characteristics
|
||||
|
||||
.. _advisory locks: http://www.postgresql.org/docs/8.2/interactive/\
|
||||
explicit-locking.html#ADVISORY-LOCKS
|
||||
.. _get_lock: http://dev.mysql.com/doc/refman/5.5/en/\
|
||||
|
|
|
@ -5,6 +5,7 @@ pbr>=1.6
|
|||
Babel>=1.3
|
||||
stevedore>=1.5.0 # Apache-2.0
|
||||
six>=1.9.0
|
||||
enum34;python_version=='2.7' or python_version=='2.6' or python_version=='3.3'
|
||||
iso8601>=0.1.9
|
||||
zake>=0.1.6 # Apache-2.0
|
||||
jsonschema!=2.5.0,<3.0.0,>=2.0.0
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import abc
|
||||
import collections
|
||||
import enum
|
||||
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import netutils
|
||||
|
@ -28,6 +29,74 @@ import tooz
|
|||
TOOZ_BACKENDS_NAMESPACE = "tooz.backends"
|
||||
|
||||
|
||||
class Characteristics(enum.Enum):
|
||||
"""Attempts to describe the characteristic that a driver supports."""
|
||||
|
||||
DISTRIBUTED_ACROSS_THREADS = 'DISTRIBUTED_ACROSS_THREADS'
|
||||
"""Coordinator components when used by multiple **threads** work
|
||||
the same as if those components were only used by a single thread."""
|
||||
|
||||
DISTRIBUTED_ACROSS_PROCESSES = 'DISTRIBUTED_ACROSS_PROCESSES'
|
||||
"""Coordinator components when used by multiple **processes** work
|
||||
the same as if those components were only used by a single thread."""
|
||||
|
||||
DISTRIBUTED_ACROSS_HOSTS = 'DISTRIBUTED_ACROSS_HOSTS'
|
||||
"""Coordinator components when used by multiple **hosts** work
|
||||
the same as if those components were only used by a single thread."""
|
||||
|
||||
LINEARIZABLE = 'LINEARIZABLE'
|
||||
"""The driver has the following properties:
|
||||
|
||||
* Ensures each operation must take place before its
|
||||
completion time.
|
||||
* Any operation invoked subsequently must take place
|
||||
after the invocation and by extension, after the original operation
|
||||
itself.
|
||||
"""
|
||||
|
||||
SEQUENTIAL = 'SEQUENTIAL'
|
||||
"""The driver has the following properties:
|
||||
|
||||
* Operations can take effect before or after completion – but all
|
||||
operations retain the constraint that operations from any given process
|
||||
must take place in that processes order.
|
||||
"""
|
||||
|
||||
CAUSAL = 'CAUSAL'
|
||||
"""The driver has the following properties:
|
||||
|
||||
* Does **not** have to enforce the order of every
|
||||
operation from a process, perhaps, only causally related operations
|
||||
must occur in order.
|
||||
"""
|
||||
|
||||
SERIALIZABLE = 'SERIALIZABLE'
|
||||
"""The driver has the following properties:
|
||||
|
||||
* The history of **all** operations is equivalent to
|
||||
one that took place in some single atomic order but with unknown
|
||||
invocation and completion times - it places no bounds on
|
||||
time or order.
|
||||
"""
|
||||
|
||||
SAME_VIEW_UNDER_PARTITIONS = 'SAME_VIEW_UNDER_PARTITIONS'
|
||||
"""When a client is connected to a server and that server is partitioned
|
||||
from a group of other servers it will (somehow) have the same view of
|
||||
data as a client connected to a server on the other side of the
|
||||
partition (typically this is accomplished by write availability being
|
||||
lost and therefore nothing can change).
|
||||
"""
|
||||
|
||||
SAME_VIEW_ACROSS_CLIENTS = 'SAME_VIEW_ACROSS_CLIENTS'
|
||||
"""A client connected to one server will *always* have the same view
|
||||
every other client will have (no matter what server those other
|
||||
clients are connected to). Typically this is a sacrifice in
|
||||
write availability because before a write can be acknowledged it must
|
||||
be acknowledged by *all* servers in a cluster (so that all clients
|
||||
that are connected to those servers read the exact *same* thing).
|
||||
"""
|
||||
|
||||
|
||||
class Hooks(list):
|
||||
def run(self, *args, **kwargs):
|
||||
return list(map(lambda cb: cb(*args, **kwargs), self))
|
||||
|
@ -72,6 +141,12 @@ class CoordinationDriver(object):
|
|||
backing store.
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = ()
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._started = False
|
||||
self._hooks_join_group = collections.defaultdict(Hooks)
|
||||
|
|
|
@ -193,6 +193,15 @@ class FileDriver(coordination._RunWatchersMixin,
|
|||
account when applying this driver in there app).
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
HASH_ROUTINE = 'sha1'
|
||||
"""This routine is used to hash a member (or group) id into a filesystem
|
||||
safe name that can be used for member lookup and group joining."""
|
||||
|
|
|
@ -133,6 +133,15 @@ class IPCDriver(coordination.CoordinationDriver):
|
|||
.. _IPC: http://en.wikipedia.org/wiki/Inter-process_communication
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
_SEGMENT_SIZE = 1024
|
||||
_GROUP_LIST_KEY = "GROUP_LIST"
|
||||
_GROUP_PROJECT = "_TOOZ_INTERNAL"
|
||||
|
|
|
@ -173,6 +173,17 @@ class MemcachedDriver(coordination._RunWatchersMixin,
|
|||
.. _msgpack: http://msgpack.org/
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_HOSTS,
|
||||
coordination.Characteristics.CAUSAL,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
#: Key prefix attached to groups (used in name-spacing keys)
|
||||
GROUP_PREFIX = b'_TOOZ_GROUP_'
|
||||
|
||||
|
|
|
@ -102,6 +102,16 @@ class MySQLDriver(coordination.CoordinationDriver):
|
|||
.. _MySQL: http://dev.mysql.com/
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_HOSTS,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
def __init__(self, member_id, parsed_url, options):
|
||||
"""Initialize the MySQL driver."""
|
||||
super(MySQLDriver, self).__init__()
|
||||
|
|
|
@ -158,6 +158,16 @@ class PostgresDriver(coordination.CoordinationDriver):
|
|||
.. _PostgreSQL: http://www.postgresql.org/
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_HOSTS,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
def __init__(self, member_id, parsed_url, options):
|
||||
"""Initialize the PostgreSQL driver."""
|
||||
super(PostgresDriver, self).__init__()
|
||||
|
|
|
@ -160,6 +160,17 @@ class RedisDriver(coordination._RunWatchersMixin,
|
|||
.. _AOF: http://redis.io/topics/persistence
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_HOSTS,
|
||||
coordination.Characteristics.CAUSAL,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
MIN_VERSION = version.LooseVersion("2.6.0")
|
||||
"""
|
||||
The min redis version that this driver requires to operate with...
|
||||
|
|
|
@ -17,6 +17,7 @@ from __future__ import absolute_import
|
|||
from zake import fake_client
|
||||
from zake import fake_storage
|
||||
|
||||
from tooz import coordination
|
||||
from tooz.drivers import zookeeper
|
||||
|
||||
|
||||
|
@ -31,6 +32,14 @@ class ZakeDriver(zookeeper.KazooDriver):
|
|||
.. _zookeeper: http://zookeeper.apache.org/
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
# NOTE(harlowja): this creates a shared backend 'storage' layer that
|
||||
# would typically exist inside a zookeeper server, but since zake has
|
||||
# no concept of a 'real' zookeeper server we create a fake one and share
|
||||
|
|
|
@ -407,6 +407,20 @@ class KazooDriver(BaseZooKeeperDriver):
|
|||
this option is one of the keys in this dictionary).
|
||||
"""
|
||||
|
||||
CHARACTERISTICS = (
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_THREADS,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_PROCESSES,
|
||||
coordination.Characteristics.DISTRIBUTED_ACROSS_HOSTS,
|
||||
# Writes *always* go through a single leader process, but it may
|
||||
# take a while for those writes to propagate to followers (and =
|
||||
# during this time clients can read older values)...
|
||||
coordination.Characteristics.SEQUENTIAL,
|
||||
)
|
||||
"""
|
||||
Tuple of :py:class:`~tooz.coordination.Characteristics` introspectable
|
||||
enum member(s) that can be used to interogate how this driver works.
|
||||
"""
|
||||
|
||||
def __init__(self, member_id, parsed_url, options):
|
||||
super(KazooDriver, self).__init__(member_id, parsed_url, options)
|
||||
self._coord = self._make_client(parsed_url, self._options)
|
||||
|
|
Loading…
Reference in New Issue