Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vine: errors are not correctly propagated in FuturesExecutor #3920

Open
gpauloski opened this issue Aug 20, 2024 · 0 comments
Open

Vine: errors are not correctly propagated in FuturesExecutor #3920

gpauloski opened this issue Aug 20, 2024 · 0 comments
Assignees

Comments

@gpauloski
Copy link
Contributor

gpauloski commented Aug 20, 2024

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants