Untitled
unknown
plain_text
a year ago
7.2 kB
5
Indexable
CLUSTER_HOST = 'remote_host' r = StrictRedis(CLUSTER_HOST, 6379) """ CREATE TABLE `experiments` ( `experiment_id` int AUTO_INCREMENT, `title` varchar(100) NOT NULL, `is_disabled` tinyint DEFAULT '0', `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `start_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `end_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`experiment_id`) ) ENGINE = InnoDB CREATE TABLE `experiment_variants` ( `variant_id` int AUTO_INCREMENT NOT NULL, `experiment_id` int NOT NULL, `title` varchar(50) NOT NULL, `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`variant_id`), KEY `experiment_id` (`experiment_id`), CONSTRAINT `experiment_variants_ibfk_1` FOREIGN KEY (`experiment_id`) REFERENCES `experiments` (`experiment_id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB CREATE TABLE `device_experiments` ( `id` int AUTO_INCREMENT NOT NULL , `device_id` int NOT NULL, `experiment_id` int NOT NULL, `variant_id` int NOT NULL, `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `variant_id` (`variant_id`), KEY `experiment_id` (`experiment_id`), CONSTRAINT `device_experiments_ibfk_1` FOREIGN KEY (`variant_id`) REFERENCES `experiment_variants` (`variant_id`) ON DELETE RESTRICT ON UPDATE RESTRICT, CONSTRAINT `device_experiments_ibfk_2` FOREIGN KEY (`experiment_id`) REFERENCES `experiments` (`experiment_id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB """ def get_experiment_by_id(experiment_id): key, ttl = f"exp:detail:{experiment_id}", 3600 * 12 details = r.get(key) if details: return json.loads(details) query = f"""SELECT * FROM experiments where experiment_id = '{experiment_id}'""" cursor = connection.cursor() cursor.execute(query) data = cursor.fetchone() cursor.close() details = {} if data: details = data[0] r.set(key, json.dumps(details)) r.expire(key, ttl) return details def get_variant_by_id(variant_id): """ Get variant details by variant id :param variant_id: Variant Id :type variant_id: str :return: Variant Details :rtype: dict """ cache_key, ttl = f'variant:detail:{variant_id}', 3600 * 12 variant = r.get(cache_key) if variant: variant_json = json.loads(variant) return variant_json query = f"""SELECT * FROM experiment_variants where variant_id = '{variant_id}'""" cursor = connection.cursor() cursor.execute(query) data = cursor.fetchone() cursor.close() details = {} if data: details = data[0] r.set(cache_key, json.dumps(details)) r.expire(cache_key, ttl) return details def get_variants_by_experiment_id(experiment_id): cache_key, ttl = f'exp:variants:{experiment_id}', 3600 * 12 variant_details = r.get(cache_key) if variant_details: variants_list = json.loads(variant_details) return variants_list query = f"""SELECT variant_id FROM experiment_variants where experiment_id = '{experiment_id}'""" cursor = connection.cursor() cursor.execute(query) data = cursor.fetchall() cursor.close() variant_ids = [] for row in data: variant_id = row[0] variant_ids.append(variant_id) if variant_ids: r.set(cache_key, json.dumps(variant_ids)) return variant_ids def get_device_variant(device_id, experiment_id): cache_key, ttl = f'device:experiment_var:{device_id}:{experiment_id}', 3600 * 12 variant = r.get(cache_key) if variant: variant_id = json.loads(variant) return variant_id query = f""" SELECT variant_id FROM device_experiments where device_id = '{device_id}' and experiment_id = '{experiment_id}' """ cursor = connection.cursor() cursor.execute(query) data = cursor.fetchone() cursor.close() variant_id = None if data: variant_id = data[0] r.set(cache_key, json.dumps(variant_id)) r.expire(cache_key, ttl) return variant_id class BaseExp: @staticmethod def allocate_variant(device_id, experiment_id): exp_details = get_experiment_by_id(experiment_id) if exp_details.get('is_disabled'): return {} existing_variant_id = get_device_variant(device_id, experiment_id) if existing_variant_id: return get_variant_by_id(existing_variant_id) variants = get_variants_by_experiment_id(experiment_id) if not variants: return {} chosen_variant = random.choice(variants) query = f""" INSERT INTO device_experiments (device_id, experiment_id, variant_id) VALUES ('{device_id}', '{experiment_id}', '{chosen_variant}') """ cursor = connection.cursor() cursor.execute(query) cursor.close() chosen_variant_details = get_variant_by_id(chosen_variant) return chosen_variant_details class Exp1(BaseExp): def allocate_variant(self, device_id, experiment_id): variant = self.allocate_variant(device_id, experiment_id) return variant class Exp2(BaseExp): def allocate_variant(self, device_id, experiment_id): variant = self.allocate_variant(device_id, experiment_id) return variant class Exp3(BaseExp): def allocate_variant(self, device_id, experiment_id): variant = self.allocate_variant(device_id, experiment_id) return variant class Exp4(BaseExp): def allocate_variant(self, device_id, experiment_id): variant = self.allocate_variant(device_id, experiment_id) return variant class Exp5(BaseExp): def allocate_variant(self, device_id, experiment_id): variant = self.allocate_variant(device_id, experiment_id) return variant def launch(request): data = request.GET.dict() # Parameters coming in the request user_id = data.get('user_id') device_id = data.get('device_id') platform = data.get('platform') response = {} if not device_id and not user_id: return Response( { 'error': { 'message': 'Cannot fetch config' } }, status=400 ) var1 = Exp1().allocate_variant(device_id, 1) var2 = Exp2().allocate_variant(device_id, 2) Exp3().allocate_variant(device_id, 3) Exp4().allocate_variant(device_id, 4) Exp5().allocate_variant(device_id, 5) if var1 and var1.get('title', '') == "B": response['detail_1'] = 'details1' response['detail_2'] = True if var2 and var2.get('title', '') == "B": response['detail_1'] = 'details2' response['detail_2'] = False return response """ - launch() -> Very high latency API - Number of redis calls per request is very high - Redis get calls have high latencies Redis Cluster -> Single cloud hosted redis cluster """
Editor is loading...
Leave a Comment