Skip to content

Vine: errors are not correctly propagated in FuturesExecutor #3920

@gpauloski

Description

@gpauloski

I mentioned last week that I noted some small errors I ran into the FuturesExecutor. I was able to patch most of them when running my experiments, so I'd be happy to spend some time today/tomorrow on a PR. I'm not quite sure about (2) though, as it's an error in the Manager and maybe unrelated to the FuturesExecutor.

  1. Exceptions are not raised by Future.result() nor is Future.exception() set.
from ndcctools.taskvine import FuturesExecutor

class TestException(Exception):
    pass

def success() -> bool:
    return True

def failure() -> None:
    raise TestException()

with FuturesExecutor(manager_name='exceptions-example') as executor:
    future = executor.submit(success)
    assert future.result()

    future = executor.submit(failure)
    try:
        future.result()
    except TestException:
        pass
    else:
        raise RuntimeError('Future did not raise exception')

    assert isinstance(future.exception(), TestException)
  1. Future.done() does not work.
from ndcctools.taskvine import FuturesExecutor

def success() -> bool:
    return True

with FuturesExecutor(manager_name='done-example') as executor:
    future = executor.submit(success)
    assert future.result()
    assert future.done()
Traceback (most recent call last):
  File "/Users/jgpaul/workspace/cctools/scratch/done.py", line 9, in <module>
    assert future.done()
           ^^^^^^^^^^^^^
  File "/Users/jgpaul/miniconda3/envs/cctools-build/lib/python3.12/site-packages/ndcctools/taskvine/futures.py", line 258, in done
    state = self._task._module_manager.task_state(self._task.id)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jgpaul/miniconda3/envs/cctools-build/lib/python3.12/site-packages/ndcctools/taskvine/manager.py", line 393, in task_state
    return cvine.vine_task_state(self._taskvine, task_id)
           ^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'ndcctools.taskvine.cvine' has no attribute 'vine_task_state'. Did you mean: 'vine_task_create'?
  1. Future.result(timeout=TIMEOUT) returns 'result_pending' instead of raising TimeoutError.
from ndcctools.taskvine import FuturesExecutor
from ndcctools.taskvine.futures import as_completed

def timeout() -> None:
    import time
    time.sleep(60)

with FuturesExecutor(manager_name='done-example') as executor:
    future = executor.submit(timeout)

    try:
        # This returns "result_pending" instead of raising TimeoutError.
        future.result(timeout=1)
    except TimeoutError:
        pass
    else:
        raise RuntimeError('result() did not raise TimeoutError')
  1. TimeoutErrors are not correctly raised by as_completed().

Rather, as_completed() returns the class TimeoutError.

from ndcctools.taskvine import FuturesExecutor
from ndcctools.taskvine.futures import as_completed

def timeout() -> None:
    import time
    time.sleep(60)

with FuturesExecutor(manager_name='done-example') as executor:
    future = executor.submit(timeout)

    for future in as_completed([future], timeout=1):
        future.result()
  1. Future.result() of a FutureFunctionCall returns the string traceback instead of raising the exception from the task.
from ndcctools.taskvine import FuturesExecutor

def failure() -> None:
    raise Exception('Test')

with FuturesExecutor(manager_name='done-example') as executor:
    libtask = executor.create_library_from_functions('test-library', failure)
    executor.install_library(libtask)

    task = executor.future_funcall('test-library', 'failure')
    future = executor.submit(task)

    result = future.result()
    # Result is the string traceback. Rather, result() should raise
    # the exception.
    assert isinstance(result, str)
    print(result)

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions