ancient-wolf-19325
08/16/2024, 8:57 PMflytekit that asserts shared process namespace for the primary and profiler containers in the pod and adding some e.g. additional capabilities
◦ This ensures any sampling profiler can read the Task Python process' proc/$pid/maps
◦ Easy enough, that part is done!
• Knowing what PID is the user task being run. This would entail e.g. pgrep -f <entrypoint_for_task>
My problem arises in that last bullet point -- what process name should I be attempting to get the PID of?
• I first, naively, tried pgrep -f pyflyte-execute given that this is the entrypoint into the lifecycle of a task. This likely spins off separate processes for the user code itself, though, and as such does not work
Once dispatch_execute is called somewhere within pyflyte-execute, what would be the appropriate process to grep for? Would it be simpler to attempt a different approach, such as a custom PythonFunctionTask that dumps the task objects PID to a shared volume?
# Answer
To attach a sampling Python call stack profiler as a sidecar to a Flyte task, you need to identify the correct process ID (PID) of the user task. The pyflyte-execute command is indeed the entry point, but it spawns additional processes for the user code, making it challenging to directly grep for the correct PID.
Steps to Identify the Correct PID:
1. Custom PythonFunctionTask: Modify the task to write its PID to a shared volume. This approach ensures you capture the exact PID of the user task.
Here's an example of how you can achieve this:
from flytekit import task, workflow
import os
@task
def my_task() -> str:
pid = os.getpid()
with open("/shared_volume/task_pid.txt", "w") as f:
f.write(str(pid))
# Your task logic here
return "Task completed"
@workflow
def my_workflow() -> str:
return my_task()
PodSpec Configuration:
Ensure your PodSpec includes a shared volume and the necessary capabilities for the profiler container to access the task's process information.ancient-wolf-19325
08/16/2024, 8:57 PM>>```from flytekit import Resources, task, workflow from flytekitplugins.k8s.pod import Pod, PodTemplate, PodSpec, Container, Volume, VolumeMount, EmptyDirVolumeSource shared_volume = Volume( name="shared-volume", empty_dir=EmptyDirVolumeSource(medium="Memory") ) shared_volume_mount = VolumeMount( name="shared-volume", mount_path="/shared_volume" ) profiler_container = Container( name="profiler", image="profiler_image", command=["profiler_command"], volume_mounts=[shared_volume_mount] ) primary_container = Container( name="primary", image="task_image", command=["pyflyte-execute", "--task-module", "my_module", "--task-name", "my_task"], volume_mounts=[shared_volume_mount] ) pod_spec = PodSpec( containers=[primary_container, profiler_container], volumes=[shared_volume] ) @task( task_config=Pod(pod_spec=pod_spec), requests=Resources(cpu="1", mem="1Gi"), limits=Resources(cpu="2", mem="2Gi") ) def my_task() -> str: pid = os.getpid() with open("/shared_volume/task_pid.txt", "w") as f: f.write(str(pid)) # Your task logic here return "Task completed" @workflow def my_workflow() -> str: return my_task() ``` Summary: - Use a custom
PythonFunctionTask to write the task's PID to a shared volume.
- Configure the PodSpec to include a shared volume and the necessary capabilities for the profiler container.
Would you like more details on any specific part of this process?
Sources:
- https://docs.flyte.org/en/latest/api/flytekit/design/execution.html
- https://docs.flyte.org/en/latest/concepts/workflow_lifecycle.html#understand-the-lifecycle-of-a-flyte-workflow
Note: I wasn’t able to find highly relevant data sources, but above are a few potentially relevant links.
Slack Link
https://flyte-org.slack.com/archives/CP2HDHKE1/p1723841832.206539 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.