예제 #1
0
    def __init__(
        self,
        controller_handle,
        endpoint_name,
        sync: bool,
        *,
        method_name=None,
        shard_key=None,
        http_method=None,
        http_headers=None,
    ):
        self.controller_handle = controller_handle
        self.endpoint_name = endpoint_name

        self.method_name = method_name
        self.shard_key = shard_key
        self.http_method = http_method
        self.http_headers = http_headers

        self.router = Router(self.controller_handle)
        self.sync = sync
        # In the synchrounous mode, we create a new event loop in a separate
        # thread and run the Router.setup in that loop. In the async mode, we
        # can just use the current loop we are in right now.
        if self.sync:
            self.async_loop = create_or_get_async_loop_in_thread()
            asyncio.run_coroutine_threadsafe(
                self.router.setup_in_async_loop(),
                self.async_loop,
            )
        else:  # async
            self.async_loop = asyncio.get_event_loop()
            # create_task is not threadsafe.
            self.async_loop.create_task(self.router.setup_in_async_loop())
예제 #2
0
파일: api.py 프로젝트: zjureel/ray
class ThreadProxiedRouter:
    def __init__(self, controller_handle, sync: bool):
        self.router = Router(controller_handle)

        if sync:
            self.async_loop = create_or_get_async_loop_in_thread()
            asyncio.run_coroutine_threadsafe(
                self.router.setup_in_async_loop(),
                self.async_loop,
            )
        else:
            self.async_loop = asyncio.get_event_loop()
            self.async_loop.create_task(self.router.setup_in_async_loop())

    def _remote(self, endpoint_name, handle_options, request_data,
                kwargs) -> Coroutine:
        request_metadata = RequestMetadata(
            get_random_letters(10),  # Used for debugging.
            endpoint_name,
            TaskContext.Python,
            call_method=handle_options.method_name,
            shard_key=handle_options.shard_key,
            http_method=handle_options.http_method,
            http_headers=handle_options.http_headers,
        )
        coro = self.router.assign_request(request_metadata, request_data,
                                          **kwargs)
        return coro
예제 #3
0
 def __init__(self, controller_handle, sync: bool,
              endpoint_tag: EndpointTag):
     self.controller_handle = controller_handle
     self.sync = sync
     self.endpoint_tag = endpoint_tag
     if sync:
         self._async_loop = create_or_get_async_loop_in_thread()
     else:
         self._async_loop = asyncio.get_event_loop()
     self.router = Router(controller_handle, endpoint_tag, self._async_loop)
예제 #4
0
파일: api.py 프로젝트: zjureel/ray
    def __init__(self, controller_handle, sync: bool):
        self.router = Router(controller_handle)

        if sync:
            self.async_loop = create_or_get_async_loop_in_thread()
            asyncio.run_coroutine_threadsafe(
                self.router.setup_in_async_loop(),
                self.async_loop,
            )
        else:
            self.async_loop = asyncio.get_event_loop()
            self.async_loop.create_task(self.router.setup_in_async_loop())
예제 #5
0
파일: handle.py 프로젝트: vishalbelsare/ray
 def _make_router(self) -> Router:
     # Delayed import because ray.serve.api depends on handles.
     return Router(
         self.controller_handle,
         self.deployment_name,
         event_loop=create_or_get_async_loop_in_thread(),
     )
예제 #6
0
    async def fetch_config_from_controller(self, name, instance_name=None):
        assert ray.is_initialized()
        controller = serve.api._get_controller()

        self.route_table = await controller.get_router_config.remote()

        self.request_counter = metrics.Count(
            "num_http_requests", "The number of HTTP requests processed",
            "requests", ["route"])

        self.router = Router()
        await self.router.setup(name, instance_name)
예제 #7
0
파일: http_proxy.py 프로젝트: tseiger1/ray
    def __init__(self, controller_name):
        controller = ray.get_actor(controller_name)
        self.router = Router(controller)
        self.long_poll_client = LongPollAsyncClient(
            controller, {
                LongPollKey.ROUTE_TABLE: self._update_route_table,
            })

        self.request_counter = metrics.Count(
            "num_http_requests",
            description="The number of HTTP requests processed",
            tag_keys=("route", ))
