def wait_for_conc(cache_map: AbstractConcCache, q: Tuple[str, ...], subchash: Optional[str], minsize: int) -> bool: """ Find a conc. calculation record in cache (matching provided subchash and query) and wait until a result is available. The behavior is modified by 'minsize' (see below). arguments: minsize -- min. size of concordance we accept: 1) > 0 => we want at least some lines to be available => short time limit 2) == -1 => we want the whole concordance to be ready => longer time limit 3) == 0 => we only care whether the file exists => sort time limit """ time_limit = 5 if minsize >= 0 else 30 t0 = t1 = time.time() i = 1 has_result, finished = _check_result(cache_map, q, subchash, minsize) while not finished and t1 - t0 < time_limit: time.sleep(i * 0.1) i += 1 t1 = time.time() has_result, finished = _check_result(cache_map, q, subchash, minsize) if not os.path.isfile(cache_map.cache_file_path(subchash, q)): if finished: # cache vs. filesystem mismatch cache_map.del_entry(subchash, q) return False return True
def _check_result(cache_map: AbstractConcCache, q: Tuple[str, ...], subchash: Optional[str], minsize: int) -> Tuple[bool, bool]: """ Check for result status while validating calculation status. In case of an error an Exception can be thrown. return: 2-tuple ["has min. acceptable result", "is finished"] Return True if a specific concordance calculation has not reached a minimal viewable size yet. Otherwise it returns False (= we can show a partial result). In case the calculation finished due to an error the function throws a ConcCalculationStatusException. """ status = cache_map.get_calc_status(subchash, q) if status is None: cache_map.del_full_entry(subchash, q) raise ConcCalculationStatusException( f'Missing status information for ({subchash}, {q}).') err = status.test_error(TASK_TIME_LIMIT) if err is not None: cache_map.del_full_entry(subchash, q) raise err return not status.has_some_result(minsize=minsize), status.finished
def _check_result(cache_map: AbstractConcCache, q: Tuple[str, ...], subchash: Optional[str], minsize: int) -> Tuple[bool, bool]: """ Check for result status while validating calculation status. In case of an error an Exception can be thrown. It is perfectly fine to not find an entry for some subchash+q combination (in such case, False, False is returned). return: 2-tuple ["has min. acceptable result", "is finished"] Return True if a specific concordance calculation has not reached a minimal viewable size yet. Otherwise it returns False (= we can show a partial result). In case the calculation finished due to an error the function throws a ConcCalculationStatusException. """ status = cache_map.get_calc_status(subchash, q) if status is None: return False, False status.check_for_errors(TASK_TIME_LIMIT) if status.error is not None: cache_map.del_full_entry(subchash, q) raise status.error return status.has_some_result(minsize=minsize), status.finished
def cancel_async_task(cache_map: AbstractConcCache, subchash: Optional[str], q: Tuple[str, ...]): cachefile = cache_map.cache_file_path(subchash, q) status = cache_map.get_calc_status(subchash, q) if status: try: if status.task_id: app = bgcalc.calc_backend_client(settings) app.control.revoke(status.task_id, terminate=True, signal='SIGKILL') except IOError: pass cache_map.del_entry(subchash, q) del_silent(cachefile)
def cancel_conc_task(cache_map: AbstractConcCache, subchash: Optional[str], q: Tuple[str, ...]): """ Removes conc. cache entry and also a respective calculation task (silently). """ cachefile = cache_map.readable_cache_path(subchash, q) status = cache_map.get_calc_status(subchash, q) if status: try: if status.task_id: worker = bgcalc.calc_backend_client(settings) worker.control.revoke(status.task_id, terminate=True, signal='SIGKILL') except (IOError, CalcTaskNotFoundError): pass cache_map.del_entry(subchash, q) del_silent(cachefile)