{"id":287331,"date":"2018-08-16T14:06:55","date_gmt":"2018-08-16T10:06:55","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=287331"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2018-08-16T10:06:55","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=287331","title":{"rendered":"\u041f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d asyncio: \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 await"},"content":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/420129\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><em>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430:<br \/>  \u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0440\u0430\u0437 \u043d\u0430\u0441\u0442\u0443\u043f\u0438\u0432 \u043d\u0430 \u0433\u0440\u0430\u0431\u043b\u0438 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 python asyncio \u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u044b \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435, \u0447\u0435\u043c \u0441\u0443\u0445\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \u041c\u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/medium.com\/python-pandemonium\/asyncio-coroutine-patterns-beyond-await-a6121486656f\">Yeray Diaz &quot;Asyncio Coroutine Patterns: Beyond await&quot;<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u0432\u0442\u043e\u0440 \u0432\u0435\u0441\u044c\u043c\u0430 \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 asyncio \u0438 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u0438\u0435\u043c\u0430\u043c\u0438. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043d\u0438\u0447\u0435\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u0436\u0435 \u0446\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u0442\u043e \u0440\u0435\u0448\u0438\u043b\u0441\u044f \u0435\u0451 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438. <\/em><\/p>\n<p>  <\/p>\n<p>Asyncio \u2014 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u0430\u044f \u043c\u0435\u0447\u0442\u0430 python \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430: \u043f\u0438\u0448\u0435\u0448\u044c \u043a\u043e\u0434, \u0433\u0440\u0430\u043d\u0438\u0447\u0430\u0449\u0438\u0439 \u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0448\u044c Python \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435. \u042d\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0438\u043c\u043f\u043e\u0440\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0430\u043d\u0442\u0438\u0433\u0440\u0430\u0432\u0438\u0442\u0430\u0446\u0438\u0438: <a href=\"http:\/\/xkcd.com\/353\/\">import antigravity<\/a><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0442\u0430\u043a, \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u0442\u044f\u0436\u0435\u043b\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435 \u0438, \u043f\u043e\u043a\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0430\u043c \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0430\u0434\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0443\u0432\u0435\u0441\u0442\u0438 \u0432\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u043b\u0435\u043a\u043e, \u0432\u0430\u043c \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439. \u041f\u0435\u0447\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 asyncio. \u041f\u043b\u043e\u0445\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0440\u0430\u0437\u0443 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0447\u0442\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u041d\u0438\u0436\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 asyncio.<\/p>\n<p><a name=\"habracut\"><\/a><\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c:<\/p>\n<p>  <\/p>\n<p>\u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043b\u044e\u0431\u0438\u043c\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 aiohttp \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 HTTP \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 Hacker News API, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0430\u0439\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0421\u043b\u0435\u0434\u0443\u044f \u043e\u0442\u043a\u043b\u0438\u043a\u0443 \u043d\u0430 \u043c\u043e\u044e <a href=\"https:\/\/hackernoon.com\/asyncio-for-the-working-python-developer-5c468e6e2e8e\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e<\/a>, \u044f \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b async\/await \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432 Python 3.5. \u042f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u043d\u0430\u043a\u043e\u043c \u0441 \u0438\u0434\u0435\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0434\u0435\u0441\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u044b. \u0418 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0447\u0435\u0442\u0435, \u0432\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 <a href=\"https:\/\/github.com\/yeraydiazdiaz\/asyncio-coroutine-patterns\">GitHub \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c!<\/p>\n<p>  <\/p>\n<h2 id=\"rekursivnye-korutiny\">\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b<\/h2>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e \u0432 asyncio. \u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 API \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 AbstractEventLoop, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u041d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0442 \u044d\u0442\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f asyncio \u2014 \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0435\u0431\u043a\u0440\u0430\u0443\u043b\u0435\u0440\u0430 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0438\u0434\u0430. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0437\u0430\u043d\u044f\u0442\u044b \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c HackerNews, \u0438\u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0445\u043e\u043b\u0438\u0432\u0430\u0440, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u043d\u0430 HN \u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0432\u044b\u0448\u0435 \u043f\u043e\u0440\u043e\u0433\u0430, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u0432\u0430\u0441. \u0412\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0433\u0443\u0433\u043b\u0438\u043b\u0438 \u0438 \u043d\u0430\u0448\u043b\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043d\u0430 HN API, \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u043e\u0434\u043d\u0430\u043a\u043e \u0432\u044b \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<blockquote><p>\u0425\u043e\u0442\u0438\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u043e\u0431\u0449\u0435\u0435 \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0441\u0442\u0430\u0442\u044c\u0438? \u041e\u0431\u043e\u0439\u0434\u0438\u0442\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0441\u043e\u0441\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0438\u0445.<\/p><\/blockquote>\n<p>\u0412\u044b\u0437\u043e\u0432 \u043f\u0440\u0438\u043d\u044f\u0442!<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">&quot;&quot;&quot;     \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0443\u043f\u0440\u043e\u0449\u0430\u044f \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440,     \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b     \u043d\u0430\u0432\u0435\u0440\u0445\u0443 \u0441\u0442\u0435\u043a\u0430.     \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e     \u043f\u043e\u0441\u0442\u0430 Hacker News \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044f \u0447\u0438\u0441\u043b\u043e \u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043c\u043a\u043e\u0432 &quot;&quot;&quot;  import asyncio import argparse import logging from urllib.parse import urlparse, parse_qs from datetime import datetime  import aiohttp import async_timeout  LOGGER_FORMAT = '%(asctime)s %(message)s' URL_TEMPLATE = &quot;https:\/\/hacker-news.firebaseio.com\/v0\/item\/{}.json&quot; FETCH_TIMEOUT = 10  parser = argparse.ArgumentParser(description='Calculate the comments of a Hacker News post.') parser.add_argument('--id', type=int, default=8863, help='ID of the post in HN, defaults to 8863') parser.add_argument('--url', type=str, help='URL of a post in HN') parser.add_argument('--verbose', action='store_true', help='Detailed output')  logging.basicConfig(format=LOGGER_FORMAT, datefmt='[%H:%M:%S]') log = logging.getLogger() log.setLevel(logging.INFO)  fetch_counter = 0  async def fetch(session, url):     &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f aiohttp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u0440\u043d\u044b\u0439 JSON \u043e\u0442\u0432\u0435\u0442.         \u041a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 aiohttp \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0441\u0441\u0438\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.     &quot;&quot;&quot;     global fetch_counter     with async_timeout.timeout(FETCH_TIMEOUT):         fetch_counter += 1         async with session.get(url) as response:             return await response.json()  async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;         \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     now = datetime.now()     response = await fetch(session, url)     log.debug('{:^6} &gt; Fetching of {} took {} seconds'.format(     post_id, url, (datetime.now() - now).total_seconds()))      if 'kids' not in response:  # \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439. \u0411\u0435\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430, \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435)     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     log.debug('{:^6} &gt; Fetching {} child posts'.format(     post_id, number_of_comments))     tasks = [post_number_of_comments(loop, session, kid_id) for kid_id in response['kids']]      # \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442     results = await asyncio.gather(*tasks)      # \u0441\u0432\u043e\u0434\u0438\u043c \u043d\u0438\u0436\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      return number_of_comments  def id_from_HN_url(url):     &quot;&quot;&quot;         \u0412\u0435\u0440\u043d\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `id` URL \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0435\u0441\u043b\u0438 \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0438\u043b\u0438 None.     &quot;&quot;&quot;     parse_result = urlparse(url)     try:         return parse_qs(parse_result.query)['id'][0]     except (KeyError, IndexError):         return None  if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      post_id = id_from_HN_url(args.url) if args.url else args.id     loop = asyncio.get_event_loop()      with aiohttp.ClientSession(loop=loop) as session:         now = datetime.now()         comments = loop.run_until_complete(             post_number_of_comments(loop, session, post_id))         log.info(             '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_counter))         log.info(&quot;-- Post {} has {} comments&quot;.format(post_id, comments))         loop.close()<\/code><\/pre>\n<p>  <\/p>\n<p><em>\u041d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 \u0444\u043b\u0430\u0433\u043e\u043c \u201c \u2014verbose\u201d \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430.<\/em><\/p>\n<p>  <\/p>\n<pre><code>    [14:47:32] &gt; Calculating comments took 2.23 seconds and 73 fetches     [14:47:32] -- Post 8863 has 72 comments<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043f\u0440\u044f\u043c\u043e \u043a \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435. \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u044b\u043b\u043e \u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;         \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     now = datetime.now()     response = await fetch(session, url)     log.debug('{:^6} &gt; Fetching of {} took {} seconds'.format(         post_id, url, (datetime.now() - now).total_seconds()))      if 'kids' not in response:  # base case, there are no comments         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430, \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435)     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     log.debug('{:^6} &gt; Fetching {} child posts'.format(         post_id, number_of_comments))     tasks = [post_number_of_comments(         loop, session, kid_id) for kid_id in response['kids']]      # \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442     results = await asyncio.gather(*tasks)      # \u0441\u0432\u0435\u0434\u0435\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      return number_of_comments<\/code><\/pre>\n<p>  <\/p>\n<ol>\n<li>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c JSON \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u0442\u0430.<\/li>\n<li>\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043e\u0431\u043e\u0439\u0434\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432.<\/li>\n<li>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u0438 \u0432\u0435\u0440\u043d\u0435\u043c \u043d\u043e\u043b\u044c,<br \/>  \u043a\u043e\u0433\u0434\u0430 \u0443 \u043f\u043e\u0441\u0442\u0430 \u043d\u0435\u0442 \u043e\u0442\u043a\u043b\u0438\u043a\u043e\u0432.<\/li>\n<li>\u041f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 \u043e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u043c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0441\u0442<br \/>  \u043a \u0447\u0438\u0441\u043b\u0443 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u0438 \u0432\u0435\u0440\u043d\u0435\u043c<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0411\u0440\u0435\u0442\u0442 \u0421\u043b\u0430\u0442\u043a\u0438\u043d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a <a href=\"https:\/\/www.youtube.com\/watch?v=CWmq-jtkemY\">fan-in \u0438 fan-out<\/a>, \u043c\u044b fan-out \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u0438 fan-in \u0441\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432<\/p>\n<p>  <\/p>\n<p>\u0412 API asyncio \u0435\u0441\u0442\u044c \u043f\u0430\u0440\u0443 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u0442\u0438 fan-out \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0417\u0434\u0435\u0441\u044c \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <a href=\"https:\/\/docs.python.org\/3\/library\/asyncio-task.html#asyncio.gather\">gather<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u0441\u044f \u0438 \u0432\u0435\u0440\u043d\u0443\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0432\u043e\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0442\u0430\u043a\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u0441 \u043e\u0434\u043d\u043e\u0439 \u043b\u044e\u0431\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u044e\u0431\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0441\u0432\u043e\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 gather \u0438 \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437\u044f\u0449\u043d\u043e\u0439 \u0438 (\u043b\u0435\u0433\u043a\u043e) \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435.<\/p>\n<p>  <\/p>\n<p>&quot;\u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e&quot; \u2014 \u0441\u043a\u0430\u0436\u0435\u0442\u0435 \u0432\u044b? \u041b\u0430\u0434\u043d\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u0442\u0443\u043f\u0435\u043d\u044c\u043a\u0443 \u0432\u044b\u0448\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"vystrelil-i-zabyl\">\u0412\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u043b \u0438 \u0437\u0430\u0431\u044b\u043b<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0435\u0431\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0447\u0442\u0443 \u0441 \u043f\u043e\u0441\u0442\u0430\u043c\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043a\u0430\u043a \u043c\u044b \u043e\u0431\u0445\u043e\u0434\u0438\u043b\u0438 \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u043e\u0441\u0442\u043e\u0432. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 &quot;if&quot; \u0432 \u043a\u043e\u043d\u0435\u0446 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0433\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     response = await fetch(session, url)      if 'kids' not in response:  # \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439. \u0411\u0435\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u043a\u0430\u043a \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     tasks = [post_number_of_comments(loop, session, kid_id) for kid_id in response['kids']]      # \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b     results = await asyncio.gather(*tasks)      # \u0441\u0432\u043e\u0434\u0438\u043c \u043d\u0438\u0436\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      # \u041b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0440\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     if number_of_comments &gt; MIN_COMMENTS:         await log_post(response)      return number_of_comments  async def log_post(post):     &quot;&quot;&quot;         \u0421\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430.     &quot;&quot;&quot;     await asyncio.sleep(random() * 3)     log.info(&quot;Post logged&quot;) <\/code><\/pre>\n<p>  <\/p>\n<p><em>\u0414\u0430, \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b asyncio.sleep. \u042d\u0442\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437. \u041e\u0431\u0435\u0449\u0430\u044e.<\/em><\/p>\n<p>  <\/p>\n<pre><code>[09:41:02] Post logged [09:41:04] Post logged [09:41:06] Post logged [09:41:06] &gt; Calculating comments took 6.35 seconds and 73 fetches [09:41:06] -- Post 8863 has 72 comments<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0447\u0435\u043c \u0440\u0430\u043d\u044c\u0448\u0435!<br \/>  \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e, \u043a\u0430\u043a \u043c\u044b \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, await \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 future \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e &quot;\u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0438 \u0437\u0430\u0431\u044b\u0442\u044c&quot; \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u043e\u0439, \u0430 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0436\u0434\u0430\u0442\u044c \u0435\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f await, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0431\u0435\u0437 \u0435\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u0411\u044b\u0441\u0442\u0440\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0432 \u043d\u0430 API asyncio \u043d\u0430\u0439\u0434\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <a href=\"https:\/\/docs.python.org\/3\/library\/asyncio-task.html#asyncio.ensure_future\">ensure_future<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u043e\u0431\u0435\u0440\u043d\u0435\u0442 \u0435\u0451 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 Task \u0438 \u0432\u0435\u0440\u043d\u0451\u0442. \u041f\u043e\u043c\u043d\u044f, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0431\u044b\u043b\u0430 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0446\u0438\u043a\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043a\u043e\u0433\u0434\u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u043e\u0440\u043e\u0432\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u043c await log_post \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;     \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     response = await fetch(session, url)      if 'kids' not in response:  # base case, there are no comments         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u043a\u0430\u043a \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     tasks = [post_number_of_comments(         loop, session, kid_id) for kid_id in response['kids']]      # \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b     results = await asyncio.gather(*tasks)      # \u0441\u0432\u043e\u0434\u0438\u043c \u043d\u0438\u0436\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      # \u041b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0440\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     if number_of_comments &gt; MIN_COMMENTS:         asyncio.ensure_future(log_post(response))      return number_of_comments <\/code><\/pre>\n<p>  <\/p>\n<pre><code>[09:42:57] &gt; Calculating comments took 1.69 seconds and 73 fetches [09:42:57] -- Post 8863 has 72 comments [09:42:57] Task was destroyed but it is pending! task: &lt;Task pending coro=&lt;log_post() done, defined at 02_fire_and_forget.py:82&gt; wait_for=&lt;Future pending cb=[&lt;TaskWakeupMethWrapper object at 0x1109197f8&gt;()]&gt;&gt; [09:42:57] Task was destroyed but it is pending! task: &lt;Task pending coro=&lt;log_post() done, defined at 02_fire_and_forget.py:82&gt; wait_for=&lt;Future pending cb=[&lt;TaskWakeupMethWrapper object at 0x110919948&gt;()]&gt;&gt; [09:42:57] Task was destroyed but it is pending! task: &lt;Task pending coro=&lt;log_post() done, defined at 02_fire_and_forget.py:82&gt; wait_for=&lt;Future pending cb=[&lt;TaskWakeupMethWrapper object at 0x110919978&gt;()]&gt;&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0445\u043c, \u0443\u0441\u0442\u0440\u0430\u0448\u0430\u044e\u0449\u0435\u0435 <abbr title=\"\u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0430, \u043d\u043e \u043e\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f!\">Task was destroyed but it is pending!<\/abbr> \u043f\u0440\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 asyncio \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043c\u0438\u0440\u0443. \u0425\u043e\u0440\u043e\u0448\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044c \u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 (1.69 \u0441.), \u043f\u043b\u043e\u0445\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e asyncio \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0432\u044b\u0445\u043e\u0434 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b &quot;\u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u043b-\u0438-\u0437\u0430\u0431\u044b\u043b&quot;.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b <em>post_number_of_comments<\/em>, \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 <em>log_post<\/em> \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<br \/>  \u043c\u044b \u043b\u0438\u0431\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c \u0446\u0438\u043a\u043b\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/docs.python.org\/3\/library\/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever\">run_forever<\/a>, \u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0438\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/docs.python.org\/3\/library\/asyncio-task.html#asyncio.Task.all_tasks\">all_tasks<\/a> \u043a\u043b\u0430\u0441\u0441\u0430 Task \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0436\u0434\u0435\u043c \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0440\u0430\u0441\u0447\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0432\u043d\u0435\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <em>post_number_of_comments<\/em>:<\/p>\n<p>  <\/p>\n<pre><code>if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      post_id = id_from_HN_url(args.url) if args.url else args.id     loop = asyncio.get_event_loop()     with aiohttp.ClientSession(loop=loop) as session:         now = datetime.now()         comments = loop.run_until_complete(             post_number_of_comments(loop, session, post_id))         log.info(             '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_counter))         log.info(&quot;-- Post {} has {} comments&quot;.format(post_id, comments))      pending_tasks = [         task for task in asyncio.Task.all_tasks() if not task.done()]     loop.run_until_complete(asyncio.gather(*pending_tasks))     loop.close()<\/code><\/pre>\n<p>  <\/p>\n<pre><code>[09:47:29] &gt; Calculating comments took 1.72 seconds and 73 fetches [09:47:29] \u2014 Post 8863 has 72 comments [09:47:30] Post logged [09:47:31] Post logged [09:47:32] Post logged<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b.<br \/>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u0435\u0442\u043e\u0434 <em>all_tasks<\/em> \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e, \u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u0438\u0434\u0435\u044f, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432 \u043d\u0430\u0448\u0435\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043d\u043e \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0437\u0430\u0434\u0430\u0447, \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u2014 \u043d\u0430\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f, \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c \u0440\u0430\u043d\u0435\u0435,<br \/>  \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432. \u041a\u0430\u043a \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>ensure_future<\/em> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <em>Task<\/em>, \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0441 \u043d\u0438\u0437\u043a\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a <em>task_registry<\/em> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432 \u043d\u0435\u043c futures:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;Retrieve data for current post and recursively for all comments.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     response = await fetch(session, url)      if 'kids' not in response:  # base case, there are no comments         return 0      # calculate this post's comments as number of comments     number_of_comments = len(response['kids'])      # create recursive tasks for all comments     tasks = [post_number_of_comments(         loop, session, kid_id) for kid_id in response['kids']]      # schedule the tasks and retrieve results     results = await asyncio.gather(*tasks)      # reduce the descendents comments and add it to this post's     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      # Log if number of comments is over a threshold     if number_of_comments &gt; MIN_COMMENTS:         # Add the future to the registry         task_registry.append(asyncio.ensure_future(log_post(response)))      return number_of_comments  # (... ommitted code ...) #  if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      post_id = id_from_HN_url(args.url) if args.url else args.id     loop = asyncio.get_event_loop()      task_registry = []  # define our task registry      with aiohttp.ClientSession(loop=loop) as session:         now = datetime.now()         comments = loop.run_until_complete(             post_number_of_comments(loop, session, post_id))         log.info(             '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_counter))         log.info(&quot;-- Post {} has {} comments&quot;.format(post_id, comments))      pending_tasks = [task for task in task_registry if not task.done()]     loop.run_until_complete(asyncio.gather(*pending_tasks))     loop.close()<\/code><\/pre>\n<p>  <\/p>\n<pre><code>[09:53:46] &gt; Calculating comments took 1.68 seconds and 73 fetches [09:53:46] \u2014 Post 8863 has 72 comments [09:53:46] Post logged [09:53:48] Post logged [09:53:49] Post logged<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0440\u043e\u043a \u2014 <em>asyncio<\/em> \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0434\u0430\u0447 \u0442\u0438\u043f\u0430 <a href=\"http:\/\/celeryproject.org\/\"><em>Celery<\/em><\/a>. \u0412\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u0446\u0438\u043a\u043b\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u043e\u043c\u0443 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443:<\/p>\n<p>  <\/p>\n<h2 id=\"periodicheski-zapuskaemye-korutiny\">\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u044f \u0441 \u043d\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u043e HN(\u0438 \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u043e\u0432\u0435\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443), \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438,<br \/>  \u0447\u0442\u043e \u0440\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0430\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043a \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 HN \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0438 \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 5 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043d\u0430 API HN \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 500 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 \u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043a \u043d\u0438\u043c, \u0441\u043a\u0430\u0436\u0435\u043c \u0440\u0430\u0437 \u0432 \u043f\u044f\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u043e\u043f\u0440\u043e\u0441\u0443, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 <em>while<\/em> \u0446\u0438\u043a\u043b, \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u043f\u0440\u043e\u0441\u0430 (\u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <em>await<\/em>), \u0438 <em>\u0437\u0430\u0441\u044b\u043f\u0430\u0442\u044c<\/em>(\u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <em>sleep<\/em>) \u043d\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u042f \u0432\u043d\u0435\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u043f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 URL \u043f\u043e\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">&quot;&quot;&quot; An example of periodically scheduling coroutines using an infinite loop of awaiting and sleeping. &quot;&quot;&quot;  import asyncio import argparse import logging from datetime import datetime  import aiohttp import async_timeout  LOGGER_FORMAT = '%(asctime)s %(message)s' URL_TEMPLATE = &quot;https:\/\/hacker-news.firebaseio.com\/v0\/item\/{}.json&quot; TOP_STORIES_URL = &quot;https:\/\/hacker-news.firebaseio.com\/v0\/topstories.json&quot; FETCH_TIMEOUT = 10  parser = argparse.ArgumentParser(description='Calculate the number of comments of the top stories in HN.') parser.add_argument('--period', type=int, default=5, help='Number of seconds between poll') parser.add_argument('--limit', type=int, default=5,help='Number of new stories to calculate comments for') parser.add_argument('--verbose', action='store_true', help='Detailed output')  logging.basicConfig(format=LOGGER_FORMAT, datefmt='[%H:%M:%S]') log = logging.getLogger() log.setLevel(logging.INFO)  fetch_counter = 0  async def fetch(session, url):     &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f aiohttp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u043d\u043d\u044b\u0439 JSON \u043e\u0442\u0432\u0435\u0442.         \u041a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 aiohttp \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0441\u0441\u0438\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.     &quot;&quot;&quot;     global fetch_counter     with async_timeout.timeout(FETCH_TIMEOUT):         fetch_counter += 1         async with session.get(url) as response:             return await response.json()  async def post_number_of_comments(loop, session, post_id):     &quot;&quot;&quot;         \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     response = await fetch(session, url)      if 'kids' not in response:  # base case, there are no comments         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430, \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435)     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     tasks = [post_number_of_comments(         loop, session, kid_id) for kid_id in response['kids']]      # \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b     results = await asyncio.gather(*tasks)      # \u0441\u0432\u043e\u0434\u0438\u043c \u043d\u0438\u0436\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      return number_of_comments  async def get_comments_of_top_stories(loop, session, limit, iteration):     &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430 HN.     &quot;&quot;&quot;     response = await fetch(session, TOP_STORIES_URL)     tasks = [post_number_of_comments(loop, session, post_id) for post_id in response[:limit]]     results = await asyncio.gather(*tasks)     for post_id, num_comments in zip(response[:limit], results):         log.info(&quot;Post {} has {} comments ({})&quot;.format(post_id, num_comments, iteration))  async def poll_top_stories_for_comments(loop, session, period, limit):     &quot;&quot;&quot;         \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438  \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     global fetch_counter     iteration = 1     while True:         now = datetime.now()         log.info(&quot;Calculating comments for top {} stories. ({})&quot;.format(limit, iteration))         await get_comments_of_top_stories(loop, session, limit, iteration)          log.info('&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_counter))         log.info(&quot;Waiting for {} seconds...&quot;.format(period))         iteration += 1         fetch_counter = 0         await asyncio.sleep(period)  if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      loop = asyncio.get_event_loop()     with aiohttp.ClientSession(loop=loop) as session:         loop.run_until_complete(             poll_top_stories_for_comments(                 loop, session, args.period, args.limit))      loop.close()<\/code><\/pre>\n<p>  <\/p>\n<pre><code>[10:14:03] Calculating comments for top 5 stories. (1) [10:14:06] Post 13848196 has 31 comments (1) [10:14:06] Post 13849430 has 37 comments (1) [10:14:06] Post 13849037 has 15 comments (1) [10:14:06] Post 13845337 has 128 comments (1) [10:14:06] Post 13847465 has 27 comments (1) [10:14:06] &gt; Calculating comments took 2.96 seconds and 244 fetches [10:14:06] Waiting for 5 seconds\u2026 [10:14:11] Calculating comments for top 5 stories. (2) [10:14:14] Post 13848196 has 31 comments (2) [10:14:14] Post 13849430 has 37 comments (2) [10:14:14] Post 13849037 has 15 comments (2) [10:14:14] Post 13845337 has 128 comments (2) [10:14:14] Post 13847465 has 27 comments (2) [10:14:14] &gt; Calculating comments took 3.04 seconds and 244 fetches [10:14:14] Waiting for 5 seconds\u2026<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u0435\u0441\u043b\u0438 \u0432\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043b\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u0442\u043c\u0435\u0442\u043a\u0443,<br \/>  \u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0437 \u0432 5 \u0441\u0435\u043a\u0443\u043d\u0434, \u043e\u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 5 \u0441\u0435\u043a\u0443\u043d\u0434 <strong><em>\u043f\u043e\u0441\u043b\u0435<\/em><\/strong> \u0442\u043e\u0433\u043e \u043a\u0430\u043a <strong>_\u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 get_comments_of_top<em>stories<\/em><\/strong>. \u0421\u043d\u043e\u0432\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <em>await<\/em> \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0430\u0448\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u043e.<br \/>  \u042d\u0442\u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0447\u0435\u043c \u043f\u044f\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434. \u0422\u0430\u043a\u0436\u0435, \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c _run_until<em>complete<\/em> \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0441\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043a\u0430\u043a \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u044b \u043f\u043e _ensure<em>future<\/em>, \u0438 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043f\u0438\u0445\u043d\u0443\u0442\u044c \u0435\u0435 \u0432 \u043a\u043e\u0434 \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <em>await<\/em>&#8230;<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def poll_top_stories_for_comments(loop, session, period, limit):     &quot;&quot;&quot;         \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438  \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     global fetch_counter     iteration = 1     while True:         now = datetime.now()         log.info(&quot;Calculating comments for top {} stories. ({})&quot;.format(             limit, iteration))         asyncio.ensure_future(             get_comments_of_top_stories(loop, session, limit, iteration))          log.info(             '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_counter))         log.info(&quot;Waiting for {} seconds...&quot;.format(period))         iteration += 1         fetch_counter = 0         await asyncio.sleep(period) <\/code><\/pre>\n<p>  <\/p>\n<pre><code>    [10:55:40] Calculating comments for top 5 stories. (1)     [10:55:40] &gt; Calculating comments took 0.00 seconds and 0 fetches     [10:55:40] Waiting for 5 seconds\u2026     [10:55:43] Post 13848196 has 32 comments (1)     [10:55:43] Post 13849430 has 48 comments (1)     [10:55:43] Post 13849037 has 16 comments (1)     [10:55:43] Post 13845337 has 129 comments (1)     [10:55:43] Post 13847465 has 29 comments (1)     [10:55:45] Calculating comments for top 5 stories. (2)     [10:55:45] &gt; Calculating comments took 0.00 seconds and 260 fetches     [10:55:45] Waiting for 5 seconds\u2026     [10:55:48] Post 13848196 has 32 comments (2)     [10:55:48] Post 13849430 has 48 comments (2)     [10:55:48] Post 13849037 has 16 comments (2)     [10:55:48] Post 13845337 has 129 comments (2)     [10:55:48] Post 13847465 has 29 comments (2)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0445\u043c\u2026 \u041b\u0430\u0434\u043d\u043e, \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043e\u0442\u043c\u0435\u0442\u043a\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u044f\u0442\u044c \u0441\u0435\u043a\u0443\u043d\u0434, \u043d\u043e \u0447\u0442\u043e \u0437\u0430 0.00 \u0441\u0435\u043a\u0443\u043d\u0434 \u0438 \u043d\u0435\u0442 \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0418 \u0437\u0430\u0442\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u043e\u043b\u044c \u0441\u0435\u043a\u0443\u043d\u0434 \u0438 260 \u0432\u044b\u0431\u043e\u0440\u043e\u043a?<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0434\u043d\u043e \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0439 \u0443\u0445\u043e\u0434\u0430 \u043e\u0442 await, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u043d\u043e\u043b\u044c \u0441\u0435\u043a\u0443\u043d\u0434 \u0438, \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437, \u043d\u043e\u043b\u044c \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u0435\u043b\u043a\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0436\u0438\u0442\u044c \u0431\u0435\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043d\u043e \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447?<\/p>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430, \u043c\u043e\u0439 \u0434\u0440\u0443\u0433, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0431\u0435\u0433\u043d\u0443\u0442\u044c \u043a\u2026 callback-\u0430\u043c (\u043f\u043e\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u0441\u044f((( )<\/p>\n<p>  <\/p>\n<p>\u042f \u0437\u043d\u0430\u044e, \u0437\u043d\u0430\u044e, \u0432\u0435\u0441\u044c \u0441\u043c\u044b\u0441\u043b \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c callback \u2014 \u043e\u0432, \u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0434\u0440\u0430\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u0434\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 &quot;\u0417\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 await&quot;. \u041c\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0430 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u0438 <em>await<\/em>, \u0443 \u043d\u0430\u0441 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441 \u0440\u0443\u0447\u043d\u044b\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0437\u0430\u0434\u0430\u0447 \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0427\u0442\u043e \u044d\u0442\u043e \u0432\u0430\u043c \u0434\u0430\u0435\u0442? <abbr title=\"\u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u043f\u043b\u043e\u0445\u043e\">spoiler<\/abbr><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043c\u044b \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 _ensure<em>future<\/em> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <em>Future<\/em>, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c callback \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f _add_done<em>callback<\/em>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u043c, \u0438 \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u0432\u044b\u0431\u043e\u0440\u043e\u043a(fetches) \u043c\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043c \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043b\u0430\u0441\u0441 <em>URLFetcher<\/em>. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0447\u0442\u043e\u0431\u044b \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043f\u043e\u0434\u0441\u0447\u0435\u0442 \u0432\u044b\u0431\u043e\u0440\u043e\u043a. \u0422\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0432\u043d\u043e\u0441\u0438\u043b\u0430 \u0431\u0430\u0433:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">&quot;&quot;&quot;     \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e     \u0446\u0438\u043a\u043b\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0437\u0430\u0434\u0430\u0447 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 ensure_future \u0438 \u0432\u044b\u0437\u043e\u0432\u0430 sleep.     \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 future, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f ensure_future,     \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u0432\u044b\u0431\u043e\u0440\u043e\u043a,     \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 URLFetcher     \u041d\u043e \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0443\u0445\u0443\u0434\u0448\u0430\u0435\u0442\u0441\u044f. &quot;&quot;&quot;  import asyncio import argparse import logging from datetime import datetime  import aiohttp import async_timeout  LOGGER_FORMAT = '%(asctime)s %(message)s' URL_TEMPLATE = &quot;https:\/\/hacker-news.firebaseio.com\/v0\/item\/{}.json&quot; TOP_STORIES_URL = &quot;https:\/\/hacker-news.firebaseio.com\/v0\/topstories.json&quot; FETCH_TIMEOUT = 10  parser = argparse.ArgumentParser(description='Calculate the number of comments of the top stories in HN.') parser.add_argument('--period', type=int, default=5, help='Number of seconds between poll') parser.add_argument('--limit', type=int, default=5, help='Number of new stories to calculate comments for') parser.add_argument('--verbose', action='store_true', help='Detailed output')  logging.basicConfig(format=LOGGER_FORMAT, datefmt='[%H:%M:%S]') log = logging.getLogger() log.setLevel(logging.INFO)  class URLFetcher():     &quot;&quot;&quot;         \u041e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0441\u0447\u0435\u0442 URL \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438     &quot;&quot;&quot;      def __init__(self):         self.fetch_counter = 0      async def fetch(self, session, url):         &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f aiohttp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u0440\u043d\u044b\u0439 JSON \u043e\u0442\u0432\u0435\u0442.         \u041a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 aiohttp \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0441\u0441\u0438\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.         &quot;&quot;&quot;         with async_timeout.timeout(FETCH_TIMEOUT):             self.fetch_counter += 1             async with session.get(url) as response:                 return await response.json()  async def post_number_of_comments(loop, session, fetcher, post_id):     &quot;&quot;&quot;         \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     url = URL_TEMPLATE.format(post_id)     response = await fetcher.fetch(session, url)      # \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439. \u041d\u0435\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     if response is None or 'kids' not in response:         return 0      # \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430, \u043a\u0430\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 (\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435)     number_of_comments = len(response['kids'])      # \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432     tasks = [post_number_of_comments(         loop, session, fetcher, kid_id) for kid_id in response['kids']]      # s\u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b     results = await asyncio.gather(*tasks)      # \u0441\u0432\u043e\u0434\u0438\u043c \u043d\u0438\u0436\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430     number_of_comments += sum(results)     log.debug('{:^6} &gt; {} comments'.format(post_id, number_of_comments))      return number_of_comments  async def get_comments_of_top_stories(loop, session, limit, iteration):     &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u043e\u043f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 HN.     &quot;&quot;&quot;     fetcher = URLFetcher()  # create a new fetcher for this task     response = await fetcher.fetch(session, TOP_STORIES_URL)     tasks = [post_number_of_comments(         loop, session, fetcher, post_id) for post_id in response[:limit]]     results = await asyncio.gather(*tasks)     for post_id, num_comments in zip(response[:limit], results):         log.info(&quot;Post {} has {} comments ({})&quot;.format(             post_id, num_comments, iteration))     return fetcher.fetch_counter  # return the fetch count  async def poll_top_stories_for_comments(loop, session, period, limit):     &quot;&quot;&quot;         \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438  \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     iteration = 1     while True:         log.info(&quot;Calculating comments for top {} stories. ({})&quot;.format(limit, iteration))          future = asyncio.ensure_future(get_comments_of_top_stories(loop, session, limit, iteration))          now = datetime.now()          def callback(fut):             fetch_count = fut.result()             log.info('&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                     (datetime.now() - now).total_seconds(), fetch_count))          future.add_done_callback(callback)          log.info(&quot;Waiting for {} seconds...&quot;.format(period))         iteration += 1         await asyncio.sleep(period)  if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      loop = asyncio.get_event_loop()     with aiohttp.ClientSession(loop=loop) as session:         loop.run_until_complete(             poll_top_stories_for_comments(                 loop, session, args.period, args.limit))      loop.close()<\/code><\/pre>\n<p>  <\/p>\n<pre><code>    [12:23:40] Calculating comments for top 5 stories. (1)     [12:23:40] Waiting for 5 seconds...     [12:23:43] Post 13848196 has 38 comments (1)     [12:23:43] Post 13849430 has 72 comments (1)     [12:23:43] Post 13849037 has 19 comments (1)     [12:23:43] Post 13848283 has 64 comments (1)     [12:23:43] Post 13847465 has 34 comments (1)     [12:23:43] &gt; Calculating comments took 3.17 seconds and 233 fetches     [12:23:45] Calculating comments for top 5 stories. (2)     [12:23:45] Waiting for 5 seconds...     [12:23:47] Post 13848196 has 38 comments (2)     [12:23:47] Post 13849430 has 72 comments (2)     [12:23:47] Post 13849037 has 19 comments (2)     [12:23:47] Post 13848283 has 64 comments (2)     [12:23:47] Post 13847465 has 34 comments (2)     [12:23:47] &gt; Calculating comments took 2.47 seconds and 233 fetches     [12:23:50] Calculating comments for top 5 stories. (3)     [12:23:50] Waiting for 5 seconds...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0443\u0436\u0435 \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0444\u043e\u043a\u0443\u0441\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u0435\u043a\u0446\u0438\u0438 callback:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">async def poll_top_stories_for_comments(loop, session, period, limit):     &quot;&quot;&quot;         \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438  \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432.     &quot;&quot;&quot;     iteration = 1     while True:         log.info(&quot;Calculating comments for top {} stories. ({})&quot;.format(             limit, iteration))          future = asyncio.ensure_future(             get_comments_of_top_stories(loop, session, limit, iteration))          now = datetime.now()          def callback(fut):             fetch_count = fut.result()             log.info(                 '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                     (datetime.now() - now).total_seconds(), fetch_count))          future.add_done_callback(callback)          log.info(&quot;Waiting for {} seconds...&quot;.format(period))         iteration += 1         await asyncio.sleep(period) <\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e <em>callback<\/em> <a href=\"https:\/\/docs.python.org\/3\/library\/asyncio-task.html#asyncio.Future.add_done_callback\">\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442 future.<\/a> \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u0431\u043e\u0440\u043e\u043a(fetch) \u0438\u0437 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 <em>URLFetcher<\/em> \u043a\u0430\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 _get_comments_of_top<em>stories<\/em> \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 future.<\/p>\n<p>  <\/p>\n<p>\u0412\u0438\u0434\u0438\u0442\u0435? \u042f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0432\u0430\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0437\u0430\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u0447\u043d\u043e \u043d\u0435\u0442 <em>await<\/em>. <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u043c callback-\u0438, \u043f\u0440\u0438 \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u044b\u0445 \u0441\u043a\u0438\u0442\u0430\u043d\u0438\u044f\u0445 \u043f\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 API asyncio \u0432\u0430\u043c \u043f\u043e\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 <em>AbstractBaseLoop<\/em> \u0441 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 _call<em>later<\/em> \u0438 _call<em>at<\/em>,<br \/>  \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043a\u0430\u043a \u0447\u0442\u043e-\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b. \u0418 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u0440\u0430\u0432\u044b, \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 <em>poll_top_stories_for_comments<\/em>:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\"> def poll_top_stories_for_comments(loop, session, period, limit, iteration=0):     &quot;&quot;&quot;     \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 get_comments_of_top_stories.     &quot;&quot;&quot;     log.info(&quot;Calculating comments for top {} stories ({})&quot;.format(         limit, iteration))      future = asyncio.ensure_future(         get_comments_of_top_stories(loop, session, limit, iteration))      now = datetime.now()      def callback(fut):         fetch_count = fut.result()         log.info(             '&gt; Calculating comments took {:.2f} seconds and {} fetches'.format(                 (datetime.now() - now).total_seconds(), fetch_count))      future.add_done_callback(callback)      log.info(&quot;Waiting for {} seconds...&quot;.format(period))      iteration += 1     loop.call_later(         period,         partial(  # or call_at(loop.time() + period)             poll_top_stories_for_comments,             loop, session, period, limit, iteration         )     )  if __name__ == '__main__':     args = parser.parse_args()     if args.verbose:         log.setLevel(logging.DEBUG)      loop = asyncio.get_event_loop()     with aiohttp.ClientSession(loop=loop) as session:         poll_top_stories_for_comments(             loop, session, args.period, args.limit)          loop.run_forever()      loop.close() <\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0440\u0430\u043d\u0435\u0435. \u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041c\u044b \u0443\u0448\u043b\u0438 \u043e\u0442 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u0437\u0430\u0441\u044b\u043f\u0430\u043d\u0438\u044f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f _ensure<em>future<\/em> \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f.<br \/>  (\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430: \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434)<\/li>\n<li>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 _poll_top_stories_for<em>comments<\/em> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u0430 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0430\u043c\u043e\u0439 \u0441\u0435\u0431\u044f, \u043c\u044b \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e _run<em>forever<\/em> \u0446\u0438\u043a\u043b\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0431\u044b\u043b \u0432\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041b\u0430\u0434\u043d\u043e, \u044d\u0442\u043e \u0432\u0441\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u0434\u0430\u0436\u0435 \u043f\u0440\u0435\u0432\u043e\u0441\u0445\u043e\u0434\u043d\u043e, \u043d\u043e, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0411\u043e\u0433 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u2014 \u043d\u0430\u0448\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438? \u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0441 \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432\u044b\u0431\u0440\u043e\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 URL:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\"> MAXIMUM_FETCHES = 5  class URLFetcher():     &quot;&quot;&quot;         \u041e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0441\u0447\u0435\u0442 URL \u0432\u044b\u0431\u043e\u0440\u043e\u043a \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438     &quot;&quot;&quot;      def __init__(self):         self.fetch_counter = 0      async def fetch(self, session, url):         &quot;&quot;&quot;         \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c URL \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f aiohttp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u0440\u043d\u044b\u0439 JSON \u043e\u0442\u0432\u0435\u0442.         \u041a\u0430\u043a \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 aiohttp \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0441\u0441\u0438\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e.         &quot;&quot;&quot;         with async_timeout.timeout(FETCH_TIMEOUT):             self.fetch_counter += 1             if self.fetch_counter &gt; MAXIMUM_FETCHES:                 raise Exception('BOOM!')              async with session.get(url) as response:                 return await response.json() <\/code><\/pre>\n<p>  <\/p>\n<pre><code>    [12:51:00] Calculating comments for top 5 stories. (1)     [12:51:00] Waiting for 5 seconds\u2026     [12:51:01] Exception in callback poll_top_stories_for_comments.&lt;locals&gt;.callback(&lt;Task finishe\u2026ion(\u2018BOOM!\u2019,)&gt;) at 05_periodic_coroutines.py:121     handle: &lt;Handle poll_top_stories_for_comments.&lt;locals&gt;.callback(&lt;Task finishe\u2026ion(\u2018BOOM!\u2019,)&gt;) at 05_periodic_coroutines.py:121&gt;     Traceback (most recent call last):      File \u201c\/Users\/yeray\/.pyenv\/versions\/3.6.0\/lib\/python3.6\/asyncio\/events.py\u201d, line 126, in _run      self._callback(*self._args)      File \u201c05_periodic_coroutines.py\u201d, line 122, in callback      fetch_count = fut.result()      File \u201c05_periodic_coroutines.py\u201d, line 100, in get_comments_of_top_stories      results = await asyncio.gather(*tasks)      File \u201c05_periodic_coroutines.py\u201d, line 69, in post_number_of_comments      response = await fetcher.fetch(session, url)      File \u201c05_periodic_coroutines.py\u201d, line 58, in fetch      raise Exception(\u2018BOOM!\u2019)     Exception: BOOM!     [12:51:05] Calculating comments for top 5 stories. (2)     [12:51:05] Waiting for 5 seconds\u2026<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0435 \u0442\u0430\u043a \u0437\u0434\u043e\u0440\u043e\u0432\u043e, \u043f\u0440\u0430\u0432\u0434\u0430?<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c? \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438, \u0433\u0434\u0435 \u044f \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447: <a href=\"https:\/\/medium.com\/@yeraydiazdiaz\/asyncio-coroutine-patterns-errors-and-cancellation-3bb422e961ff\">\u041f\u0430\u0442\u0442\u0435\u0440\u043d\u044b asyncio \u043a\u043e\u0440\u0443\u0442\u0438\u043d: \u041e\u0448\u0438\u0431\u043a\u0438 \u0438 \u041e\u0442\u043c\u0435\u043d\u0430<\/a><\/p>\n<p><cut\/><\/div>\n<p>        <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/post\/420129\/\"> https:\/\/habr.com\/post\/420129\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/420129\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><em>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430:<br \/>  \u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0440\u0430\u0437 \u043d\u0430\u0441\u0442\u0443\u043f\u0438\u0432 \u043d\u0430 \u0433\u0440\u0430\u0431\u043b\u0438 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 python asyncio \u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u044b \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435, \u0447\u0435\u043c \u0441\u0443\u0445\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \u041c\u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/medium.com\/python-pandemonium\/asyncio-coroutine-patterns-beyond-await-a6121486656f\">Yeray Diaz &quot;Asyncio Coroutine Patterns: Beyond await&quot;<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u0432\u0442\u043e\u0440 \u0432\u0435\u0441\u044c\u043c\u0430 \u0443\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 asyncio \u0438 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u0438\u0435\u043c\u0430\u043c\u0438. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043d\u0438\u0447\u0435\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u0436\u0435 \u0446\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u0442\u043e \u0440\u0435\u0448\u0438\u043b\u0441\u044f \u0435\u0451 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438. <\/em><\/p>\n<p>  <\/p>\n<p>Asyncio \u2014 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u0430\u044f \u043c\u0435\u0447\u0442\u0430 python \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430: \u043f\u0438\u0448\u0435\u0448\u044c \u043a\u043e\u0434, \u0433\u0440\u0430\u043d\u0438\u0447\u0430\u0449\u0438\u0439 \u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c, \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0448\u044c Python \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435. \u042d\u0442\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0438\u043c\u043f\u043e\u0440\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0430\u043d\u0442\u0438\u0433\u0440\u0430\u0432\u0438\u0442\u0430\u0446\u0438\u0438: <a href=\"http:\/\/xkcd.com\/353\/\">import antigravity<\/a><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0442\u0430\u043a, \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u0442\u044f\u0436\u0435\u043b\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435 \u0438, \u043f\u043e\u043a\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0430\u043c \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0430\u0434\u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0443\u0432\u0435\u0441\u0442\u0438 \u0432\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u043b\u0435\u043a\u043e, \u0432\u0430\u043c \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439. \u041f\u0435\u0447\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 asyncio. \u041f\u043b\u043e\u0445\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0440\u0430\u0437\u0443 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0447\u0442\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u041d\u0438\u0436\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 asyncio.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-287331","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=287331"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287331\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=287331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=287331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=287331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}