3
3
"""An SQLAlchemy backend for the search endpoint
4
4
"""
5
5
6
+ import logging
7
+
6
8
from ... import storage
7
9
from ... import toolkit
8
10
from .. import config
14
16
import sqlalchemy .sql .functions
15
17
16
18
19
+ logger = logging .getLogger (__name__ )
20
+
21
+
17
22
Base = sqlalchemy .ext .declarative .declarative_base ()
18
23
19
24
@@ -43,6 +48,24 @@ def __repr__(self):
43
48
type (self ).__name__ , self .name , self .description )
44
49
45
50
51
+ def retry (f ):
52
+ def _retry (self , * args , ** kwargs ):
53
+ retry_times = 1
54
+ i = 0
55
+ while True :
56
+ try :
57
+ return f (self , * args , ** kwargs )
58
+ except sqlalchemy .exc .DBAPIError as e :
59
+ if i < retry_times :
60
+ logger .warn ("DB is disconnected. Reconnect to it." )
61
+ self .reconnect_db ()
62
+ i += 1
63
+ else :
64
+ raise e
65
+
66
+ return _retry
67
+
68
+
46
69
class SQLAlchemyIndex (Index ):
47
70
"""Maintain an index of repository data
48
71
@@ -56,12 +79,17 @@ def __init__(self, database=None):
56
79
if database is None :
57
80
cfg = config .load ()
58
81
database = cfg .sqlalchemy_index_database
82
+ self ._database = database
59
83
self ._engine = sqlalchemy .create_engine (database )
60
84
self ._session = sqlalchemy .orm .sessionmaker (bind = self ._engine )
61
85
self .version = 1
62
86
self ._setup_database ()
63
87
super (SQLAlchemyIndex , self ).__init__ ()
64
88
89
+ def reconnect_db (self ):
90
+ self ._engine = sqlalchemy .create_engine (self ._database )
91
+ self ._session = sqlalchemy .orm .sessionmaker (bind = self ._engine )
92
+
65
93
@toolkit .exclusive_lock
66
94
def _setup_database (self ):
67
95
session = self ._session ()
@@ -78,6 +106,7 @@ def _setup_database(self):
78
106
self ._generate_index (session = session )
79
107
session .close ()
80
108
109
+ @retry
81
110
def _generate_index (self , session ):
82
111
store = storage .load ()
83
112
Base .metadata .create_all (self ._engine )
@@ -86,6 +115,7 @@ def _generate_index(self, session):
86
115
session .add (Repository (** repository ))
87
116
session .commit ()
88
117
118
+ @retry
89
119
def _handle_repository_created (
90
120
self , sender , namespace , repository , value ):
91
121
name = '{0}/{1}' .format (namespace , repository )
@@ -95,6 +125,7 @@ def _handle_repository_created(
95
125
session .commit ()
96
126
session .close ()
97
127
128
+ @retry
98
129
def _handle_repository_updated (
99
130
self , sender , namespace , repository , value ):
100
131
name = '{0}/{1}' .format (namespace , repository )
@@ -109,13 +140,15 @@ def _handle_repository_updated(
109
140
session .commit ()
110
141
session .close ()
111
142
143
+ @retry
112
144
def _handle_repository_deleted (self , sender , namespace , repository ):
113
145
name = '{0}/{1}' .format (namespace , repository )
114
146
session = self ._session ()
115
147
session .query (Repository ).filter (Repository .name == name ).delete ()
116
148
session .commit ()
117
149
session .close ()
118
150
151
+ @retry
119
152
def results (self , search_term = None ):
120
153
session = self ._session ()
121
154
repositories = session .query (Repository )
0 commit comments