예제 #8
0
    async def fetch_config_from_controller(self, controller_name):
        assert ray.is_initialized()
        controller = ray.get_actor(controller_name)

        self.route_table = await controller.get_router_config.remote()

        self.request_counter = metrics.Count(
            "num_http_requests",
            description="The number of HTTP requests processed",
            tag_keys=("route", ))

        self.router = Router(controller)
        await self.router.setup_in_async_loop()
예제 #9
0
    async def fetch_config_from_controller(self, instance_name=None):
        assert ray.is_initialized()
        controller = serve.api._get_controller()

        self.route_table = await controller.get_router_config.remote()

        # The exporter is required to return results for /-/metrics endpoint.
        [self.metric_exporter] = await controller.get_metric_exporter.remote()

        self.metric_client = MetricClient(self.metric_exporter)
        self.request_counter = self.metric_client.new_counter(
            "num_http_requests",
            description="The number of requests processed",
            label_names=("route", ))

        self.router = Router()
        await self.router.setup(instance_name)
예제 #10
0
    def __init__(self, controller_name):
        # Set the controller name so that serve.connect() will connect to the
        # controller instance this proxy is running in.
        ray.serve.api._set_internal_controller_name(controller_name)
        self.client = ray.serve.connect()

        controller = ray.get_actor(controller_name)
        self.route_table = {}  # Should be updated via long polling.
        self.router = Router(controller)
        self.long_poll_client = LongPollAsyncClient(controller, {
            LongPollKey.ROUTE_TABLE: self._update_route_table,
        })

        self.request_counter = metrics.Count(
            "num_http_requests",
            description="The number of HTTP requests processed",
            tag_keys=("route", ))
예제 #11
0
class ThreadProxiedRouter:
    def __init__(self, controller_handle, sync: bool,
                 endpoint_tag: EndpointTag):
        self.controller_handle = controller_handle
        self.sync = sync
        self.endpoint_tag = endpoint_tag
        if sync:
            self._async_loop = create_or_get_async_loop_in_thread()
        else:
            self._async_loop = asyncio.get_event_loop()
        self.router = Router(controller_handle, endpoint_tag, self._async_loop)

    @property
    def async_loop(self):
        # called by handles
        return self._async_loop

    def _remote(self, endpoint_name, handle_options, request_data,
                kwargs) -> Coroutine:
        request_metadata = RequestMetadata(
            get_random_letters(10),  # Used for debugging.
            endpoint_name,
            call_method=handle_options.method_name,
            shard_key=handle_options.shard_key,
            http_method=handle_options.http_method,
            http_headers=handle_options.http_headers,
        )
        coro = self.router.assign_request(request_metadata, request_data,
                                          **kwargs)
        return coro

    def __reduce__(self):
        deserializer = ThreadProxiedRouter
        serialized_data = (
            self.controller_handle,
            self.sync,
            self.endpoint_tag,
        )
        return deserializer, serialized_data
예제 #12
0
async def add_servable_to_router(
    servable,
    controller_name,
    controller_actor,
    **kwargs,
):
    worker = setup_worker("backend",
                          servable,
                          controller_name=controller_name,
                          **kwargs)
    await controller_actor.set_traffic.remote(
        "endpoint",
        TrafficPolicy({"backend": 1.0}),
    )
    await controller_actor.add_new_replica.remote(
        "backend", worker, kwargs.get("backend_config", BackendConfig()))

    router = Router(
        controller_actor,
        "endpoint",
        asyncio.get_event_loop(),
    )
    return worker, router
예제 #13
0
파일: handle.py 프로젝트: vishalbelsare/ray
 def _make_router(self) -> Router:
     return Router(
         self.controller_handle,
         self.deployment_name,
         event_loop=asyncio.get_event_loop(),
     )
