درون‌نگری گراف فراخوانی

کد منبع: Lib/asyncio/graph.py


asyncio ابزارهای قدرتمند درون‌نگری نمودار فراخوانی در ران‌تایم دارد که برای ردگیری کل نمودار فراخوانی یک هم‌روال یا وظیفه در حال اجرا، یا یک آینده معلق به کار می‌روند. می‌توان از این ابزارها و سازوکار زیربنایی، از درون یک برنامه پایتون یا به‌وسیله پروفایل‌گیرها و اشکال‌زداهای خارجی استفاده کرد.

همچنین ملاحظه نمائید

ابزارهای درون‌نگری خط فرمان

ابزارهای خط فرمان برای بازرسی وظایف در فرایند پایتون دیگری که در حال اجرا است.

اضافه شده در نسخه‌ی 3.14.

asyncio.print_call_graph(future=None, /, *, file=None, depth=1, limit=None)

گراف فراخوانی ناهمگام برای وظیفه فعلی یا Task یا Future ارائه‌شده را چاپ می‌کند.

این تابع مدخل‌ها را از فریم بالایی تا نقطه فراخوانی به ترتیب رو به پایین چاپ می‌کند.

این تابع یک آرگومان اختیاری future دریافت می‌کند. اگر ارسال نشود، از وظیفه در حال اجرای فعلی استفاده خواهد شد.

اگر تابع روی وظیفه جاری فراخوانی شود، می‌توانید از آرگومان اختیاری و فقط کلیدواژه‌ای depth برای رد کردن تعداد مشخصی از فریم‌ها از بالای پشته استفاده کنید.

اگر آرگومان اختیاری فقط کلیدواژه‌ای limit ارائه شود، هر پشته فراخوانی در گراف حاصل به‌گونه‌ای کوتاه می‌شود که حداکثر شامل abs(limit) ورودی باشد. اگر limit مثبت باشد، ورودی‌های باقی‌مانده نزدیک‌ترین ورودی‌ها به نقطه فراخوانی هستند. اگر limit منفی باشد، بالاترین ورودی‌ها باقی می‌مانند. اگر limit ذکر نشود یا None باشد، همه ورودی‌ها موجود خواهند بود. اگر limit برابر 0 باشد، پشته فراخوانی اصلاً چاپ نمی‌شود و فقط اطلاعات «awaited by» چاپ می‌شود.

اگر file حذف شود یا None باشد، تابع در sys.stdout چاپ خواهد کرد.

مثال:

کد پایتون زیر:

import asyncio

async def test():
    asyncio.print_call_graph()

async def main():
    async with asyncio.TaskGroup() as g:
        g.create_task(test(), name='test')

asyncio.run(main())

چاپ خواهد شد:

* Task(name='test', id=0x1039f0fe0)
+ Call stack:
|   File 't2.py', line 4, in async test()
+ Awaited by:
   * Task(name='Task-1', id=0x103a5e060)
      + Call stack:
      |   File 'taskgroups.py', line 107, in async TaskGroup.__aexit__()
      |   File 't2.py', line 7, in async main()
asyncio.format_call_graph(future=None, /, *, depth=1, limit=None)

مانند print_call_graph()، اما یک رشته برمی‌گرداند. اگر future برابر None باشد و هیچ وظیفه جاری‌ای وجود نداشته باشد، تابع یک رشته خالی برمی‌گرداند.

asyncio.capture_call_graph(future=None, /, *, depth=1, limit=None)

گراف فراخوانی ناهمگام برای وظیفه جاری یا Task یا Future ارائه‌شده را ضبط کنید.

این تابع یک آرگومان اختیاری future دریافت می‌کند. اگر ارسال نشود، از وظیفه در حال اجرای فعلی استفاده می‌شود. اگر وظیفه فعلی وجود نداشته باشد، تابع None را برمی‌گرداند.

اگر تابع روی وظیفه جاری فراخوانی شود، می‌توانید از آرگومان اختیاری و فقط کلیدواژه‌ای depth برای رد کردن تعداد مشخصی از فریم‌ها از بالای پشته استفاده کنید.

یک شیء از دیتاکلاس FutureCallGraph برمی‌گرداند:

  • FutureCallGraph(future, call_stack, awaited_by)

    که در آن future ارجاعی به یک Future یا Task (یا زیرکلاس‌های آن‌ها) است.

    call_stack یک تاپل از اشیای FrameCallGraphEntry است.

    awaited_by تاپلی از اشیای FutureCallGraph است.

  • FrameCallGraphEntry(frame)

    که در آن frame یک شیء فریم از یک تابع معمولی پایتون در پشته فراخوانی است.

توابع سودمند سطح پایین

برای درون‌نگری گراف فراخوانی ناهمگام، asyncio به همکاری ساختارهای کنترل جریان، مانند shield() یا TaskGroup نیاز دارد. هر زمان که یک شیء میانی Future با APIهای سطح پایین مانند Future.add_done_callback() دخیل باشد، باید از دو تابع زیر استفاده کنید تا asyncio را از چگونگی دقیق اتصال چنین اشیای میانی Future به وظایفی که آن‌ها را پوشش می‌دهند یا کنترل می‌کنند مطلع کنید.

asyncio.future_add_to_awaited_by(future, waiter, /)

ثبت می‌کند که future توسط waiter await می‌شود.

هر دو future و waiter باید نمونه‌هایی از Future یا Task یا زیرکلاس‌های آن‌ها باشند، در غیر این صورت این فراخوانی هیچ اثری نخواهد داشت.

فراخوانی future_add_to_awaited_by() باید در نهایت با فراخوانی تابع future_discard_from_awaited_by() با همان آرگومان‌ها دنبال شود.

asyncio.future_discard_from_awaited_by(future, waiter, /)

ثبت کنید که future دیگر توسط waiter await نمی‌شود.

هر دو future و waiter باید نمونه‌هایی از Future یا Task یا زیرکلاس‌های آن‌ها باشند، در غیر این صورت این فراخوانی هیچ اثری نخواهد داشت.