{"id":475319,"date":"2025-09-17T05:13:51","date_gmt":"2025-09-17T05:13:51","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=475319"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=475319","title":{"rendered":"\u0421\u0435\u0440\u0432\u0438\u0441 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0438\u043b\u0438 \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0433\u043d\u0430\u0442\u044c \u043a\u043e\u0434 \u043f\u043e\u0434 \u0432\u0441\u0435 \u0441\u043b\u0443\u0447\u0430\u0438"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0441\u043d\u043e\u0432\u0430 \u043f\u0438\u0441\u0430\u0442\u0435\u043b\u044c-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 <a href=\"https:\/\/simpl-group.ru\/\" rel=\"noopener noreferrer nofollow\">Simpl Group<\/a> (\u0434\u0430, \u0431\u0435\u0437 e).<br \/>\u0421\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b\u0430 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c Meet Up \u2014 \u0443\u0436\u0435 6-\u043c, \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0447\u0438\u043c, \u2014 \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b\u0430 \u0441\u0432\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0432\u0435\u0434\u0430\u044e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438 \u0432\u0430\u043c. \u041d\u0435 \u043f\u0440\u043e \u0432\u0435\u0434\u044c\u043c \u0438 \u0434\u0435\u043c\u043e\u043d\u043e\u0432, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u0430\u043a \u0432 \u043c\u043e\u0435\u0439 \u043a\u043d\u0438\u0433\u0435. \u0410 \u043f\u0440\u043e \u0446\u0438\u0440\u043a \u2014 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u0440\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447\u0438, \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u0445 \u0438 \u043d\u0435 \u043f\u0430\u0434\u0430\u044e\u0442.<br \/>\u0418\u043b\u0438, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0430\u0434\u0430\u043b\u0438.<\/p>\n<p>(\u041a \u0441\u043b\u043e\u0432\u0443, \u043a\u043d\u0438\u0433\u0443 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c: <a href=\"https:\/\/www.litres.ru\/book\/ingini\/poroki-71906656\/\" rel=\"noopener noreferrer nofollow\">\u00ab\u041f\u043e\u0440\u043e\u043a\u0438\u00bb, Ingini<\/a>)<\/p>\n<h2>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e <\/h2>\n<p>\u0423 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043c\u0435\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0442\u0440\u044e\u043a \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0440\u0430\u0441\u0447\u0451\u0442. \u0412\u0441\u0451, \u043a\u0430\u043a \u0432 \u0441\u0442\u0430\u0440\u043e\u043c \u0446\u0438\u0440\u043a\u0435: \u043e\u0434\u0438\u043d \u0430\u0440\u0442\u0438\u0441\u0442, \u043e\u0434\u0438\u043d \u043d\u043e\u043c\u0435\u0440.<\/p>\n<p>\u041d\u043e \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u0418 \u0437\u0430 \u043d\u0435\u0439 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430. \u0418 \u0432\u043e\u0442 \u0443\u0436\u0435 \u0437\u0440\u0438\u0442\u0435\u043b\u0438 \u0445\u043e\u0442\u044f\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044b\u0436\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447, \u043d\u043e \u0438 \u043c\u0435\u0434\u0432\u0435\u0434\u044f \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0435, \u0436\u043e\u043d\u0433\u043b\u0451\u0440\u043e\u0432, \u0430\u043a\u0440\u043e\u0431\u0430\u0442\u043e\u0432 \u0438 \u0434\u0430\u0436\u0435 \u043a\u0438\u0431\u0435\u0440\u0434\u0440\u0430\u043a\u043e\u043d\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0441\u0451 \u0448\u043e\u0443. \u0422\u0430\u043a, \u0447\u0442\u043e\u0431\u044b:<\/p>\n<ul>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0430\u0440\u0442\u0438\u0441\u0442\u043e\u0432 <strong>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u0438\u043b\u0438\u044f\u043c\u0438<\/strong>;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043c\u0430\u043d\u0435\u0436 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437;<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e: \u043d\u0430\u0434\u0451\u0436\u043d\u043e, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u043d\u043e.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041a\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0446\u0438\u0440\u043a\u0435 \u2014 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0448\u043e\u0443<\/h2>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:<br \/><em>\u041e\u0434\u043d\u0430 <\/em>\u2014 \u044d\u0442\u043e \u043b\u043e\u0448\u0430\u0434\u043a\u0438, \u043f\u0440\u044b\u0433\u0430\u044e\u0449\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447;<br \/><em>\u0412\u0442\u043e\u0440\u0430\u044f <\/em>\u2014 \u044d\u0442\u043e \u043c\u0438\u0448\u043a\u0430 \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0435, \u043f\u0440\u043e\u0435\u0437\u0436\u0430\u044e\u0449\u0438\u0439 \u0442\u043e \u0432 \u043e\u0434\u043d\u0443, \u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443.<\/p>\n<p>\u0427\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0449\u0435\u0433\u043e \u0432 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f\u0445?<\/p>\n<ul>\n<li>\n<p><strong>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b<\/strong> \u2014 \u0434\u0440\u0435\u0441\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438, \u043f\u043e\u0434\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0433\u043e\u043b\u043e\u0441\u043e\u043c: \u00ab\u0412\u043f\u0435\u0440\u0451\u0434!\u00bb.<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/strong> \u2014 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u043e\u0440\u044b, \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043d\u0430\u0440\u044f\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u043a\u043b\u0430\u0434\u0430 (\u0411\u0414).<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0447\u0435\u0440\u0435\u0434\u0438<\/strong> \u2014 \u043c\u0430\u043d\u0435\u0436, \u0433\u0434\u0435 \u0430\u0440\u0442\u0438\u0441\u0442\u044b \u0436\u0434\u0443\u0442, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u044f\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u043e\u0440<\/strong> \u2014 \u0442\u0451\u043c\u043d\u044b\u0439 \u043a\u043e\u0440\u0438\u0434\u043e\u0440, \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u043e\u0442 \u043a\u0443\u043b\u0438\u0441 \u043a \u0441\u0432\u0435\u0442\u0443 \u0440\u0430\u043c\u043f\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b<\/strong> \u2014 \u0434\u0432\u0435\u0440\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043a\u0443\u043b\u0438\u0441\u044c\u0435\u043c \u0438 \u0441\u0446\u0435\u043d\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>\u0414\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b<\/strong> \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0446\u0435\u043d\u0430, \u0433\u0434\u0435 \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u043e\u043c\u0435\u0440.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441:<\/p>\n<ul>\n<li>\n<p>\u041b\u043e\u0448\u0430\u0434\u043a\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 <strong>\u043f\u043e \u043e\u0434\u043d\u043e\u0439<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0434\u0432\u0435\u0434\u0438 \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f <strong>\u043f\u043e \u0442\u0440\u043e\u0435<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0442\u043e-\u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 <strong>Kafka<\/strong>, \u043a\u0442\u043e-\u0442\u043e \u2014 \u0447\u0435\u0440\u0435\u0437 <strong>HTTP<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u0430\u0440\u043e\u0447\u043a\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0439, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043a\u0443\u043b\u0438\u0441\u044b \u0438 \u0434\u0440\u0435\u0441\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u0443 \u043c\u0438\u0448\u0435\u043a \u0438 \u043b\u043e\u0448\u0430\u0434\u043e\u043a \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435, \u0430 \u0434\u0432\u0435\u0440\u0438, \u0430\u043a\u0442\u0435\u0440\u044b \u0438 \u0441\u0446\u0435\u043d\u044b \u0440\u0430\u0437\u043d\u044b\u0435.<\/p>\n<h2>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043d\u0430\u0448 \u043c\u0430\u043d\u0435\u0436 \u2014 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, <strong>\u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0448 \u0446\u0438\u0440\u043a \u0438\u0437\u043d\u0443\u0442\u0440\u0438<\/strong>. \u0427\u0442\u043e \u0442\u0430\u043c \u0432 \u043a\u0443\u043b\u0438\u0441\u0430\u0445, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043f\u043e\u0442\u044b\u043a\u0430\u0435\u0442\u0441\u044f?<\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430:<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c <strong>\u0435\u0434\u0438\u043d\u044b\u0439 \u0446\u0438\u0440\u043a<\/strong>, \u043a\u0443\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0432\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0430\u0440\u0442\u0438\u0441\u0442\u0430: \u0445\u043e\u0442\u044c \u043c\u0435\u0434\u0432\u0435\u0434\u044f, \u0445\u043e\u0442\u044c \u0436\u043e\u043d\u0433\u043b\u0451\u0440\u0430, \u043d\u0443 \u0438 \u0434\u0430, \u043a\u0438\u0431\u0435\u0440\u0434\u0440\u0430\u043a\u043e\u043d\u0430 \u0442\u043e\u0436\u0435.<\/p>\n<h3>\u0412 \u0431\u0430\u0437\u0435<\/h3>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u043b\u043e\u044f \u043a\u043e\u0441\u0442\u044e\u043c\u0430:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0431\u0449\u0438\u0439<\/strong>: ID, \u0442\u0438\u043f, \u0441\u0442\u0430\u0442\u0443\u0441, \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0439<\/strong>: \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0430\u0440\u0442\u0438\u0441\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"sql\">task                       -- \u043e\u0431\u0449\u0438\u0439 \u0441\u043a\u043b\u0430\u0434 \u0437\u0430\u0434\u0430\u0447 task_{taskType}_parameters -- \u0433\u0430\u0440\u0434\u0435\u0440\u043e\u0431 \u0434\u043b\u044f \u043a\u043e\u0441\u0442\u044e\u043c\u043e\u0432<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0412 \u043a\u043e\u0434\u0435<\/h3>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043d\u0430\u0448\u0435 \u043e\u0440\u0443\u0436\u0438\u0435 \u2014 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a \u043a\u043b\u0430\u0441\u0441 \u043d\u0430 \u0432\u0441\u0451, \u0447\u0442\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<p>\u041f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<h4>1. \u041c\u043e\u0434\u0435\u043b\u044c\u043a\u0438<\/h4>\n<pre><code class=\"cs\">public interface ITaskParameters { }public interface ITaskDto { }public record TaskOneParameters(int Value) : ITaskParameters;public record TaskTwoParameters(string Data) : ITaskParameters;public record TaskOneDto(int Value) : ITaskDto;public record TaskTwoDto(string Data) : ITaskDto;public class QueueTask where TParam : ITaskParameters{    public QueueTask(TParam parameters)    {        Parameters = parameters;        TaskInfo = new QueueTaskInfo();    }    public TParam Parameters { get; }    public QueueTaskInfo TaskInfo { get; }}public class QueueTaskInfo{public Guid Id { get; set; }    public DateTime QueueTime { get; set; }    public QueueTaskStatus Status { get; set; }    public QueueTaskType Type { get; set; }}public enum QueueTaskStatus{    ReadyForExecution,    InProgress,    Completed,    Failed}public enum QueueTaskType{    TaskOne,    TaskTwo}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>2. \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b<\/h4>\n<pre><code class=\"cs\">\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\/\/\/ &lt;\/summary&gt;[Route(\"api\/[controller]\")][ApiController]public abstract class AbstractQueueTasksController : ControllerBase    where TParam : ITaskParameters{    protected AbstractQueueTasksController(IMediator mediator)    {        _mediator = mediator;    }    protected IMediator _mediator { get; }        \/\/\/ &lt;summary&gt;\/\/\/ \u041e\u0431\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u0437\u0430\u0434\u0430\u0447\/\/\/ &lt;\/summary&gt;    [HttpGet(\"GetTasks\")]public Task&lt;...&gt; GetAsync(CancellationToken cancellationToken = default){    return _mediator.Send(new AbstractGetQueueTasksRequest(), cancellationToken);}}\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0438\u043f\u0430 \"TaskOne\"\/\/\/ &lt;\/summary&gt;public class TaskOneController : AbstractQueueTasksController{    public TaskOneController(IMediator mediator) : base(mediator) { }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0448\u043b\u0430 \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0434\u0430\u0436\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b\/\/\/ &lt;\/summary&gt;    [HttpPost(\"Enqueue\")]    public Task EnqueueAsync(TaskOneDto dto, CancellationToken cancellationToken = default)    {        return _mediator.Send(new EnqueueTaskCommand(dto), cancellationToken);    }}\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0438\u043f\u0430 \"TaskTwo\"\/\/\/ &lt;\/summary&gt;public class TaskTwoController : AbstractQueueTasksController{    public TaskTwoController(IMediator mediator) : base(mediator) { }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0448\u043b\u0430 \u0441 \u0444\u0440\u043e\u043d\u0442\u0430\/\/\/ &lt;\/summary&gt;    [HttpPost(\"Enqueue\")]    public Task EnqueueAsync(TaskTwoDto dto, CancellationToken cancellationToken = default)    {    ... \/\/ \u0442\u0443\u0442 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u043a\u0430 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445        return _mediator.Send(new EnqueueTaskCommand(dto), cancellationToken);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>3. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/h4>\n<pre><code class=\"cs\">\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\/\/\/ &lt;\/summary&gt;public class EnqueueTaskCommand : IRequest    where TDto : ITaskDto{    public EnqueueTaskCommand(TDto dto) =&gt; TaskDto = dto;    public TDto TaskDto { get; }}\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\/\/\/ &lt;\/summary&gt;public abstract class EnqueueTaskCommandHandler : IRequestHandler&amp;gt;    where TParam : ITaskParameters    where TDto : ITaskDto{    private readonly AbstractDataflowQueue _queue;    protected EnqueueTaskCommandHandler(AbstractDataflowQueue queue)    {        _queue = queue;    }    public async Task Handle(EnqueueTaskCommand request, CancellationToken cancellationToken)    {        if (request is null)            throw new ArgumentNullException(nameof(request));        var param = Map(request.TaskDto);        await _queue.EnqueueAsync(param, cancellationToken);    }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \/\/\/ &lt;\/summary&gt;    protected abstract TParam Map(TDto dto);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>4. \u041e\u0447\u0435\u0440\u0435\u0434\u044c<\/h4>\n<pre><code class=\"cs\">public abstract class AbstractDataflowQueue     where TParam : ITaskParameters{    private readonly SemaphoreSlim _locker = new(1, 1); \/\/ \u041d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447    protected AbstractQueueTaskRepository _repository { get; }    protected AbstractBackgroundExecutingTask _executor { get; }    protected AbstractDataflowQueue(        AbstractBackgroundExecutingTask executor,        AbstractQueueTaskRepository repository)    {        _executor = executor;        _repository = repository;    }    public async Task EnqueueAsync(QueueTask item, CancellationToken cancellationToken = default)    {        if (item is null)         throw new ArgumentNullException(nameof(item));        await _locker.WaitAsync(cancellationToken);        try        {            item.TaskInfo.QueueTime = DateTime.Now;            item.TaskInfo.Status = QueueTaskStatus.ReadyForExecution;            await _repository.SaveAsync(item, cancellationToken);            await _executor.TrySendQueueTask(item.Id);        }        finally        {            _locker.Release();        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>5. \u042d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u0435\u0440<\/h4>\n<pre><code class=\"cs\">\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u0435\u0440: \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0451 \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\/\/\/ &lt;\/summary&gt;public abstract class AbstractBackgroundExecutingTask    where TParam : ITaskParameters{    protected AbstractBackgroundExecutingTask(        IManager manager,        AbstractQueueTaskRepository repository,        int defaultMaxParallelism = 1)    {        _manager = manager;        _repository = repository;        var options = new ExecutionDataflowBlockOptions        {            MaxDegreeOfParallelism = defaultMaxParallelism,            BoundedCapacity = DataflowBlockOptions.Unbounded        };        _block = new ActionBlock(HandleAsync, options);    }    protected IManager _manager { get; }    protected AbstractQueueTaskRepository _repository { get; }    protected ActionBlock _block { get; }    public bool TrySendQueueTask(Guid taskId)    {        return _block.Post(taskId);    }    private async Task HandleAsync(Guid taskId)    {        var task = await _repository.GetTask(taskId);        if (task == null) return;        task.TaskInfo.Status = QueueTaskStatus.InProgress;        await _manager.TransferTask(task);                task.TaskInfo.Status = QueueTaskStatus.Completed;        await _repository.UpdateAsync(task);    }}\/\/\/ &lt;summary&gt;\/\/\/ \u041b\u043e\u0448\u0430\u0434\u043a\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u0439\/\/\/ &lt;\/summary&gt;public class TaskOneExecutor : AbstractBackgroundExecutingTask{    public TaskOneExecutor(        IManager manager,        AbstractQueueTaskRepository repository)        : base(manager, repository, defaultMaxParallelism: 1) { }}\/\/\/ &lt;summary&gt;\/\/\/ \u041c\u0435\u0434\u0432\u0435\u0434\u0438 \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u0442\u0440\u043e\u0451\u043c\/\/\/ &lt;\/summary&gt;public class TaskTwoExecutor : AbstractBackgroundExecutingTask{    public TaskTwoExecutor(        IManager manager,        AbstractQueueTaskRepository repository)        : base(manager, repository, defaultMaxParallelism: 3) { }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>6. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/h4>\n<pre><code class=\"cs\">public abstract class AbstractQueueTaskRepository    where TParam : ITaskParameters{    \/\/ \u041f\u0440\u043e\u0441\u0442\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438    protected readonly Dictionary&lt;Guid, QueueTask&lt;TParam&gt;&gt; _storage = new();    public virtual Task SaveAsync(QueueTask task, CancellationToken cancellationToken = default)    {        _storage[task.TaskInfo.Id] = task;        return Task.CompletedTask;    }    public virtual Task UpdateAsync(QueueTask task, CancellationToken cancellationToken = default)    {        if (_storage.ContainsKey(task.TaskInfo.Id))        {            _storage[task.TaskInfo.Id] = task;        }        return Task.CompletedTask;    }    public virtual QueueTask? GetTask(Guid taskId)    {        _storage.TryGetValue(taskId, out var task);        return task;    }        ...}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>+\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0434 \u0438 \u0434\u0440\u0443\u0433\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430<\/p>\n<h4>7. \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b<\/h4>\n<pre><code class=\"cs\">public interface IManager    where TParam : ITaskParameters{    Task TransferTask(QueueTask task);}\/\/\/ &lt;summary&gt;\/\/\/ \u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 \u043a\u0430\u0444\u043a\u0430\/\/\/ &lt;\/summary&gt;public class TaskOneManager : IManager{    private readonly ITaskOneProducer _producer;    private readonly ITaskOneConsumer _consumer;    public TaskOneManager(        ITaskOneProducer producer,        ITaskOneConsumer consumer)    {        _producer = producer;        _consumer = consumer;    }    public async Task TransferTask(QueueTask queueTask)    {\/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430await _producer.PublishAsync(queueTask);\/\/ \u041e\u0436\u0438\u0434\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u044e\u043c\u0435\u0440\u0430await _consumer.GetResult(queueTask.TaskInfo.Id);    }}\/\/\/ &lt;summary&gt;\/\/\/ \u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 Refit \u043a\u043b\u0438\u0435\u043d\u0442\/\/\/ &lt;\/summary&gt;public class TaskTwoManager : IManager{    private readonly ITaskTwoClient _client;    public TaskTwoManager(ITaskTwoClient client)    {        _client = client;    }    public async Task TransferTask(QueueTask task)    {        await _client.SendTaskTwoAsync(task);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043a\u043e\u0434 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. <\/p>\n<p>\u0418 <em>\u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u043a \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d<\/em> \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u0438\u043d\u0430\u0447\u0435 \u0432\u0441\u044f \u0432\u0430\u0448\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f). \u0422\u043e\u043b\u044c\u043a\u043e \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c Transient.<\/p>\n<h4>\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430:<\/h4>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/168\/2c2\/626\/1682c2626a2584f68e812d0b567ccec9.png\" width=\"841\" height=\"741\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/168\/2c2\/626\/1682c2626a2584f68e812d0b567ccec9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/168\/2c2\/626\/1682c2626a2584f68e812d0b567ccec9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u041a\u0430\u043a \u0431\u044b \u043c\u044b \u043f\u0440\u0438\u0440\u0443\u0447\u0438\u043b\u0438 \u0440\u0430\u0437\u043d\u043e\u0448\u0451\u0440\u0441\u0442\u043d\u044b\u0445 \u0430\u0440\u0442\u0438\u0441\u0442\u043e\u0432 \u2014 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0437\u0430\u0432\u0442\u0440\u0430 \u043a \u043d\u0430\u043c \u0437\u0430\u0445\u043e\u0434\u044f\u0442:<\/p>\n<ul>\n<li>\n<p>\u0421\u043b\u043e\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e SOAP.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0438\u043d\u0433\u0432\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043d\u0446\u0435\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0432 10 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u041d\u0430\u0448\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442: \u00ab\u0414\u0430 \u043d\u0435\u00a0\u0432\u043e\u043f\u0440\u043e\u0441\u00bb. \u0412\u043e\u0442 \u043a\u0430\u043a \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c <strong>\u043d\u043e\u0432\u043e\u0433\u043e \u0437\u0432\u0435\u0440\u044f<\/strong> \u0432 \u043d\u0430\u0448 \u0446\u0438\u0440\u043a:<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0431\u0430\u0437\u0443:<\/p>\n<ul>\n<li>\n<p>\u041d\u043e\u0432\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u043e\u0434:<\/p>\n<ul>\n<li>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u044d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u043e\u0440\u0430 \u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>DI-\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432 <code>Program.cs<\/code>. (\u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u0448\u0438 \u0436\u0438\u0432\u043e\u0442\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u044b\u043c\u0438 \u043d\u0430\u0448\u0438\u043c\u0438 \u0440\u0435\u043b\u044c\u0441\u0430\u043c\u0438)<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432\u0441\u0451. \u0412\u0435\u0441\u044c \u043f\u0443\u0442\u044c \u2014 <strong>\u043f\u043e \u043d\u0430\u043a\u0430\u0442\u0430\u043d\u043d\u043e\u0439<\/strong>. \u041d\u0438\u043a\u0442\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u043c\u0438\u0448\u043a\u0430\u043c, \u043b\u043e\u0448\u0430\u0434\u044f\u043c \u0438 \u0441\u043b\u043e\u043d\u0430\u043c \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.<\/p>\n<h2>\u0421\u043b\u043e\u0432\u0430 \u0430\u0432\u0442\u043e\u0440\u0430<\/h2>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0438\u043d\u0438-\u043c\u0438\u0434\u043b\u0430. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u0430\u043c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043c\u0435\u0442\u0430\u0444\u043e\u0440\u044b) \u041c\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u043d\u0430 Meet Up \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c! \u0410 \u0442\u0430\u043c, \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0447\u0438\u043c, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0431\u044b\u043b\u0438, \u043d\u043e \u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438, \u0442\u0435\u0441\u0442\u0435\u0440\u044b \u0438 \u0434\u0430\u0436\u0435 \u043c\u0435\u0434\u0438\u0439\u0449\u0438\u043a\u0438!<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u044f, \u0442\u043e \u0437\u0430\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0439\u0442\u0435 \u043a \u043d\u0430\u043c. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043c\u044b \u0434\u0430\u0436\u0435 \u0441\u043a\u043e\u0440\u043e \u0432\u044b\u0439\u0434\u0435\u043c \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0441 \u043d\u0430\u0448\u0438\u043c \u043c\u0438\u0442\u0430\u043f\u043e\u043c)<\/p>\n<p>\u041d\u0443 \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0435\u0441\u0442\u044c \u0447\u0442\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0442\u043e \u043c\u0438\u043b\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0448\u0443 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. \u042f \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0434\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043a\u0440\u0438\u0442\u0438\u043a\u0435!<\/p>\n<\/div>\n<p>\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\/ru\/articles\/947556\/\">https:\/\/habr.com\/ru\/articles\/947556\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0441\u043d\u043e\u0432\u0430 \u043f\u0438\u0441\u0430\u0442\u0435\u043b\u044c-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Simpl Group (\u0434\u0430, \u0431\u0435\u0437 e).\u0421\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b\u0430 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c Meet Up \u2014 \u0443\u0436\u0435 6-\u043c, \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0447\u0438\u043c, \u2014 \u0438 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b\u0430 \u0441\u0432\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0432\u0435\u0434\u0430\u044e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438 \u0432\u0430\u043c. \u041d\u0435 \u043f\u0440\u043e \u0432\u0435\u0434\u044c\u043c \u0438 \u0434\u0435\u043c\u043e\u043d\u043e\u0432, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u0430\u043a \u0432 \u043c\u043e\u0435\u0439 \u043a\u043d\u0438\u0433\u0435. \u0410 \u043f\u0440\u043e \u0446\u0438\u0440\u043a \u2014 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u0440\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447\u0438, \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u0445 \u0438 \u043d\u0435 \u043f\u0430\u0434\u0430\u044e\u0442.\u0418\u043b\u0438, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043c\u044b \u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0430\u0434\u0430\u043b\u0438.(\u041a \u0441\u043b\u043e\u0432\u0443, \u043a\u043d\u0438\u0433\u0443 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c: \u00ab\u041f\u043e\u0440\u043e\u043a\u0438\u00bb, Ingini)\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u0423 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043c\u0435\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0442\u0440\u044e\u043a \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0440\u0430\u0441\u0447\u0451\u0442. \u0412\u0441\u0451, \u043a\u0430\u043a \u0432 \u0441\u0442\u0430\u0440\u043e\u043c \u0446\u0438\u0440\u043a\u0435: \u043e\u0434\u0438\u043d \u0430\u0440\u0442\u0438\u0441\u0442, \u043e\u0434\u0438\u043d \u043d\u043e\u043c\u0435\u0440.\u041d\u043e \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u0418 \u0437\u0430 \u043d\u0435\u0439 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430. \u0418 \u0432\u043e\u0442 \u0443\u0436\u0435 \u0437\u0440\u0438\u0442\u0435\u043b\u0438 \u0445\u043e\u0442\u044f\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044b\u0436\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447, \u043d\u043e \u0438 \u043c\u0435\u0434\u0432\u0435\u0434\u044f \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0435, \u0436\u043e\u043d\u0433\u043b\u0451\u0440\u043e\u0432, \u0430\u043a\u0440\u043e\u0431\u0430\u0442\u043e\u0432 \u0438 \u0434\u0430\u0436\u0435 \u043a\u0438\u0431\u0435\u0440\u0434\u0440\u0430\u043a\u043e\u043d\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u043c.\u0417\u043d\u0430\u0447\u0438\u0442, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0441\u0451 \u0448\u043e\u0443. \u0422\u0430\u043a, \u0447\u0442\u043e\u0431\u044b:\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0430\u0440\u0442\u0438\u0441\u0442\u043e\u0432 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u0438\u043b\u0438\u044f\u043c\u0438;\u041d\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043c\u0430\u043d\u0435\u0436 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437;\u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e: \u043d\u0430\u0434\u0451\u0436\u043d\u043e, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u043d\u043e.\u041a\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0446\u0438\u0440\u043a\u0435 \u2014 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u0448\u043e\u0443\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:\u041e\u0434\u043d\u0430 \u2014 \u044d\u0442\u043e \u043b\u043e\u0448\u0430\u0434\u043a\u0438, \u043f\u0440\u044b\u0433\u0430\u044e\u0449\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u0440\u0443\u0447;\u0412\u0442\u043e\u0440\u0430\u044f \u2014 \u044d\u0442\u043e \u043c\u0438\u0448\u043a\u0430 \u043d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0435, \u043f\u0440\u043e\u0435\u0437\u0436\u0430\u044e\u0449\u0438\u0439 \u0442\u043e \u0432 \u043e\u0434\u043d\u0443, \u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443.\u0427\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0449\u0435\u0433\u043e \u0432 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f\u0445?\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u2014 \u0434\u0440\u0435\u0441\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438, \u043f\u043e\u0434\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0433\u043e\u043b\u043e\u0441\u043e\u043c: \u00ab\u0412\u043f\u0435\u0440\u0451\u0434!\u00bb.\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u2014 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u043e\u0440\u044b, \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043d\u0430\u0440\u044f\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u043a\u043b\u0430\u0434\u0430 (\u0411\u0414).\u041e\u0447\u0435\u0440\u0435\u0434\u0438 \u2014 \u043c\u0430\u043d\u0435\u0436, \u0433\u0434\u0435 \u0430\u0440\u0442\u0438\u0441\u0442\u044b \u0436\u0434\u0443\u0442, \u043f\u043e\u043a\u0430 \u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u044f\u0442.\u042d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u043e\u0440 \u2014 \u0442\u0451\u043c\u043d\u044b\u0439 \u043a\u043e\u0440\u0438\u0434\u043e\u0440, \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u043e\u0442 \u043a\u0443\u043b\u0438\u0441 \u043a \u0441\u0432\u0435\u0442\u0443 \u0440\u0430\u043c\u043f\u044b.\u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u2014 \u0434\u0432\u0435\u0440\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043a\u0443\u043b\u0438\u0441\u044c\u0435\u043c \u0438 \u0441\u0446\u0435\u043d\u043e\u0439.\u0414\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0446\u0435\u043d\u0430, \u0433\u0434\u0435 \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u043e\u043c\u0435\u0440.\u041d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441:\u041b\u043e\u0448\u0430\u0434\u043a\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u0439.\u041c\u0435\u0434\u0432\u0435\u0434\u0438 \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0442\u0440\u043e\u0435.\u041a\u0442\u043e-\u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 Kafka, \u043a\u0442\u043e-\u0442\u043e \u2014 \u0447\u0435\u0440\u0435\u0437 HTTP.\u041f\u043e \u0441\u0443\u0442\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u0430\u0440\u043e\u0447\u043a\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0439, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043a\u0443\u043b\u0438\u0441\u044b \u0438 \u0434\u0440\u0435\u0441\u0441\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u0443 \u043c\u0438\u0448\u0435\u043a \u0438 \u043b\u043e\u0448\u0430\u0434\u043e\u043a \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435, \u0430 \u0434\u0432\u0435\u0440\u0438, \u0430\u043a\u0442\u0435\u0440\u044b \u0438 \u0441\u0446\u0435\u043d\u044b \u0440\u0430\u0437\u043d\u044b\u0435.\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043d\u0430\u0448 \u043c\u0430\u043d\u0435\u0436 \u2014 \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0448 \u0446\u0438\u0440\u043a \u0438\u0437\u043d\u0443\u0442\u0440\u0438. \u0427\u0442\u043e \u0442\u0430\u043c \u0432 \u043a\u0443\u043b\u0438\u0441\u0430\u0445, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043f\u043e\u0442\u044b\u043a\u0430\u0435\u0442\u0441\u044f?\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430:\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u044b\u0439 \u0446\u0438\u0440\u043a, \u043a\u0443\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0432\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0430\u0440\u0442\u0438\u0441\u0442\u0430: \u0445\u043e\u0442\u044c \u043c\u0435\u0434\u0432\u0435\u0434\u044f, \u0445\u043e\u0442\u044c \u0436\u043e\u043d\u0433\u043b\u0451\u0440\u0430, \u043d\u0443 \u0438 \u0434\u0430, \u043a\u0438\u0431\u0435\u0440\u0434\u0440\u0430\u043a\u043e\u043d\u0430 \u0442\u043e\u0436\u0435.\u0412 \u0431\u0430\u0437\u0435\u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u043b\u043e\u044f \u043a\u043e\u0441\u0442\u044e\u043c\u0430:\u041e\u0431\u0449\u0438\u0439: ID, \u0442\u0438\u043f, \u0441\u0442\u0430\u0442\u0443\u0441, \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u043e\u0448\u0438\u0431\u043a\u0438.\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0439: \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0430\u0440\u0442\u0438\u0441\u0442\u0430.\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:task                       &#8212; \u043e\u0431\u0449\u0438\u0439 \u0441\u043a\u043b\u0430\u0434 \u0437\u0430\u0434\u0430\u0447 task_{taskType}_parameters &#8212; \u0433\u0430\u0440\u0434\u0435\u0440\u043e\u0431 \u0434\u043b\u044f \u043a\u043e\u0441\u0442\u044e\u043c\u043e\u0432\u0412 \u043a\u043e\u0434\u0435\u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043d\u0430\u0448\u0435 \u043e\u0440\u0443\u0436\u0438\u0435 \u2014 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a \u043a\u043b\u0430\u0441\u0441 \u043d\u0430 \u0432\u0441\u0451, \u0447\u0442\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0437\u0430\u0434\u0430\u0447.\u041f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434.1. \u041c\u043e\u0434\u0435\u043b\u044c\u043a\u0438public interface ITaskParameters { }public interface ITaskDto { }public record TaskOneParameters(int Value) : ITaskParameters;public record TaskTwoParameters(string Data) : ITaskParameters;public record TaskOneDto(int Value) : ITaskDto;public record TaskTwoDto(string Data) : ITaskDto;public class QueueTask where TParam : ITaskParameters{    public QueueTask(TParam parameters)    {        Parameters = parameters;        TaskInfo = new QueueTaskInfo();    }    public TParam Parameters { get; }    public QueueTaskInfo TaskInfo { get; }}public class QueueTaskInfo{public Guid Id { get; set; }    public DateTime QueueTime { get; set; }    public QueueTaskStatus Status { get; set; }    public QueueTaskType Type { get; set; }}public enum QueueTaskStatus{    ReadyForExecution,    InProgress,    Completed,    Failed}public enum QueueTaskType{    TaskOne,    TaskTwo}2. \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\/\/\/ &lt;\/summary&gt;[Route(&#171;api\/[controller]&#187;)][ApiController]public abstract class AbstractQueueTasksController : ControllerBase    where TParam : ITaskParameters{    protected AbstractQueueTasksController(IMediator mediator)    {        _mediator = mediator;    }    protected IMediator _mediator { get; }        \/\/\/ &lt;summary&gt;\/\/\/ \u041e\u0431\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u0437\u0430\u0434\u0430\u0447\/\/\/ &lt;\/summary&gt;    [HttpGet(&#171;GetTasks&#187;)]public Task&lt;&#8230;&gt; GetAsync(CancellationToken cancellationToken = default){    return _mediator.Send(new AbstractGetQueueTasksRequest(), cancellationToken);}}\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0438\u043f\u0430 &#171;TaskOne&#187;\/\/\/ &lt;\/summary&gt;public class TaskOneController : AbstractQueueTasksController{    public TaskOneController(IMediator mediator) : base(mediator) { }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0448\u043b\u0430 \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0434\u0430\u0436\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b\/\/\/ &lt;\/summary&gt;    [HttpPost(&#171;Enqueue&#187;)]    public Task EnqueueAsync(TaskOneDto dto, CancellationToken cancellationToken = default)    {        return _mediator.Send(new EnqueueTaskCommand(dto), cancellationToken);    }}\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0438\u043f\u0430 &#171;TaskTwo&#187;\/\/\/ &lt;\/summary&gt;public class TaskTwoController : AbstractQueueTasksController{    public TaskTwoController(IMediator mediator) : base(mediator) { }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0448\u043b\u0430 \u0441 \u0444\u0440\u043e\u043d\u0442\u0430\/\/\/ &lt;\/summary&gt;    [HttpPost(&#171;Enqueue&#187;)]    public Task EnqueueAsync(TaskTwoDto dto, CancellationToken cancellationToken = default)    {    &#8230; \/\/ \u0442\u0443\u0442 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u043a\u0430 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445        return _mediator.Send(new EnqueueTaskCommand(dto), cancellationToken);    }}3. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\/\/\/ &lt;summary&gt;\/\/\/ \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\/\/\/ &lt;\/summary&gt;public class EnqueueTaskCommand : IRequest    where TDto : ITaskDto{    public EnqueueTaskCommand(TDto dto) =&gt; TaskDto = dto;    public TDto TaskDto { get; }}\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\/\/\/ &lt;\/summary&gt;public abstract class EnqueueTaskCommandHandler : IRequestHandler&amp;gt;    where TParam : ITaskParameters    where TDto : ITaskDto{    private readonly AbstractDataflowQueue _queue;    protected EnqueueTaskCommandHandler(AbstractDataflowQueue queue)    {        _queue = queue;    }    public async Task Handle(EnqueueTaskCommand request, CancellationToken cancellationToken)    {        if (request is null)            throw new ArgumentNullException(nameof(request));        var param = Map(request.TaskDto);        await _queue.EnqueueAsync(param, cancellationToken);    }\/\/\/ &lt;summary&gt;\/\/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \/\/\/ &lt;\/summary&gt;    protected abstract TParam Map(TDto dto);}4. \u041e\u0447\u0435\u0440\u0435\u0434\u044cpublic abstract class AbstractDataflowQueue     where TParam : ITaskParameters{    private readonly SemaphoreSlim _locker = new(1, 1); \/\/ \u041d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447    protected AbstractQueueTaskRepository _repository { get; }    protected AbstractBackgroundExecutingTask _executor { get; }    protected AbstractDataflowQueue(        AbstractBackgroundExecutingTask executor,        AbstractQueueTaskRepository repository)    {        _executor = executor;        _repository = repository;    }    public async Task EnqueueAsync(QueueTask item, CancellationToken cancellationToken = default)    {        if (item is null)         throw new ArgumentNullException(nameof(item));        await _locker.WaitAsync(cancellationToken);        try        {            item.TaskInfo.QueueTime = DateTime.Now;            item.TaskInfo.Status = QueueTaskStatus.ReadyForExecution;            await _repository.SaveAsync(item, cancellationToken);            await _executor.TrySendQueueTask(item.Id);        }        finally        {            _locker.Release();        }    }}5. \u042d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u0435\u0440\/\/\/ &lt;summary&gt;\/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u0435\u0440: \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0451 \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\/\/\/ &lt;\/summary&gt;public abstract class AbstractBackgroundExecutingTask    where TParam : ITaskParameters{    protected AbstractBackgroundExecutingTask(        IManager manager,        AbstractQueueTaskRepository repository,        int defaultMaxParallelism = 1)    {        _manager = manager;        _repository = repository;        var options = new ExecutionDataflowBlockOptions        {            MaxDegreeOfParallelism = defaultMaxParallelism,            BoundedCapacity = DataflowBlockOptions.Unbounded        };        _block = new ActionBlock(HandleAsync, options);    }    protected IManager _manager { get; }    protected AbstractQueueTaskRepository _repository { get; }    protected ActionBlock _block { get; }    public bool TrySendQueueTask(Guid taskId)    {        return _block.Post(taskId);    }    private async Task HandleAsync(Guid taskId)    {        var task = await _repository.GetTask(taskId);        if (task == null) return;        task.TaskInfo.Status = QueueTaskStatus.InProgress;        await _manager.TransferTask(task);                task.TaskInfo.Status = QueueTaskStatus.Completed;        await _repository.UpdateAsync(task);    }}\/\/\/ &lt;summary&gt;\/\/\/ \u041b\u043e\u0448\u0430\u0434\u043a\u0438 \u043f\u0440\u044b\u0433\u0430\u044e\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u0439\/\/\/ &lt;\/summary&gt;public class TaskOneExecutor : AbstractBackgroundExecutingTask{    public TaskOneExecutor(        IManager manager,        AbstractQueueTaskRepository repository)        : base(manager, repository, defaultMaxParallelism: 1) { }}\/\/\/ &lt;summary&gt;\/\/\/ \u041c\u0435\u0434\u0432\u0435\u0434\u0438 \u043a\u0430\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u0442\u0440\u043e\u0451\u043c\/\/\/ &lt;\/summary&gt;public class TaskTwoExecutor : AbstractBackgroundExecutingTask{    public TaskTwoExecutor(        IManager manager,        AbstractQueueTaskRepository repository)        : base(manager, repository, defaultMaxParallelism: 3) { }}6. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439public abstract class AbstractQueueTaskRepository    where TParam : ITaskParameters{    \/\/ \u041f\u0440\u043e\u0441\u0442\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438    protected readonly Dictionary&lt;Guid, QueueTask&lt;TParam&gt;&gt; _storage = new();    public virtual Task SaveAsync(QueueTask task, CancellationToken cancellationToken = default)    {        _storage[task.TaskInfo.Id] = task;        return Task.CompletedTask;    }    public virtual Task UpdateAsync(QueueTask task, CancellationToken cancellationToken = default)    {        if (_storage.ContainsKey(task.TaskInfo.Id))        {            _storage[task.TaskInfo.Id] = task;        }&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-475319","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/475319","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=475319"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/475319\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=475319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=475319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=475319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}