def all(cls, list_name, offset=0, limit=-1): # -1 表示最后一个, # ZRANGE salary 0 - 1 WITHSCORES # 显示整个有序集成员 ############################################ if limit != -1: limit -= 1 if offset != 0: offset -= 1 # api 输入 offset =1 ,limit=5 # 实际 offset =0 ,limit=4 # 为了符合大众的概念??? ############################################ # Redis 有序集合结构(单元唯一,带有的分数可以相同) # http://www.runoob.com/redis/redis-sorted-sets.html #z range, 正序 # z rev range ,反序列 ids = redis_connection.zrevrange(list_name, offset, limit) #批量执行,想象把很对ids放入一个管道,然后一起发送过去 pipe = redis_connection.pipeline() for id in ids: pipe.get(id) tasks = [cls.create_from_data(data) for data in pipe.execute()] return tasks
def enqueue_query(query, data_source, user_id, scheduled_query=None, metadata={}): query_hash = gen_query_hash(query) logging.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[%s] Found existing job: %s", query_hash, job_id) job = QueryTask(job_id=job_id) if job.ready(): logging.info("[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete(_job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() time_limit = None if scheduled_query: queue_name = data_source.scheduled_queue_name scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name scheduled_query_id = None time_limit = settings.ADHOC_QUERY_TIME_LIMIT result = execute_query.apply_async(args=(query, data_source.id, metadata, user_id, scheduled_query_id), queue=queue_name, time_limit=time_limit) job = QueryTask(async_result=result) tracker = QueryTaskTracker.create( result.id, 'created', query_hash, data_source.id, scheduled_query is not None, metadata) tracker.save(connection=pipe) logging.info("[%s] Created new job: %s", query_hash, job.id) pipe.set(_job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def add_task(cls, query, data_source, scheduled=False, metadata={}): query_hash = gen_query_hash(query) logging.info("[Manager][%s] Inserting job", query_hash) logging.info("[Manager] Metadata: [%s]", metadata) try_count = 0 job = None while try_count < cls.MAX_RETRIES: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(cls._job_lock_id(query_hash, data_source.id)) job_id = pipe.get(cls._job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[Manager][%s] Found existing job: %s", query_hash, job_id) job = cls(job_id=job_id) if job.ready(): logging.info( "[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete( QueryTask._job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled: queue_name = data_source.scheduled_queue_name else: queue_name = data_source.queue_name result = execute_query.apply_async(args=(query, data_source.id, metadata), queue=queue_name) job = cls(async_result=result) logging.info("[Manager][%s] Created new job: %s", query_hash, job.id) pipe.set(cls._job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def enqueue_query(query, data_source, scheduled=False, metadata={}): query_hash = gen_query_hash(query) logging.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[%s] Found existing job: %s", query_hash, job_id) job = QueryTask(job_id=job_id) tracker = QueryTaskTracker.get_by_task_id(job_id, connection=pipe) # tracker might not exist, if it's an old job if scheduled and tracker: tracker.update(retries=tracker.retries+1) elif tracker: tracker.update(scheduled_retries=tracker.scheduled_retries+1) if job.ready(): logging.info("[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete(_job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled: queue_name = data_source.scheduled_queue_name else: queue_name = data_source.queue_name result = execute_query.apply_async(args=(query, data_source.id, metadata), queue=queue_name) job = QueryTask(async_result=result) tracker = QueryTaskTracker.create(result.id, 'created', query_hash, data_source.id, scheduled, metadata) tracker.save(connection=pipe) logging.info("[%s] Created new job: %s", query_hash, job.id) pipe.set(_job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def all(cls, list_name, offset=0, limit=-1): if limit != -1: limit -= 1 if offset != 0: offset -= 1 ids = redis_connection.zrevrange(list_name, offset, limit) pipe = redis_connection.pipeline() for id in ids: pipe.get(id) tasks = [cls.create_from_data(data) for data in pipe.execute()] return tasks
def add_task(cls, query, data_source, scheduled=False, metadata={}): query_hash = gen_query_hash(query) logging.info("[Manager][%s] Inserting job", query_hash) logging.info("[Manager] Metadata: [%s]", metadata) try_count = 0 job = None while try_count < cls.MAX_RETRIES: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(cls._job_lock_id(query_hash, data_source.id)) job_id = pipe.get(cls._job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[Manager][%s] Found existing job: %s", query_hash, job_id) job = cls(job_id=job_id) if job.ready(): logging.info("[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete(QueryTask._job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled: queue_name = data_source.scheduled_queue_name else: queue_name = data_source.queue_name result = execute_query.apply_async(args=(query, data_source.id, metadata), queue=queue_name) job = cls(async_result=result) logging.info("[Manager][%s] Created new job: %s", query_hash, job.id) pipe.set(cls._job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def add_task(cls, query, data_source, scheduled=False): query_hash = gen_query_hash(query) logging.info("[Manager][%s] Inserting job", query_hash) try_count = 0 job = None while try_count < cls.MAX_RETRIES: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(cls._job_lock_id(query_hash, data_source.id)) job_id = pipe.get(cls._job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[Manager][%s] Found existing job: %s", query_hash, job_id) job = cls(job_id=job_id) else: pipe.multi() if scheduled: queue_name = data_source.scheduled_queue_name else: queue_name = data_source.queue_name result = execute_query.apply_async(args=(query, data_source.id), queue=queue_name) job = cls(async_result=result) logging.info("[Manager][%s] Created new job: %s", query_hash, job.id) pipe.set(cls._job_lock_id(query_hash, data_source.id), job.id) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def enqueue_query(query, data_source, user_id, is_api_key=False, scheduled_query=None, metadata={}): query_hash = gen_query_hash(query) logging.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[%s] Found existing job: %s", query_hash, job_id) job = QueryTask(job_id=job_id) if job.ready(): logging.info("[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete(_job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled_query: queue_name = data_source.scheduled_queue_name scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name scheduled_query_id = None args = (query, data_source.id, metadata, user_id, scheduled_query_id, is_api_key) argsrepr = json_dumps({ 'org_id': data_source.org_id, 'data_source_id': data_source.id, 'enqueue_time': time.time(), 'scheduled': scheduled_query_id is not None, 'query_id': metadata.get('Query ID'), 'user_id': user_id }) time_limit = settings.dynamic_settings.query_time_limit(scheduled_query, user_id, data_source.org_id) result = execute_query.apply_async(args=args, argsrepr=argsrepr, queue=queue_name, time_limit=time_limit) job = QueryTask(async_result=result) logging.info("[%s] Created new job: %s", query_hash, job.id) pipe.set(_job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def enqueue_query(query, data_source, user_id, is_api_key=False, scheduled_query=None, metadata={}): query_hash = gen_query_hash(query) logger.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logger.info("[%s] Found existing job: %s", query_hash, job_id) job_complete = None try: job = Job.fetch(job_id) job_exists = True status = job.get_status() job_complete = status in [ JobStatus.FINISHED, JobStatus.FAILED ] if job_complete: message = "job found is complete (%s)" % status except NoSuchJobError: message = "job found has expired" job_exists = False if job_complete or not job_exists: logger.info("[%s] %s, removing lock", query_hash, message) redis_connection.delete( _job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled_query: queue_name = data_source.scheduled_queue_name scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name scheduled_query_id = None time_limit = settings.dynamic_settings.query_time_limit( scheduled_query, user_id, data_source.org_id) metadata["Queue"] = queue_name queue = Queue(queue_name) enqueue_kwargs = { "user_id": user_id, "scheduled_query_id": scheduled_query_id, "is_api_key": is_api_key, "job_timeout": time_limit, "meta": { "data_source_id": data_source.id, "org_id": data_source.org_id, "scheduled": scheduled_query_id is not None, "query_id": metadata.get("Query ID"), "user_id": user_id, }, } if not scheduled_query: enqueue_kwargs["result_ttl"] = settings.JOB_EXPIRY_TIME job = queue.enqueue(execute_query, query, data_source.id, metadata, **enqueue_kwargs) logger.info("[%s] Created new job: %s", query_hash, job.id) pipe.set( _job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME, ) pipe.execute() break except redis.WatchError: continue if not job: logger.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def enqueue_query( query, data_source, user_id, is_api_key=False, scheduled_query=None, metadata={} ): query_id = metadata.get("Query ID", "unknown") query_hash = gen_query_hash(query) get_logger().info("[query_id=%s] [query_hash=%s] Inserting job", query_id, query_hash) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: job_status = "UNKNOWN" job_complete = False job_cancelled = "False" try: job = Job.fetch(job_id) job_exists = True job_status = job.get_status() job_complete = job_status in [JobStatus.FINISHED, JobStatus.FAILED] if job.is_cancelled: job_cancelled = "True" except NoSuchJobError: job_exists = False job_status = "EXPIRED" get_logger().info("[query_id=%s] [query_hash=%s] Found existing job [job.id=%s] [job_status=%s] [job_cancelled=%s]", query_id, query_hash, job_id, job_status, job_cancelled) if job_complete or (not job_exists): #get_logger().info("[query_id=%s] [query_hash=%s] [job.id=%s], removing redis lock", query_id, query_hash, job_id) redis_connection.delete(_job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled_query: queue_name = data_source.scheduled_queue_name #默认都是scheduled_queries scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name #默认都是queries scheduled_query_id = None time_limit = settings.dynamic_settings.query_time_limit( scheduled_query, user_id, data_source.org_id ) metadata["Queue"] = queue_name metadata["Enqueue Time"] = time.time() queue = Queue(queue_name) enqueue_kwargs = { "user_id": user_id, "scheduled_query_id": scheduled_query_id, "is_api_key": is_api_key, "job_timeout": time_limit, "meta": { "data_source_id": data_source.id, "org_id": data_source.org_id, "scheduled": scheduled_query_id is not None, "query_id": query_id, "user_id": user_id, }, } if not scheduled_query: enqueue_kwargs["result_ttl"] = settings.JOB_EXPIRY_TIME job = queue.enqueue( execute_query, query, data_source.id, metadata, **enqueue_kwargs ) get_logger().info("[query_id=%s] [query_hash=%s] Created new job [job.id=%s]", query_id, query_hash, job.id) pipe.set( _job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME, ) pipe.execute() break except redis.WatchError: get_logger().error("[query_id=%s] [query_hash=%s] redis.WatchError, try_count = %d", query_id, query_hash, try_count) continue if not job: get_logger().error("[Manager] [query_id=%s] [query_hash=%s] Failed adding job for query.", query_id, query_hash) return job
def enqueue_query(query, data_source, user_id, is_api_key=False, scheduled_query=None, metadata={}): query_hash = gen_query_hash(query) logging.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[%s] Found existing job: %s", query_hash, job_id) job = Job.fetch(job_id) status = job.get_status() if status in [JobStatus.FINISHED, JobStatus.FAILED]: logging.info( "[%s] job found is ready (%s), removing lock", query_hash, status, ) redis_connection.delete( _job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() if scheduled_query: queue_name = data_source.scheduled_queue_name scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name scheduled_query_id = None time_limit = settings.dynamic_settings.query_time_limit( scheduled_query, user_id, data_source.org_id) metadata["Queue"] = queue_name queue = Queue(queue_name) job = queue.enqueue( execute_query, query, data_source.id, metadata, user_id=user_id, scheduled_query_id=scheduled_query_id, is_api_key=is_api_key, job_timeout=time_limit, ) logging.info("[%s] Created new job: %s", query_hash, job.id) pipe.set( _job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME, ) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job
def enqueue_query(query, data_source, user_id, is_api_key=False, scheduled_query=None, metadata={}): query_hash = gen_query_hash(query) logging.info("Inserting job for %s with metadata=%s", query_hash, metadata) try_count = 0 job = None while try_count < 5: try_count += 1 pipe = redis_connection.pipeline() try: pipe.watch(_job_lock_id(query_hash, data_source.id)) job_id = pipe.get(_job_lock_id(query_hash, data_source.id)) if job_id: logging.info("[%s] Found existing job: %s", query_hash, job_id) job = QueryTask(job_id=job_id) if job.ready(): logging.info("[%s] job found is ready (%s), removing lock", query_hash, job.celery_status) redis_connection.delete(_job_lock_id(query_hash, data_source.id)) job = None if not job: pipe.multi() time_limit = None if scheduled_query: queue_name = data_source.scheduled_queue_name scheduled_query_id = scheduled_query.id else: queue_name = data_source.queue_name scheduled_query_id = None time_limit = settings.ADHOC_QUERY_TIME_LIMIT args = (query, data_source.id, metadata, user_id, scheduled_query_id, is_api_key) argsrepr = json_dumps({ 'org_id': data_source.org_id, 'data_source_id': data_source.id, 'enqueue_time': time.time(), 'scheduled': scheduled_query_id is not None, 'query_id': metadata.get('Query ID'), 'user_id': user_id }) result = execute_query.apply_async(args=args, argsrepr=argsrepr, queue=queue_name, time_limit=time_limit) job = QueryTask(async_result=result) logging.info("[%s] Created new job: %s", query_hash, job.id) pipe.set(_job_lock_id(query_hash, data_source.id), job.id, settings.JOB_EXPIRY_TIME) pipe.execute() break except redis.WatchError: continue if not job: logging.error("[Manager][%s] Failed adding job for query.", query_hash) return job