예제 #14
0
class RayServeHandle:
    """A handle to a service endpoint.

    Invoking this endpoint with .remote is equivalent to pinging
    an HTTP endpoint.

    Example:
       >>> handle = serve.get_handle("my_endpoint")
       >>> handle
       RayServeHandle(
            Endpoint="my_endpoint",
            Traffic=...
       )
       >>> handle.remote(my_request_content)
       ObjectRef(...)
       >>> ray.get(handle.remote(...))
       # result
       >>> ray.get(handle.remote(let_it_crash_request))
       # raises RayTaskError Exception
    """
    def __init__(
        self,
        controller_handle,
        endpoint_name,
        sync: bool,
        *,
        method_name=None,
        shard_key=None,
        http_method=None,
        http_headers=None,
    ):
        self.controller_handle = controller_handle
        self.endpoint_name = endpoint_name

        self.method_name = method_name
        self.shard_key = shard_key
        self.http_method = http_method
        self.http_headers = http_headers

        self.router = Router(self.controller_handle)
        self.sync = sync
        # In the synchrounous mode, we create a new event loop in a separate
        # thread and run the Router.setup in that loop. In the async mode, we
        # can just use the current loop we are in right now.
        if self.sync:
            self.async_loop = create_or_get_async_loop_in_thread()
            asyncio.run_coroutine_threadsafe(
                self.router.setup_in_async_loop(),
                self.async_loop,
            )
        else:  # async
            self.async_loop = asyncio.get_event_loop()
            # create_task is not threadsafe.
            self.async_loop.create_task(self.router.setup_in_async_loop())

    def _remote(self, request_data, kwargs) -> Coroutine:
        request_metadata = RequestMetadata(
            get_random_letters(10),  # Used for debugging.
            self.endpoint_name,
            TaskContext.Python,
            call_method=self.method_name or "__call__",
            shard_key=self.shard_key,
            http_method=self.http_method or "GET",
            http_headers=self.http_headers or dict(),
        )
        coro = self.router.assign_request(request_metadata, request_data,
                                          **kwargs)
        return coro

    def remote(self,
               request_data: Optional[Union[Dict, Any]] = None,
               **kwargs):
        """Issue an asynchrounous request to the endpoint.

        Returns a Ray ObjectRef whose results can be waited for or retrieved
        using ray.wait or ray.get, respectively.

        Returns:
            ray.ObjectRef
        Args:
            request_data(dict, Any): If it's a dictionary, the data will be
                available in ``request.json()`` or ``request.form()``.
                Otherwise, it will be available in ``request.data``.
            ``**kwargs``: All keyword arguments will be available in
                ``request.args``.
        """
        if not self.sync:
            raise RayServeException(
                "You are trying to call handle.remote() with async handle. "
                "Please use `await handle.remote_async()` instead.")

        coro = self._remote(request_data, kwargs)
        future: concurrent.futures.Future = asyncio.run_coroutine_threadsafe(
            coro, self.async_loop)

        # Block until the result is ready.
        return future.result()

    async def remote_async(self,
                           request_data: Optional[Union[Dict, Any]] = None,
                           **kwargs) -> ray.ObjectRef:
        """Experimental API for enqueue a request in async context."""
        if not asyncio.get_event_loop().is_running():
            raise RayServeException(
                "remote_async must be called from a running event loop.")
        return await self._remote(request_data, kwargs)

    def options(self,
                method_name: Optional[str] = None,
                *,
                shard_key: Optional[str] = None,
                http_method: Optional[str] = None,
                http_headers: Optional[Dict[str, str]] = None):
        """Set options for this handle.

        Args:
            method_name(str): The method to invoke on the backend.
            http_method(str): The HTTP method to use for the request.
            shard_key(str): A string to use to deterministically map this
                request to a backend if there are multiple for this endpoint.
        """
        # Don't override default non-null values.
        self.method_name = self.method_name or method_name
        self.shard_key = self.shard_key or shard_key
        self.http_method = self.http_method or http_method
        self.http_headers = self.http_headers or http_headers
        return self

    def __repr__(self):
        return f"RayServeHandle(endpoint='{self.endpoint_name}')"