Skip to content
This repository has been archived by the owner on Jul 3, 2023. It is now read-only.

Async implementation of driver/adapter #171

Merged
merged 5 commits into from
Aug 10, 2022
Merged

Async implementation of driver/adapter #171

merged 5 commits into from
Aug 10, 2022

Conversation

elijahbenizzy
Copy link
Collaborator

@elijahbenizzy elijahbenizzy commented Aug 6, 2022

@skrawcz this is what I meant

Basically we pass the coroutine the entire way through.
When a function depends on other data, we create a coroutine that
awaits everything. Finally, we do a gather at the end.

I think this is optimal but will need to dig in a bit/look into
things.

Otherwise, nifty POC with very rough edges.

The biggest hack is that I'm using a cache to store coroutine values as python makes it very hard to access them.
I think we can do better, but the point is we don't have to mess with execution.

[Short description explaining the high-level reason for the pull request]

Changes

Testing

Notes

Checklist

  • PR has an informative and human-readable title (this will be pulled into the release notes)
  • Changes are limited to a single goal (no scope creep)
  • Code can be automatically merged (no conflicts)
  • Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
  • Passes all existing automated tests
  • Any change in functionality is tested
  • New functions are documented (with a description, list of inputs, and expected output)
  • Placeholder code is flagged / future TODOs are captured in comments
  • Project documentation has been updated if adding/changing functionality.
  • Reviewers requested with the Reviewers tool ➡️

Testing checklist

Python - local testing

  • python 3.6
  • python 3.7

hamilton/driver.py Outdated Show resolved Hide resolved
hamilton/driver.py Outdated Show resolved Hide resolved
hamilton/driver.py Outdated Show resolved Hide resolved
hamilton/driver.py Outdated Show resolved Hide resolved
@elijahbenizzy elijahbenizzy force-pushed the async-prototype branch 4 times, most recently from 018fd96 to a8667ca Compare August 7, 2022 19:36
@elijahbenizzy elijahbenizzy changed the title Rough POC that we can do async without touching function graph Async implementation of driver/adapter Aug 7, 2022
@elijahbenizzy
Copy link
Collaborator Author

elijahbenizzy commented Aug 7, 2022

Remaining:

  • Tests
  • Determine how to release (experimental?)

Basically we pass the coroutine the entire way through.
When a function depends on other data, we create a coroutine that
awaits everything. Finally, we do a gather at the end.

This involves no modification to the functiongraph code
If we use tasks, we can await them twice. Furthermore, they'll
begin scheduling earlier, and python handles keeping track of them.

This is a much cleaner way to handle it.
@elijahbenizzy elijahbenizzy marked this pull request as ready for review August 8, 2022 00:59
examples/async/README.md Outdated Show resolved Hide resolved
Comment on lines 52 to 58
ad_hoc_utils.create_temporary_module(
pipeline,
computation1,
foo,
bar,
some_data,
computation2))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably not do this in an example. This doesn't feel very "ad hoc".

Otherwise 💡, fastapi could be a possible code compilation target too.

hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
hamilton/experimental/h_async.py Outdated Show resolved Hide resolved
if display_graph:
raise ValueError(f'display_graph=True is not supported for the async graph adapter. '
f'Instead you should be using visualize_execution.')
return await await_dict_of_tasks({key: asyncio.create_task(process_value(memoized_computation[key])) for key in final_vars})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return await await_dict_of_tasks({key: asyncio.create_task(process_value(memoized_computation[key])) for key in final_vars})
task_dict = {key: asyncio.create_task(process_value(memoized_computation[key])) for key in final_vars}
return await await_dict_of_tasks(task_dict)

Also is process_value needed here? Seems a bit redundant with the result being wrapped in a task and that awaited?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process_value is needed but create_task is not I think...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay. But this seems like an important line that should be at least two... break out the dict comprehension at least.

examples/async/fastapi_example.py Outdated Show resolved Hide resolved
callabl = node.callable

async def new_fn(fn=callabl, **fn_kwargs):
fn_kwargs = await await_dict_of_tasks({key: process_value(value) for key, value in fn_kwargs.items()})
Copy link
Collaborator

@skrawcz skrawcz Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can move this dict comprehension to its own line.

Copy link
Collaborator

@skrawcz skrawcz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just those two code nits, otherwise I think this looks good.

@elijahbenizzy elijahbenizzy force-pushed the async-prototype branch 2 times, most recently from ca4b36f to bc3a7e2 Compare August 10, 2022 00:14
1. Fixes docstring formats
2. Removes redundant call to create_task
3. Breaks example into modules
@elijahbenizzy elijahbenizzy merged commit ca529c1 into main Aug 10, 2022
@elijahbenizzy elijahbenizzy deleted the async-prototype branch August 10, 2022 01:02
@skrawcz skrawcz linked an issue Aug 22, 2022 that may be closed by this pull request
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add asyncio based driver and related components
2 participants