# RhodeCode VCSServer provides access to different vcs backends via network. # Copyright (C) 2014-2023 RhodeCode GmbH # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import logging import redis from ..lib import rc_cache from ..lib.ext_json import json log = logging.getLogger(__name__) redis_client = None class RedisTxnClient: def __init__(self, url): self.url = url self._create_client(url) def _create_client(self, url): connection_pool = redis.ConnectionPool.from_url(url) self.writer_client = redis.StrictRedis( connection_pool=connection_pool ) self.reader_client = self.writer_client def set(self, key, value): self.writer_client.set(key, value) def get(self, key): return self.reader_client.get(key) def delete(self, key): self.writer_client.delete(key) def get_redis_client(url=''): global redis_client if redis_client is not None: return redis_client if not url: from vcsserver import CONFIG url = CONFIG['vcs.svn.redis_conn'] redis_client = RedisTxnClient(url) return redis_client def get_txn_id_data_key(repo_path, svn_txn_id): log.debug('svn-txn-id: %s, obtaining data path', svn_txn_id) repo_key = rc_cache.utils.compute_key_from_params(repo_path) final_key = f'{repo_key}.{svn_txn_id}.svn_txn_id' log.debug('computed final key: %s', final_key) return final_key def store_txn_id_data(repo_path, svn_txn_id, data_dict): log.debug('svn-txn-id: %s, storing data', svn_txn_id) if not svn_txn_id: log.warning('Cannot store txn_id because it is empty') return redis_conn = get_redis_client() store_key = get_txn_id_data_key(repo_path, svn_txn_id) store_data = json.dumps(data_dict) redis_conn.set(store_key, store_data) def get_txn_id_from_store(repo_path, svn_txn_id, rm_on_read=False): """ Reads txn_id from store and if present returns the data for callback manager """ log.debug('svn-txn-id: %s, retrieving data', svn_txn_id) redis_conn = get_redis_client() store_key = get_txn_id_data_key(repo_path, svn_txn_id) data = {} redis_conn.get(store_key) raw_data = 'not-set' try: raw_data = redis_conn.get(store_key) if not raw_data: raise ValueError(f'Failed to get txn_id metadata, from store: {store_key}') data = json.loads(raw_data) except Exception: log.exception('Failed to get txn_id metadata: %s', raw_data) if rm_on_read: log.debug('Cleaning up txn_id at %s', store_key) redis_conn.delete(store_key) return data