Skip to content

Add support for async path operations in the server #4617

@robhowley

Description

@robhowley

Is your feature request related to a problem? Please describe.

Add opt in support for async path operations on the python feature server. This would allow the server to take advantage of the async libraries that are slowly becoming available for the various data stores. Lookups to multiple feature views with online stores such as dynamo and redis can be done in parallel. This would provide significant performance gains when calling feature services.

Describe the solution you'd like

If we are willing to move to async methods for path operations, i'd like to to see run_in_threadpool used for the sync methods. example pr here. This is the recommended approach to sync operations in async methods and is more or less what fastapi does under the hood to sync endpoints anyway.

If there is a preference for a manual opt in, then ...

A cli parameter on feast serve to indicate preference for deploying the async paths which will leverage the async feature store sdk methods.

# simple flag param
feast serve --async-read

Under the hood it would declare

@app.post(
    "/get-online-features",
    dependencies=[Depends(inject_user_details)],
)
async def get_online_features(body=Depends(get_body)):
    ...
    # and call
    response_proto = await store.get_online_features(

As async store.push functionality gets added an --async-push flag could be added as well. This approach is an explicit opt-in which is desirable when overriding default behavior. Lets the person deploying the server make informed decisions about performance based upon the backend being used. The caller need not worry about the internals of a service, just the api contract.

Describe alternatives you've considered

  • a separate cli feast-async but
    • it's nice having feast be the one universal cli
    • it implies everything will be async, which it wouldn't be
  • a cli subgroup feast serve async
    • adds more layers and indirection in the code without a lot of value
  • new base class AsyncOnlineDataStore to differentiate from the default synchronous calls
    • when the server is constructed it will define the path operation based upon type
    • this would require a nontrivial refactor

Additional context

Here is a flame graph for a call to a feature service with

  • 3 feature views
  • 11 total features
  • dynamo backend

image

We see default batching behavior and 3 calls per batch all of which are done sequentially. These can be done in parallel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions