Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Commit d6d4be9

Browse files
committed
Merge pull request #779 from hex108/fix-issue-778
Fix issue 778: OperationalError: (OperationalError) server closed the connection unexpectedly
2 parents 2de63e3 + acd9052 commit d6d4be9

File tree

1 file changed

+33
-0
lines changed
  • docker_registry/lib/index

1 file changed

+33
-0
lines changed

docker_registry/lib/index/db.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"""An SQLAlchemy backend for the search endpoint
44
"""
55

6+
import logging
7+
68
from ... import storage
79
from ... import toolkit
810
from .. import config
@@ -14,6 +16,9 @@
1416
import sqlalchemy.sql.functions
1517

1618

19+
logger = logging.getLogger(__name__)
20+
21+
1722
Base = sqlalchemy.ext.declarative.declarative_base()
1823

1924

@@ -43,6 +48,24 @@ def __repr__(self):
4348
type(self).__name__, self.name, self.description)
4449

4550

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+
4669
class SQLAlchemyIndex (Index):
4770
"""Maintain an index of repository data
4871
@@ -56,12 +79,17 @@ def __init__(self, database=None):
5679
if database is None:
5780
cfg = config.load()
5881
database = cfg.sqlalchemy_index_database
82+
self._database = database
5983
self._engine = sqlalchemy.create_engine(database)
6084
self._session = sqlalchemy.orm.sessionmaker(bind=self._engine)
6185
self.version = 1
6286
self._setup_database()
6387
super(SQLAlchemyIndex, self).__init__()
6488

89+
def reconnect_db(self):
90+
self._engine = sqlalchemy.create_engine(self._database)
91+
self._session = sqlalchemy.orm.sessionmaker(bind=self._engine)
92+
6593
@toolkit.exclusive_lock
6694
def _setup_database(self):
6795
session = self._session()
@@ -78,6 +106,7 @@ def _setup_database(self):
78106
self._generate_index(session=session)
79107
session.close()
80108

109+
@retry
81110
def _generate_index(self, session):
82111
store = storage.load()
83112
Base.metadata.create_all(self._engine)
@@ -86,6 +115,7 @@ def _generate_index(self, session):
86115
session.add(Repository(**repository))
87116
session.commit()
88117

118+
@retry
89119
def _handle_repository_created(
90120
self, sender, namespace, repository, value):
91121
name = '{0}/{1}'.format(namespace, repository)
@@ -95,6 +125,7 @@ def _handle_repository_created(
95125
session.commit()
96126
session.close()
97127

128+
@retry
98129
def _handle_repository_updated(
99130
self, sender, namespace, repository, value):
100131
name = '{0}/{1}'.format(namespace, repository)
@@ -109,13 +140,15 @@ def _handle_repository_updated(
109140
session.commit()
110141
session.close()
111142

143+
@retry
112144
def _handle_repository_deleted(self, sender, namespace, repository):
113145
name = '{0}/{1}'.format(namespace, repository)
114146
session = self._session()
115147
session.query(Repository).filter(Repository.name == name).delete()
116148
session.commit()
117149
session.close()
118150

151+
@retry
119152
def results(self, search_term=None):
120153
session = self._session()
121154
repositories = session.query(Repository)

0 commit comments

Comments
 (0)