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

Enable deployment on Serve of functions that take no parameters #19708

Merged
merged 4 commits into from
Oct 28, 2021

Conversation

shrekris-anyscale
Copy link
Contributor

Why are these changes needed?

Currently, functions that take no parameters can be deployed on Serve. However, when a request is made to the deployment over HTTP, the function will error out since it has no parameters. This PR allows functions with no parameters to successfully execute requests over HTTP without erroring out.

This PR was tested by adding a unit test called test_deploy_function_no_params to test_deploy.py that checks whether functions with no parameters run HTTP requests successfully. The PR also passed all other tests from test_deploy.py.

Related issue number

Closes #12178

Checks

  • I've run scripts/format.sh to lint the changes in this PR.
  • I've included any doc changes needed for https://docs.ray.io/en/master/.
  • I've made sure the tests are passing. Note that there might be a few flaky tests, see the recent failures at https://flakey-tests.ray.io/
  • Testing Strategy
    • Unit tests
    • Release tests
    • This PR is not tested :(

@@ -884,6 +884,17 @@ class NegativeMaxQueries:
Base.options(max_concurrent_queries=-1)


def test_deploy_function_no_params(serve_instance):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a reason all the other tests pass in serve_instance as an argument but don't necessarily use it? I pattern-matched the other tests when I included it, but I don't think I need it in the function.

Copy link
Contributor

Choose a reason for hiding this comment

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

The serve_instance is a pytest fixture that creates a shared instance of ray + serve locally and allows all of the tests to connect to it. The actual argument itself may not be used, it's basically just specifying that the shared instance should be connected to before running this test.

@@ -884,6 +884,17 @@ class NegativeMaxQueries:
Base.options(max_concurrent_queries=-1)


def test_deploy_function_no_params(serve_instance):
Copy link
Contributor

Choose a reason for hiding this comment

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

The serve_instance is a pytest fixture that creates a shared instance of ray + serve locally and allows all of the tests to connect to it. The actual argument itself may not be used, it's basically just specifying that the shared instance should be connected to before running this test.

@@ -884,6 +884,17 @@ class NegativeMaxQueries:
Base.options(max_concurrent_queries=-1)


def test_deploy_function_no_params(serve_instance):
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: these tests are quite similar, but conceptually I think this fits in test_api.py better, could you move it there?

Comment on lines 889 to 890
def d():
return "Hello world!"
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you also test a class that has a __call__(self): method?

serve.start()
d.deploy()

assert requests.get("http://localhost:8000/d").text == "Hello world!"
Copy link
Contributor

Choose a reason for hiding this comment

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

Should also probably test the get_handle case here too

runner_method = self.get_runner_method(request_item)
method_to_call = sync_to_async(runner_method)
result = None
if len(inspect.signature(runner_method).parameters) > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this check need to be > 1 for class methods because of self? Where does the self arg get injected? It may work as-is because self is already bound in method_to_call. @simon-mo would probably know.

Copy link
Contributor

Choose a reason for hiding this comment

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

it's already bound:

In [1]: class A:
   ...:     def b(self):
   ...:         pass
   ...:

In [2]: runner_method = A().b

In [3]: import inspect

In [4]: inspect.signature(runner_method).parameters
Out[4]: mappingproxy({})

@edoakes edoakes added the @author-action-required The PR author is responsible for the next step. Remove tag to send back to the reviewer. label Oct 25, 2021
Copy link
Member

@jiaodong jiaodong left a comment

Choose a reason for hiding this comment

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

lg, mostly about testing, can we add a few parametrized tests so that we cover:

  1. function deployment with no args
  2. class deployment with only "self"
  3. sync / async function for class deployment ?

For 3, example:


@serve.deployment
class A:
   def __init__(self, input):
        self.input = input
   def __call__(self):
        return self.input

where both functions can be sync or async.

Copy link
Contributor

@edoakes edoakes left a comment

Choose a reason for hiding this comment

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

LGTM!

@edoakes
Copy link
Contributor

edoakes commented Oct 28, 2021

test_object_manager unrelated.

@edoakes edoakes merged commit 6e6fff8 into ray-project:master Oct 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@author-action-required The PR author is responsible for the next step. Remove tag to send back to the reviewer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[nit] [serve] Bad error message when passing in a function that takes no args
4 participants