def wait_until_complete(self, sleep_duration=1): """ Blocks until the query is in a state where its result is determinate (i.e., one of "know", "errored", "completed", "cancelled"). """ if self.is_executing or self.is_queued or self.is_resetting: while not (self.is_finished_executing or self.is_cancelled or self.is_known): _sleep(sleep_duration)
def invalidate_db_cache(self, name=None, schema=None, cascade=True, drop=True): """ Drops this table, and (by default) any that depend on it, as well as removing them from the cache metadata table. If the table is currently being dropped from elsewhere, this method will block and return when the table has been removed. Raises ------ QueryResetFailedException If the query wasn't succesfully removed Parameters ---------- name : str Name of the table schema : str Schema of the table cascade : bool Set to false to remove only this table from cache drop : bool Set to false to remove the cache record without dropping the table """ log = partial(logger.debug, query_id=self.query_id, action="invalidate_db_cache") q_state_machine = QueryStateMachine(get_redis(), self.query_id, get_db().conn_id) log("Resetting state machine.") current_state, this_thread_is_owner = q_state_machine.reset() if this_thread_is_owner: log("Reset state machine.") con = get_db().engine try: log("Getting table reference.") table_reference_to_this_query = self.get_table() if table_reference_to_this_query is not self: log("Invalidating table reference cache.") table_reference_to_this_query.invalidate_db_cache( cascade=cascade, drop=drop) # Remove any Table pointing as this query except (ValueError, NotImplementedError) as e: log("Query not stored - no table..") pass # This cache record isn't actually stored try: log = partial(log, table_name=self.fully_qualified_table_name) except NotImplementedError: pass # Not a storable by default table try: deps = get_db().fetch( """SELECT obj FROM cache.cached LEFT JOIN cache.dependencies ON cache.cached.query_id=cache.dependencies.query_id WHERE depends_on='{}'""".format(self.query_id)) with con.begin(): con.execute("DELETE FROM cache.cached WHERE query_id=%s", (self.query_id, )) log("Deleted cache record.") if drop: con.execute("DROP TABLE IF EXISTS {}".format( self.fully_qualified_table_name)) log("Dropped cache table.") if cascade: for rec in deps: dep = pickle.loads(rec[0]) log( "Cascading to dependent.", dependency=dep.fully_qualified_table_name, ) dep.invalidate_db_cache() else: log("Not cascading to dependents.") except NotImplementedError: logger.info("Table has no standard name.") # Outside of cache schema table if schema is not None: full_name = "{}.{}".format(schema, name) else: full_name = name log("Dropping table outside cache schema.", table_name=full_name) with con.begin(): con.execute("DROP TABLE IF EXISTS {}".format(full_name)) q_state_machine.finish_resetting() elif q_state_machine.is_resetting: log("Query is being reset from elsewhere, waiting for reset to finish." ) while q_state_machine.is_resetting: _sleep(1) if not q_state_machine.is_known: raise QueryResetFailedException(self.query_id)