Commit a12a0623 authored by Lukáš Lalinský's avatar Lukáš Lalinský

Use read-only database for search

parent 78481e40
Pipeline #20532 passed with stages
in 3 minutes and 48 seconds
......@@ -580,7 +580,7 @@ class LookupHandler(APIHandler):
update_user_agent_counter(self.ctx.redis, params.application_id, str(self.user_agent), self.user_ip)
searcher = FingerprintSearcher(self.ctx.db.get_fingerprint_db(), self.ctx.index)
searcher = FingerprintSearcher(self.ctx.db.get_fingerprint_db(read_only=True), self.ctx.index)
assert params.max_duration_diff is not None
searcher.max_length_diff = params.max_duration_diff
......@@ -592,7 +592,7 @@ class LookupHandler(APIHandler):
all_matches = []
for p in fingerprints:
if isinstance(p, TrackLookupQuery):
track_id = resolve_track_gid(self.ctx.db.get_fingerprint_db(), p.track_gid)
track_id = resolve_track_gid(self.ctx.db.get_fingerprint_db(read_only=True), p.track_gid)
if track_id:
matches = [FingerprintMatch(fingerprint_id=0, track_id=track_id, track_gid=p.track_gid, score=1.0)]
else:
......@@ -645,7 +645,7 @@ class SubmissionStatusHandler(APIHandler):
# type: (APIHandlerParams) -> Dict[str, Any]
assert isinstance(params, SubmissionStatusHandlerParams)
response = {'submissions': [{'id': id, 'status': 'pending'} for id in params.ids]}
tracks = lookup_submission_status(self.ctx.db.get_ingest_db(), params.ids)
tracks = lookup_submission_status(self.ctx.db.get_ingest_db(read_only=True), params.ids)
for submission in response['submissions']:
id = submission['id']
track_gid = tracks.get(id)
......
......@@ -56,8 +56,11 @@ class DatabasesConfig(BaseConfig):
# type: () -> None
self.databases = {
'app': DatabaseConfig(),
'app:ro': DatabaseConfig(),
'fingerprint': DatabaseConfig(),
'fingerprint:ro': DatabaseConfig(),
'ingest': DatabaseConfig(),
'ingest:ro': DatabaseConfig(),
'musicbrainz': DatabaseConfig(),
}
self.use_two_phase_commit = False
......@@ -80,13 +83,13 @@ class DatabasesConfig(BaseConfig):
self.use_two_phase_commit = parser.getboolean(section, 'two_phase_commit')
for name, sub_config in self.databases.items():
sub_section = '{}:{}'.format(section, name)
sub_config.read_section(parser, sub_section)
sub_config.read(parser, sub_section)
def read_env(self, prefix):
# type: (str) -> None
read_env_item(self, 'use_two_phase_commit', prefix + 'DATABASE_TWO_PHASE_COMMIT', convert=str_to_bool)
for name, sub_config in self.databases.items():
sub_prefix = prefix + 'DATABASE_' + name.upper() + '_'
sub_prefix = prefix + 'DATABASE_' + name.replace(':', '_').upper() + '_'
sub_config.read_env(sub_prefix)
......@@ -166,14 +169,21 @@ class DatabaseConfig(BaseConfig):
def read_section(self, parser, section):
# type: (RawConfigParser, str) -> None
self.user = parser.get(section, 'user')
self.name = parser.get(section, 'name')
if parser.has_option(section, 'host'):
self.host = parser.get(section, 'host')
if parser.has_option(section, 'port'):
self.port = parser.getint(section, 'port')
if parser.has_option(section, 'user'):
self.user = parser.get(section, 'user')
elif parser.has_option(section, 'user_file'):
user_file_path = parser.get(section, 'user_file')
self.user = open(user_file_path, 'rt').read().strip()
if parser.has_option(section, 'password'):
self.password = parser.get(section, 'password')
elif parser.has_option(section, 'password_file'):
password_file_path = parser.get(section, 'password_file')
self.password = open(password_file_path, 'rt').read().strip()
if parser.has_option(section, 'pool_size'):
self.pool_size = parser.getint(section, 'pool_size')
if parser.has_option(section, 'pool_recycle'):
......
......@@ -38,25 +38,29 @@ class DatabaseContext(object):
self.engines = script.db_engines
self.session = Session(**get_session_args(script))
def connection(self, bind_key):
# type: (str) -> Connection
def connection(self, bind_key, read_only=False):
# type: (str, bool) -> Connection
if read_only:
read_only_bind_key = bind_key + ':ro'
if read_only_bind_key in self.engines:
bind_key = read_only_bind_key
return self.session.connection(bind=self.engines[bind_key])
def get_app_db(self):
# type: () -> AppDB
return AppDB(self.connection('app'))
def get_app_db(self, read_only=False):
# type: (bool) -> AppDB
return AppDB(self.connection('app', read_only))
def get_fingerprint_db(self):
# type: () -> FingerprintDB
return FingerprintDB(self.connection('fingerprint'))
def get_fingerprint_db(self, read_only=False):
# type: (bool) -> FingerprintDB
return FingerprintDB(self.connection('fingerprint', read_only))
def get_ingest_db(self):
# type: () -> IngestDB
return IngestDB(self.connection('ingest'))
def get_ingest_db(self, read_only=False):
# type: (bool) -> IngestDB
return IngestDB(self.connection('ingest', read_only))
def get_musicbrainz_db(self):
# type: () -> MusicBrainzDB
return MusicBrainzDB(self.connection('musicbrainz'))
def get_musicbrainz_db(self, read_only=True):
# type: (bool) -> MusicBrainzDB
return MusicBrainzDB(self.connection('musicbrainz', read_only))
def close(self):
# type: () -> None
......
......@@ -28,25 +28,29 @@ class Database(object):
self.session_factory.configure(**get_session_args(script))
self.session = scoped_session(self.session_factory, scopefunc)
def connection(self, bind_key):
# type: (str) -> Connection
def connection(self, bind_key, read_only=False):
# type: (str, bool) -> Connection
if read_only:
read_only_bind_key = bind_key + ':ro'
if read_only_bind_key in self.engines:
bind_key = read_only_bind_key
return self.session.connection(bind=self.engines[bind_key])
def get_app_db(self):
# type: () -> AppDB
return AppDB(self.connection('app'))
def get_app_db(self, read_only=False):
# type: (bool) -> AppDB
return AppDB(self.connection('app', read_only))
def get_fingerprint_db(self):
# type: () -> FingerprintDB
return FingerprintDB(self.connection('fingerprint'))
def get_fingerprint_db(self, read_only=False):
# type: (bool) -> FingerprintDB
return FingerprintDB(self.connection('fingerprint', read_only))
def get_ingest_db(self):
# type: () -> IngestDB
return IngestDB(self.connection('ingest'))
def get_ingest_db(self, read_only=False):
# type: (bool) -> IngestDB
return IngestDB(self.connection('ingest', read_only))
def get_musicbrainz_db(self):
# type: () -> MusicBrainzDB
return MusicBrainzDB(self.connection('musicbrainz'))
def get_musicbrainz_db(self, read_only=True):
# type: (bool) -> MusicBrainzDB
return MusicBrainzDB(self.connection('musicbrainz', read_only))
db = Database()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment