Skip to content

Commit afc89e9

Browse files
[python_uvloop] Initial commit
1 parent 35c644a commit afc89e9

File tree

4 files changed

+151
-0
lines changed

4 files changed

+151
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ARG BASE_IMAGE="prof-python-3.11"
2+
FROM $BASE_IMAGE
3+
4+
# Copy the Python target into the container
5+
COPY ./scenarios/python_uvloop_3.11/main.py \
6+
./scenarios/python_uvloop_3.11/requirements.txt \
7+
/app/
8+
RUN chmod 644 /app/*
9+
10+
11+
# Set the working directory to the location of the program
12+
WORKDIR /app
13+
14+
RUN pip install -r requirements.txt
15+
16+
ENV EXECUTION_TIME_SEC="5"
17+
ENV DD_PROFILING_ENABLED=true
18+
ENV DD_TRACE_ENABLED=false
19+
ENV DD_TRACE_DEBUG=true
20+
ENV DD_PROFILING_OUTPUT_PPROF="/app/data/profiles"
21+
ENV EXECUTION_TIME_SEC="5"
22+
23+
# Run the program when the container starts
24+
CMD python main.py
25+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"test_name": "python_uvloop_3.11",
3+
"scale_by_duration": false,
4+
"pprof-regex": "",
5+
"stacks": [
6+
{
7+
"profile-type": "wall-time",
8+
"pprof-regex": "",
9+
"stack-content": [
10+
{
11+
"regular_expression": ".*cpu_bound_work.*",
12+
"percent": 75,
13+
"error_margin": 15,
14+
"labels": [
15+
{
16+
"key": "thread name",
17+
"values": [
18+
"MainThread"
19+
]
20+
}
21+
]
22+
}
23+
]
24+
},
25+
{
26+
"profile-type": "wall-time",
27+
"pprof-regex": "",
28+
"stack-content": [
29+
{
30+
"regular_expression": ".*mixed_workload.*",
31+
"percent": 15,
32+
"error_margin": 10,
33+
"labels": [
34+
{
35+
"key": "thread name",
36+
"values": [
37+
"MainThread"
38+
]
39+
}
40+
]
41+
}
42+
]
43+
},
44+
{
45+
"profile-type": "wall-time",
46+
"pprof-regex": "",
47+
"stack-content": [
48+
{
49+
"regular_expression": ".*io_simulation.*",
50+
"percent": 0,
51+
"error_margin": 5,
52+
"labels": [
53+
{
54+
"key": "thread name",
55+
"values": [
56+
"MainThread"
57+
]
58+
}
59+
]
60+
}
61+
]
62+
}
63+
]
64+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""Test scenario for uvloop profiling."""
2+
3+
import asyncio
4+
import os
5+
import time
6+
7+
import uvloop
8+
from ddtrace.profiling import Profiler
9+
10+
11+
async def cpu_bound_work(duration: float) -> None:
12+
"""Perform CPU-bound work for a specified duration."""
13+
end_time = time.monotonic() + duration
14+
count = 0
15+
while time.monotonic() < end_time:
16+
count += 1
17+
18+
19+
async def io_simulation(duration: float) -> None:
20+
"""Simulate I/O-bound work using asyncio.sleep."""
21+
await asyncio.sleep(duration)
22+
23+
24+
async def mixed_workload(cpu_duration: float, io_duration: float) -> None:
25+
"""Perform both CPU-bound and I/O-bound work."""
26+
await cpu_bound_work(cpu_duration)
27+
await io_simulation(io_duration)
28+
29+
30+
async def main() -> None:
31+
"""Main async function that runs the test workload."""
32+
execution_time_sec = int(os.environ.get("EXECUTION_TIME_SEC", "5"))
33+
34+
# Run multiple concurrent tasks to exercise uvloop
35+
tasks = [
36+
asyncio.create_task(cpu_bound_work(execution_time_sec * 0.3)),
37+
asyncio.create_task(mixed_workload(execution_time_sec * 0.2, execution_time_sec * 0.1)),
38+
asyncio.create_task(io_simulation(execution_time_sec * 0.4)),
39+
]
40+
41+
# Also do some work in the main task
42+
await cpu_bound_work(execution_time_sec * 0.3)
43+
44+
# Wait for all tasks to complete
45+
await asyncio.gather(*tasks)
46+
47+
print(f"Completed execution for {execution_time_sec} seconds")
48+
49+
50+
if __name__ == "__main__":
51+
# Start the profiler
52+
prof = Profiler()
53+
prof.start()
54+
55+
# Install uvloop as the event loop
56+
uvloop.install()
57+
58+
# Run the async main function
59+
asyncio.run(main())
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ddtrace
2+
uvloop
3+

0 commit comments

Comments
 (0)