Exemple #1
0
    async def _report_usage(self):
        if not ray_usage_lib._usage_stats_enabled():
            return
        """
        - Always write usage_stats.json regardless of report success/failure.
        - If report fails, the error message should be written to usage_stats.json
        - If file write fails, the error will just stay at dashboard.log.
            usage_stats.json won't be written.
        """
        try:
            data = ray_usage_lib.generate_report_data(
                self.cluster_metadata,
                self.total_success,
                self.total_failed,
                self.seq_no,
            )
            error = None
            try:
                await self.client.report_usage_data_async(
                    ray_usage_lib._usage_stats_report_url(), data)
            except Exception as e:
                logger.info(f"Usage report request failed. {e}")
                error = str(e)
                self.total_failed += 1
            else:
                self.total_success += 1
            finally:
                self.seq_no += 1

            data = ray_usage_lib.generate_write_data(data, error)
            await self.client.write_usage_data_async(data, self.session_dir)

        except Exception as e:
            logger.exception(e)
            logger.info(f"Usage report failed: {e}")
Exemple #2
0
def test_usage_lib_report_data(monkeypatch, shutdown_only, tmp_path):
    with monkeypatch.context() as m:
        m.setenv("RAY_USAGE_STATS_ENABLED", "1")
        # Runtime env is required to run this test in minimal installation test.
        ray.init(num_cpus=0, runtime_env={"pip": ["ray[serve]"]})
        """
        Make sure the generated data is following the schema.
        """
        cluster_metadata = ray_usage_lib.get_cluster_metadata(
            ray.experimental.internal_kv.internal_kv_get_gcs_client(), num_retries=20
        )
        d = ray_usage_lib.generate_report_data(cluster_metadata, 2, 2, 2)
        validate(instance=asdict(d), schema=schema)

        """
        Make sure writing to a file works as expected
        """
        client = ray_usage_lib.UsageReportClient()
        temp_dir = Path(tmp_path)
        client._write_usage_data(d, temp_dir)

        wait_for_condition(lambda: file_exists(temp_dir))

        """
        Make sure report usage data works as expected
        """

        @ray.remote(num_cpus=0, runtime_env={"pip": ["ray[serve]"]})
        class ServeInitator:
            def __init__(self):
                # Start the ray serve server to verify requests are sent
                # to the right place.
                from ray import serve

                serve.start()

                @serve.deployment(ray_actor_options={"num_cpus": 0})
                async def usage(request):
                    body = await request.json()
                    if body == asdict(d):
                        return True
                    else:
                        return False

                usage.deploy()

            def ready(self):
                pass

        # We need to start a serve with runtime env to make this test
        # work with minimal installation.
        s = ServeInitator.remote()
        ray.get(s.ready.remote())

        # Query our endpoint over HTTP.
        r = client._report_usage_data("http://127.0.0.1:8000/usage", d)
        r.raise_for_status()
        assert json.loads(r.text) is True
Exemple #3
0
def test_usage_lib_report_data(
    monkeypatch, ray_start_cluster, tmp_path, reset_lib_usage
):
    with monkeypatch.context() as m:
        m.setenv("RAY_USAGE_STATS_ENABLED", "1")
        m.setenv("RAY_USAGE_STATS_REPORT_URL", "http://127.0.0.1:8000")
        cluster = ray_start_cluster
        cluster.add_node(num_cpus=0)
        # Runtime env is required to run this test in minimal installation test.
        ray.init(address=cluster.address, runtime_env={"pip": ["ray[serve]"]})
        """
        Make sure the generated data is following the schema.
        """
        cluster_metadata = ray_usage_lib.get_cluster_metadata(
            ray.experimental.internal_kv.internal_kv_get_gcs_client(), num_retries=20
        )
        cluster_config_file_path = tmp_path / "ray_bootstrap_config.yaml"
        cluster_config_file_path.write_text(
            """
cluster_name: minimal
max_workers: 1
provider:
    type: aws
    region: us-west-2
    availability_zone: us-west-2a
"""
        )
        cluster_config_to_report = ray_usage_lib.get_cluster_config_to_report(
            cluster_config_file_path
        )
        d = ray_usage_lib.generate_report_data(
            cluster_metadata, cluster_config_to_report, 2, 2, 2
        )
        validate(instance=asdict(d), schema=schema)

        """
        Make sure writing to a file works as expected
        """
        client = ray_usage_lib.UsageReportClient()
        temp_dir = Path(tmp_path)
        client.write_usage_data(d, temp_dir)

        wait_for_condition(lambda: file_exists(temp_dir))

        """
        Make sure report usage data works as expected
        """

        @ray.remote(num_cpus=0)
        class ServeInitator:
            def __init__(self):
                # Start the ray serve server to verify requests are sent
                # to the right place.
                from ray import serve

                serve.start()

                @serve.deployment(ray_actor_options={"num_cpus": 0})
                async def usage(request):
                    body = await request.json()
                    if body == asdict(d):
                        return True
                    else:
                        return False

                usage.deploy()

            def ready(self):
                pass

        # We need to start a serve with runtime env to make this test
        # work with minimal installation.
        s = ServeInitator.remote()
        ray.get(s.ready.remote())

        # Query our endpoint over HTTP.
        r = client.report_usage_data("http://127.0.0.1:8000/usage", d)
        r.raise_for_status()
        assert json.loads(r.text) is True