Files
patroni/helpers/dcs.py
T
Alexander Kukushkin 7445590546 Keep node name in AbstractDCS class
It eliminates need to pass this name into most of the methods
2015-07-07 12:26:52 +02:00

93 lines
2.2 KiB
Python

import abc
import sys
from collections import namedtuple
from helpers.utils import calculate_ttl, sleep
if sys.hexversion >= 0x03000000:
from urllib.parse import urlparse, urlunparse, parse_qsl
else:
from urlparse import urlparse, urlunparse, parse_qsl
def parse_connection_string(value):
scheme, netloc, path, params, query, fragment = urlparse(value)
conn_url = urlunparse((scheme, netloc, path, params, '', fragment))
api_url = ([v for n, v in parse_qsl(query) if n == 'application_name'] or [None])[0]
return conn_url, api_url
class DCSError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
"""
>>> str(DCSError('foo'))
"'foo'"
"""
return repr(self.value)
class Member(namedtuple('Member', 'index,name,conn_url,api_url,expiration,ttl')):
def real_ttl(self):
return calculate_ttl(self.expiration) or -1
class Cluster(namedtuple('Cluster', 'initialize,leader,last_leader_operation,members')):
def is_unlocked(self):
return not (self.leader and self.leader.name)
class AbstractDCS:
__metaclass__ = abc.ABCMeta
def __init__(self, name, config):
self._name = name
self._base_path = '/service/' + config['scope']
def client_path(self, path):
return self._base_path + path
@abc.abstractmethod
def get_cluster(self):
"""get_cluster"""
@abc.abstractmethod
def update_leader(self, state_handler):
"""update_leader"""
@abc.abstractmethod
def attempt_to_acquire_leader(self):
"""attempt_to_acquire_leader"""
def current_leader(self):
try:
cluster = self.get_cluster()
return None if cluster.is_unlocked() else cluster.leader
except DCSError:
return None
@abc.abstractmethod
def touch_member(self, connection_string, ttl=None):
"""touch_member"""
@abc.abstractmethod
def take_leader(self):
"""take_leader"""
@abc.abstractmethod
def race(self, path):
"""race"""
@abc.abstractmethod
def delete_leader(self):
"""delete_leader"""
def sleep(self, timeout):
sleep(timeout)