def test_executor(): """ Test the executor """ ex = Executor() ex2 = Executor() assert ex is ex2 ex3 = pickle.loads(pickle.dumps(ex)) assert ex3 is ex assert len(_executor_cache) == 1 assert ex.impl.submit(lambda x: x * 2, 4).result() == 8 ex.shutdown(wait=True) ex3.shutdown(wait=False) # Executor should be shutdown at this point with pytest.raises(RuntimeError): ex2.impl.submit(lambda x: x * 2, 4) assert len(_executor_cache) == 1 # Force collection del ex, ex2, ex3 # Check that callbacks assert len(_executor_cache) == 0
def __init__(self, factory, *args, **kwargs): """ Parameters ---------- factory : callable Function which creates the CASA table *args : tuple Positional arguments passed to factory. **kwargs : dict Keyword arguments passed to factory. __executor_key__ : str, optional Executor key. Identifies a unique threadpool in which table operations will be performed. """ # Save the arguments as keys for pickling and tokenising self._factory = factory self._args = args self._kwargs = kwargs # NOTE(sjperkins) # Copy the kwargs and remove (any) __executor_key__ # This is smelly but we do this to maintain # key uniqueness derived from # the *args and **kwargs in the MetaClass # as well as uniqueness when pickling/unpickling # A named keyword is possible but # TableProxy(*args, *kwargs) # doesn't produce the same unique key as # TableProxy(*args, ex_key=..., **kwargs) kwargs = kwargs.copy() self._ex_key = kwargs.pop("__executor_key__", STANDARD_EXECUTOR) # Store a reference to the Executor wrapper class # so that the Executor is retained while this TableProxy # still lives self._ex_wrapper = ex = Executor(key=self._ex_key) self._table_future = table = ex.impl.submit(factory, *args, **kwargs) weakref.finalize(self, _table_future_finaliser, ex, table, args, kwargs) # Reference to the internal ThreadPoolExecutor self._ex = ex.impl # Private, should be inaccessible self._write = False self._writeable = ex.impl.submit(_iswriteable, table).result() should_be_writeable = not kwargs.get('readonly', True) if self._writeable is False and should_be_writeable: # NOTE(sjperkins) # This seems to happen if you've opened a WSRT.MS with # readonly=False, and then you try to open WSRT.MS::SUBTABLE # with readonly=False. # Solution is to open WSRT.MS/SUBTABLE to avoid the locking, # which may introduce it's own set of issues raise RuntimeError("%s was opened as readonly=False but " "table.iswritable()==False" % table.name())
def test_executor_keys(): """ Test executor keys """ ex = Executor("foo") ex2 = Executor("bar") ex3 = Executor("foo") ex4 = Executor() assert len(_executor_cache) == 3 assert ex is not ex2 assert ex is ex3 assert pickle.loads(pickle.dumps(ex)) is ex3 assert pickle.loads(pickle.dumps(ex2)) is not ex3 del ex, ex2, ex3, ex4 assert len(_executor_cache) == 0