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: add wait and as_completed for futures #3876

Merged

Conversation

BarrySlyDelgado
Copy link
Contributor

@BarrySlyDelgado BarrySlyDelgado commented Jun 25, 2024

Proposed Changes

This adds module functions wait and as_completed to the vine futures. in regard to #3835

Merge Checklist

The following items must be completed before PRs can be merge.
Check these off to verify you have completed all steps.

  • make test Run local tests prior to pushing.
  • make format Format source code to comply with lint policies. Note that some lint errors can only be resolved manually (e.g., Python)
  • make lint Run lint on source code prior to pushing.
  • Manual Update Update the manual to reflect user-visible changes.
  • Type Labels Select a github label for the type: bugfix, enhancement, etc.
  • Product Labels Select a github label for the product: TaskVine, Makeflow, etc.
  • PR RTM Mark your PR as ready to merge.

@btovar
Copy link
Member

btovar commented Jun 26, 2024

@BarrySlyDelgado Is there an easy way to add a test for this one?

@BarrySlyDelgado
Copy link
Contributor Author

I'll create a test that tests these methods.

@gpauloski
Copy link
Contributor

Thanks, @BarrySlyDelgado! Is it also possible to either call super().__init__() in VineFuture or have VineFuture not inherit from Future?

I'm not sure which option is best, but I think both repr(future) and future.exception() will fail because both those methods are getting inherited. I've only briefly looked so do correct me if I'm wrong.

@BarrySlyDelgado
Copy link
Contributor Author

I think i'll have it call super().__init() since we're leaning into having our executor conform more to concurrent.futures. I'll do some testing to incorporate it.

@dthain
Copy link
Member

dthain commented Jul 10, 2024

@BarrySlyDelgado what's the status on this one?

@gpauloski
Copy link
Contributor

Hi, is this branch stable or is there still work to be done?

@BarrySlyDelgado
Copy link
Contributor Author

The branch has been tested and should work.

@gpauloski
Copy link
Contributor

Hi @BarrySlyDelgado, I've been testing out the branch and noticed a couple of issues.

Invoking future callbacks in VineFuture.result() causes infinite recursion if you access future.result() in the callback. (Maybe this is why the result, rather than the future, was passed to the callback originally?) It's safe to access future.result() in the callback of a concurrent.futures.Future because the callbacks are invoked in Future.set_result().

import time
import ndcctools.taskvine as vine

def foo() -> int:
    time.sleep(1)
    return 42

def check(future: vine.VineFuture) -> None:
    assert future.result() == 42

m = vine.FuturesExecutor(manager_name='my_manager')

t = m.submit(foo)
t.add_done_callback(check)

print(t.result())

Exceptions don't get set on nor raised by VineFuture.

import ndcctools.taskvine as vine

def foo():
    raise RuntimeError('oops')

m = vine.FuturesExecutor(manager_name='my_manager')

t = m.submit(foo)

try:
    t.result()
except RuntimeError:
    print('Correctly raised exception')
else:
    raise AssertionError('Did not raise exception')

@BarrySlyDelgado
Copy link
Contributor Author

Thanks for letting me know, after looking at the source code the infinite recursion is due to the order in which callback functions are executed. Essentially, what is happening is that a call to f.result() executes callback functions if self._ran_functions is False and it dose not get set to True until the callbacks execute. So, a call back that also calls f.result() will also end up running callbacks. This can be fixed by setting Self._ran_functions before running the callbacks. I'll add to this PR with that change and one that raises exceptions from futures.

@BarrySlyDelgado
Copy link
Contributor Author

@gpauloski The recursion bug should be fixed. Tasks that raise an exception now raise an exception when f.result()is called.

@gpauloski
Copy link
Contributor

Thanks, @BarrySlyDelgado. The recursion is fixed for me, but I think this only raises exceptions if loading the output fails. I had to check if the output was an instance of Exception in VineFuture.result() and raise it there.

Also, I opened issue #3892 about poor performance. But it's possible the problem is not specific to the FuturesExecutor as I also observe it with Parsl's TaskVineExecutor.

@btovar btovar merged commit 4b43490 into cooperative-computing-lab:master Jul 31, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants