Open Kilda Java Documentation
neo4j_tools.py
Go to the documentation of this file.
1 from __future__ import absolute_import
2 
3 import ConfigParser
4 import logging
5 import os
6 import time
7 
8 import neo4j.exceptions
9 import neo4j.v1.api
10 import neo4j.v1.direct
11 import py2neo
12 
13 from . import exc
14 
15 logger = logging.getLogger(__name__)
16 
17 
18 class RetryConfig(object):
19  iteration = 0
20  max_attempts = 3
21  delay = 0.1
22 
23  @classmethod
24  def configure(cls, config):
25  for attr, conv in (
26  ('max_attempts', int),
27  ('delay', float)):
28  key = 'retry.' + attr
29  try:
30  value = config.get('neo4j', key)
31  value = conv(value)
32  except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
33  continue
34  except TypeError as e:
35  raise exc.ConfigError('neo4j', key, e)
36 
37  setattr(cls, attr, value)
38 
39  def can_retry(self):
40  if self.max_attempts < 0:
41  return True
42  return self.iteration < self.max_attempts
43 
44  def sleep(self):
45  self.iteration += 1
46  if 0 < self.delay:
47  time.sleep(self.delay)
48 
49 
50 # TODO(surabujin): neo4j Session object have build-in retry mechanism. It will
51 # be better to use it, that keep support of our own
52 class Neo4jSession(neo4j.v1.api.Session):
53  def run(self, statement, parameters=None, **kwargs):
54  retry = RetryConfig()
55 
56  while retry.can_retry():
57  try:
58  result = super(Neo4jSession, self).run(
59  statement, parameters, **kwargs)
60  except neo4j.exceptions.TransientError:
61  retry.sleep()
62  continue
63 
64  return result
65 
66 
67 def connect(config):
68  RetryConfig.configure(config)
69 
70  env_keys_map = {
71  'host': 'neo4host',
72  'login': 'neo4usr',
73  'password': 'neo4pass'
74  }
75 
76  config_keys_map = {
77  'login': 'user',
78  'password': 'pass'
79  }
80  config_section = 'neo4j'
81 
82  args = {}
83 
84  for option in ('host', 'login', 'password'):
85  name = env_keys_map.get(option, option)
86  value = os.environ.get(name)
87  if not value:
88  name = config_keys_map.get(option, option)
89  value = config.get(config_section, name)
90 
91  args[option] = value
92 
93  uri_format = "bolt://{login}:{password}@{host}:7687".format
94  uri = uri_format(**args)
95 
96  args['password'] = '*' * 5
97  logger.info('NEO4j connect %s', uri_format(**args))
98  return py2neo.Graph(uri)
99 
100 
101 # monkeypatching py2neo.database to inject our retry mechanism
102 neo4j.v1.direct.Session = Neo4jSession
def connect(config)
Definition: neo4j_tools.py:67
def run(self, statement, parameters=None, kwargs)
Definition: neo4j_tools.py:53
def configure(cls, config)
Definition: neo4j_tools.py:24