{"id":486791,"date":"2026-07-09T16:26:37","date_gmt":"2026-07-09T16:26:37","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=486791"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=486791","title":{"rendered":"redb 3.3.0: \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u044d\u043d\u0442\u0435\u0440\u043f\u0440\u0430\u0439\u0437 \u043d\u0430 .NET \u2014 \u0441\u0432\u043e\u044f \u0411\u0414, \u0441\u0432\u043e\u0439 Apache Camel \u0438 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0441 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u043e\u043c (\u0438 \u0432\u0441\u0451 \u044d\u0442\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e)"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e17\/c5c\/b4b\/e17c5cb4bc9765f73b2f01dd07766577.webp\" alt=\"redb ecosystem\" title=\"redb ecosystem\" width=\"832\" height=\"1248\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e17\/c5c\/b4b\/e17c5cb4bc9765f73b2f01dd07766577.webp 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e17\/c5c\/b4b\/e17c5cb4bc9765f73b2f01dd07766577.webp 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>redb ecosystem<\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0421\u0435\u0440\u0438\u044f:<\/strong>\u00a0redb ecosystem (\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043d\u044b\u0439 \u0430\u043d\u043e\u043d\u0441 3.3.0)  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u00ab\u044d\u043d\u0442\u0435\u0440\u043f\u0440\u0430\u0439\u0437-\u0441\u0442\u0435\u043a \u043d\u0430 .NET\u00bb, \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u043c\u0435\u044e\u0442 \u0432 \u0432\u0438\u0434\u0443 \u0437\u043e\u043e\u043f\u0430\u0440\u043a: \u0431\u0430\u0437\u0430 \u043e\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u0435\u043d\u0434\u043e\u0440\u0430, \u0448\u0438\u043d\u0430 \u043e\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e, ORM \u0441 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440, \u0435\u0449\u0451 \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043b\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u2014 \u0438 \u043a\u043b\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0435\u0448\u044c \u0441\u0430\u043c \u0438 \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0436\u0435 \u0447\u0438\u043d\u0438\u0448\u044c \u043f\u043e \u043d\u043e\u0447\u0430\u043c.<\/p>\n<p>\u041c\u044b \u043f\u043e\u0448\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0443\u0442\u0451\u043c \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u043b\u0433\u043e\u0434\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u044d\u0442\u043e \u043a\u0430\u043a\u00a0<strong>\u043e\u0434\u043d\u0443 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/strong>: \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u00a0<strong>redb<\/strong>\u00a0\u043f\u043e\u0432\u0435\u0440\u0445 Postgres\/MSSQL\/SQLite, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a\u00a0<strong>redb.Route<\/strong>\u00a0(\u043d\u0430\u0448 \u043e\u0442\u0432\u0435\u0442 Apache Camel \u043f\u043e\u0434 .NET) \u0438 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u00a0<strong>redb.Tsak<\/strong>\u00a0\u0441 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u043e\u043c, hot-reload \u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u043c. \u0422\u0440\u0438 \u0441\u043b\u043e\u044f, \u043e\u0434\u0438\u043d \u043a\u043e\u0434, \u043e\u0434\u0438\u043d \u0441\u0442\u0438\u043b\u044c.<\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u044b\u0448\u043b\u0430 \u0432\u0435\u0440\u0441\u0438\u044f\u00a0<strong>3.3.0<\/strong>\u00a0\u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0431\u0430\u043c\u043f \u0432\u0441\u0435\u0439 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u043d\u0435 \u00ab\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043f\u0430\u0440\u0443 \u0444\u0438\u0447\u00bb: \u044d\u0442\u043e \u0440\u0435\u043b\u0438\u0437, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b\u00a0<strong>\u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438 \u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439<\/strong>\u00a0(\u0438 \u044d\u0442\u043e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0433\u043b\u0430\u0432\u043d\u043e\u0435), \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430, \u0434\u043e\u0432\u0435\u043b\u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 RAG-\u043f\u0435\u0442\u043b\u044e \u0434\u043b\u044f LLM \u0438 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435. \u041d\u0438\u0436\u0435 \u2014 \u043f\u043e \u0434\u0435\u043b\u0443, \u0441 \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p><strong>\u0418 \u0441\u0440\u0430\u0437\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0435: \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 3.3.0 \u0432\u0441\u0435 Pro-\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0439, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439, \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u0448\u044c \u043f\u0430\u043a\u0435\u0442 \u0438 \u044e\u0437\u0430\u0435\u0448\u044c.<\/strong>\u00a0Change tracking, bulk, \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u043a\u044d\u0448, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430, \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Tsak \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u0438 failover \u2014 \u0432\u0441\u0451 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0432 \u043f\u0440\u043e\u0434\u0435 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.\u00a0<code>dotnet add package <\/code><a href=\"http:\/\/redb.Postgres.Pro\" rel=\"noopener noreferrer nofollow\"><code>redb.Postgres.Pro<\/code><\/a>\u00a0\u2014 \u0438 \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0435\u0439\u0432\u043e\u043b\u043b\u0430, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0438\u0447\u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e.<\/p>\n<blockquote>\n<p><strong>\u0426\u0438\u043a\u043b \u043f\u0440\u043e redb \u0438 redb.Route.<\/strong>\u00a0\u042d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0438\u0438, \u0441\u0432\u0435\u0436\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u0441\u0432\u0435\u0440\u0445\u0443:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1054148\/\" rel=\"noopener noreferrer nofollow\">redb.Route \u2014 \u0443\u0445\u043e\u0434\u0438\u043c \u043e\u0442 MassTransit, \u0438\u0434\u0451\u043c \u043a Apache Camel: Kafka, Scatter\u2011Gather \u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1049222\/\" rel=\"noopener noreferrer nofollow\">Apache Camel \u043f\u043e\u0434 .NET: HTTP-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0431\u0435\u0437 <\/a><a href=\"http:\/\/ASP.NET\" rel=\"noopener noreferrer nofollow\">ASP.NET<\/a><a href=\"https:\/\/habr.com\/ru\/articles\/1049222\/\" rel=\"noopener noreferrer nofollow\"> MVC + Content-Based Router<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1042392\/\" rel=\"noopener noreferrer nofollow\">redb.Route \u2014 Apache Camel \u0434\u043b\u044f .NET, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043d\u0435 \u0431\u044b\u043b\u043e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1042058\/\" rel=\"noopener noreferrer nofollow\">redb \u2014 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f .NET \u043f\u043e\u0432\u0435\u0440\u0445 Postgres\/MSSQL: \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439, \u0431\u0435\u0437 Include, \u0441 \u043f\u043e\u043b\u043d\u044b\u043c LINQ<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u2014 \u0432\u00a0<a href=\"https:\/\/habr.com\/ru\/users\/grelikt\/articles\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0444\u0438\u043b\u0435<\/a>. \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438:\u00a0<a href=\"https:\/\/github.com\/redbase-app\/\" rel=\"noopener noreferrer nofollow\">github.com\/redbase-app<\/a>. \u041f\u0440\u043e \u0441\u0430\u043c\u0443 \u0411\u0414:\u00a0<a href=\"http:\/\/redb.ru\" rel=\"noopener noreferrer nofollow\">redb.ru<\/a>.<\/p>\n<\/blockquote>\n<hr\/>\n<h3>\u041a\u043e\u0440\u043e\u0442\u043a\u043e, \u0447\u0442\u043e \u0437\u0430 \u0442\u0440\u0438 \u0441\u043b\u043e\u044f<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0442\u043e:<\/p>\n<ul>\n<li>\n<p><strong>redb<\/strong>\u00a0\u2014 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f .NET. \u041f\u0438\u0448\u0435\u0448\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 POCO-\u043a\u043b\u0430\u0441\u0441, \u0432\u0435\u0448\u0430\u0435\u0448\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u2014 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u0441 \u043d\u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u043d\u044b\u0439 LINQ, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437\u00a0<code>Include<\/code>. \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b: Postgres, MSSQL, SQLite. \u0415\u0441\u0442\u044c Free \u0438 Pro (change tracking, bulk, \u043a\u044d\u0448, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430).<\/p>\n<\/li>\n<li>\n<p><strong>redb.Route<\/strong>\u00a0\u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0432 \u0434\u0443\u0445\u0435 Apache Camel: DSL \u0438\u0437 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 (<code>From(...).\u2026\u200b.To(...)<\/code>), 30+ \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (Kafka, RabbitMQ, HTTP, gRPC, S3, LLM \u0438 \u0442.\u0434.), \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 (EIP), \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f. \u0422\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u00ab\u043a\u043b\u0435\u0439\u00bb, \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435, \u0430 \u0441 \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>redb.Tsak<\/strong>\u00a0\u2014 \u0440\u0430\u043d\u0442\u0430\u0439\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0435\u0440\u0451\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b redb.Route \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043f\u0440\u043e\u0434-\u0441\u0435\u0440\u0432\u0438\u0441: \u0434\u0430\u0448\u0431\u043e\u0440\u0434, hot-reload \u043c\u043e\u0434\u0443\u043b\u0435\u0439 (<code>.tpkg<\/code>), \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438, \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u0438 failover. \u041f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f NuGet-\u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438, Docker-\u043e\u0431\u0440\u0430\u0437\u0430\u043c\u0438 \u0438 standalone-\u0430\u0440\u0445\u0438\u0432\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u2014 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u0432\u0435\u0441\u044c \u0442\u0435\u043a\u0441\u0442 \u2014 \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438. \u0412\u0441\u0451 \u043b\u0435\u0436\u0438\u0442 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0438\u0436\u043d\u0438\u0439 \u0441\u043b\u043e\u0439 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u043b\u043e\u0432\u0430\u0445 \u2014 \u0432\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 redb \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 LINQ \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437\u00a0<code>Include<\/code>:<\/p>\n<pre><code>[RedbScheme]public class Note{    public string Tag  { get; set; } = \"\";    public string Text { get; set; } = \"\";}\/\/ \u0437\u0430\u043f\u0438\u0441\u044cawait redb.SaveAsync(new RedbObject&lt;Note&gt; { Props = new() { Tag = \"work\", Text = \"hello\" } });\/\/ \u0447\u0442\u0435\u043d\u0438\u0435 \u2014 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043a\u043e\u0434\u0430, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e Include\/JOIN \u0440\u0443\u043a\u0430\u043c\u0438var notes = await redb.Query&lt;Note&gt;()    .Where(n =&gt; n.Tag == \"work\")    .ToListAsync();<\/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<p>\u0421\u0445\u0435\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u00a0<code>SyncSchemeAsync&lt;Note&gt;()<\/code>\u00a0\u2014 \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0431\u0435\u0437 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0441\u043b\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442 \u0438 \u0447\u0430\u043d\u043a\u0438 \u0431\u0430\u0437\u044b \u0437\u043d\u0430\u043d\u0438\u0439 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435, \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u0430\u0448\u0435\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 \u2014 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.<\/p>\n<hr\/>\n<h2>redb.Route: \u0447\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0443 \u0441 \u0434\u0432\u0438\u0436\u043a\u0430 \u2014 \u0437\u0434\u0435\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044f\u0441\u0430.<\/p>\n<h3>\u0414\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430: Amazon SQS\/SNS \u0438 Telegram<\/h3>\n<h4>redb.Route.Sqs\u00a0\u2014 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u0442\u043e\u043f\u0438\u043a AWS \u0432 \u043e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442<\/h4>\n<p>\u041e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442, \u0434\u0432\u0435 \u0441\u0445\u0435\u043c\u044b:\u00a0<code>sqs:\/\/<\/code>\u00a0(\u043e\u0447\u0435\u0440\u0435\u0434\u044c: \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 + \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440) \u0438\u00a0<code>sns:\/\/<\/code>\u00a0(\u0442\u043e\u043f\u0438\u043a: publisher + fan-out SNS\u2192SQS). \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u2014 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 AWS SDK for .NET v4, \u043d\u0435 \u0441\u0430\u043c\u043e\u043f\u0430\u043b.<\/p>\n<pre><code>using redb.Route.Sqs.Fluent;\/\/ \u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440: 5 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, long-poll, at-least-once (delete on success \u2014 ack \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439)From(Sqs.Queue(\"orders\").WaitTimeSeconds(20).ConcurrentConsumers(5))    .Process(ex =&gt; Handle(ex.In.Body));\/\/ \u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 SNS-\u0442\u043e\u043f\u0438\u043a (fan-out \u0432 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438)From(\"timer:\/\/tick?period=5000\")    .SetBody(_ =&gt; BuildEvent())    .To(Sns.Topic(\"order-events\"));<\/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>\u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u0443\u043c\u0435\u0435\u0442 long-polling,\u00a0<code>ConcurrentConsumers(N)<\/code>\u00a0(\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0446\u0438\u043a\u043b\u044b), visibility timeout \u0441 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0434\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0439 ack \u0447\u0435\u0440\u0435\u0437\u00a0<code>.Transacted()<\/code>\u00a0\u0438 FIFO. \u041f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u2014 \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u0430\u044f \u0438 \u0431\u0430\u0442\u0447-\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430, FIFO group\/dedup id. SNS-publisher \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 subject, message structure, FIFO \u0438 \u0430\u0432\u0442\u043e-\u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 SNS\u2192SQS. \u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e \u0441 LocalStack \/ ElasticMQ \u0447\u0435\u0440\u0435\u0437\u00a0<code>serviceUrl=<\/code>, \u043f\u043e\u043b\u043d\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 AWS-\u043a\u0440\u0435\u0434\u0435\u043d\u0448\u0435\u043b\u043e\u0432, W3C trace-context \u043f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0445\u043e\u0434. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u2014 \u0432\u00a0<code>redb.Route.Sqs\/<\/code><a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\"><code>README.md<\/code><\/a>.<\/p>\n<h4>redb.Route.Telegram\u00a0\u2014 \u0431\u043e\u0442 \u043a\u0430\u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442<\/h4>\n<p>\u0421\u0445\u0435\u043c\u0430\u00a0<code>telegram:\/\/<\/code>, \u043f\u043e\u0432\u0435\u0440\u0445\u00a0<a href=\"http:\/\/Telegram.Bot\" rel=\"noopener noreferrer nofollow\"><code>Telegram.Bot<\/code><\/a>. \u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u2014 long-polling (<code>receive<\/code>, \u043e\u0434\u0438\u043d\u00a0<code>getUpdates<\/code>-\u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u0442\u043e\u043a\u0435\u043d), \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u2014 \u0440\u0435\u0436\u0438\u043c\u044b\u00a0<code>send<\/code>\u00a0\/\u00a0<code>document<\/code>\u00a0\/\u00a0<code>photo<\/code>\u00a0\/\u00a0<code>edit<\/code>\u00a0\/\u00a0<code>delete<\/code>\u00a0\/\u00a0<code>answer<\/code>.<\/p>\n<pre><code>\/\/ \u042d\u0445\u043e-\u0431\u043e\u0442: \u043f\u0440\u0438\u043d\u044f\u043b \u0430\u043f\u0434\u0435\u0439\u0442, \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u0432 \u0442\u043e\u0442 \u0436\u0435 \u0447\u0430\u0442From(Tg.Receive(token))    .Process(ex =&gt; ex.Out.Body = $\"\u0412\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438: {ex.In.Body}\")    .To(Tg.Send(token).ChatId(Header(TelegramHeaders.ChatId)));<\/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>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 429\u00a0<code>retry_after<\/code>\u00a0(\u0436\u0434\u0451\u0442 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442, \u0430 \u043d\u0435 \u0440\u043e\u043d\u044f\u0435\u0442), \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f\u00a0<code>parseMode<\/code>\u00a0(\u043a\u0438\u0434\u0430\u0435\u0442 \u043d\u0430 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0435, \u0430 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u044b\u0440\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043c\u043e\u043b\u0447\u0430), inline\/reply-\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b (<code>WithInlineKeyboard<\/code>\u00a0\/\u00a0<code>WithReplyKeyboard<\/code>), pipeline \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u0432\u0435\u0431\u0445\u0443\u043a\u0430 (<code>UnpackTelegramUpdate<\/code>) \u0438 fluent-DSL (<code>Tg.Receive\/Send\/Document\/...<\/code>). \u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u2014\u00a0<strong>at-most-once<\/strong>\u00a0(Telegram \u0434\u0432\u0438\u0433\u0430\u0435\u0442 offset \u043f\u0440\u0438 \u0432\u044b\u0434\u0430\u0447\u0435 \u0430\u043f\u0434\u0435\u0439\u0442\u0430, \u044d\u0442\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e), \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u2014 \u0447\u0435\u0440\u0435\u0437\u00a0<code>.Threads(N)<\/code>\u00a0(\u0441\u043c. \u043d\u0438\u0436\u0435), \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0438 \u0441\u043f\u0430\u043d\u044b \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430.<\/p>\n<p>\u0414\u0432\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445, \u0436\u0438\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430 \u2014 SQS \u0434\u043b\u044f AWS-\u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 Telegram \u0434\u043b\u044f ChatOps\/\u0431\u043e\u0442\u043e\u0432. \u041e\u0431\u0430 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u0440\u043e\u0442\u0438\u0432 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u0432 (LocalStack \u0438 \u043c\u043e\u043a-\u0441\u0435\u0440\u0432\u0435\u0440).<\/p>\n<h3>RAG \u043f\u043e\u0434 \u043a\u043b\u044e\u0447:\u00a0knowledge:\/\/,\u00a0embed:\/\/\u00a0\u0438\u00a0.Knowledge()<\/h3>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u0443\u00a0<code>redb.Route.Llm<\/code>\u00a0\u0443\u0436\u0435 \u0431\u044b\u043b \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 OpenAI-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Anthropic. \u0412 3.3.0 \u043c\u044b\u00a0<strong>\u0437\u0430\u043c\u043a\u043d\u0443\u043b\u0438 RAG-\u043f\u0435\u0442\u043b\u044e<\/strong>\u00a0\u2014 \u043e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043e \u043e\u0442\u0432\u0435\u0442\u0430, \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043d\u0438\u0445, \u0432\u0441\u0451 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432.<\/p>\n<p>\u0427\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c:<\/p>\n<ul>\n<li>\n<p><code><strong>knowledge:\/\/<\/strong><\/code><strong>\u00a0(ingest-\u0441\u0445\u0435\u043c\u0430)<\/strong>\u00a0\u2014 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0435\u0440\u0451\u0442 \u0442\u0435\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u0440\u0435\u0436\u0435\u0442 \u043d\u0430 \u0447\u0430\u043d\u043a\u0438 (\u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u043a\u043d\u0430 \u043f\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c \u0441 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u0435\u043c), \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438\u00a0<code>IEmbeddingProvider<\/code>\u00a0\u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0438 \u0430\u043f\u0441\u0435\u0440\u0442\u0438\u0442 \u0432\u00a0<code>IKnowledgeStore<\/code>. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c:<\/p>\n<pre><code>From(\"file:\/\/docs?include=*.md\").To(\"knowledge:\/\/handbook\");<\/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>Id \u0447\u0430\u043d\u043a\u043e\u0432 \u2014\u00a0<code>{docId}#{index}<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0433\u043e \u0436\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0438 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435.<\/p>\n<\/li>\n<li>\n<p><code><strong>embed:\/\/<\/strong><\/code><strong>\u00a0(\u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u043a\u0430\u043a \u0448\u0430\u0433)<\/strong>\u00a0\u2014 \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u043e\u00a0<code>llm:\/\/<\/code>:\u00a0<code>To(\"embed:\/\/openai\")<\/code>\u00a0\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 (\u0438\u043b\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f) \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u0430\u00a0<code>Out.Body<\/code>. \u0425\u043e\u0441\u0442 URI \u2014 \u0438\u043c\u044f \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u043f\u043e \u0438\u043c\u0435\u043d\u0438.<\/p>\n<\/li>\n<li>\n<p><code><strong>.Knowledge(collection, k)<\/strong><\/code><strong>\u00a0(retrieval-DSL)<\/strong>\u00a0\u2014 \u0448\u0430\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0442\u043e\u043f-K \u0447\u0430\u043d\u043a\u043e\u0432 \u043f\u043e\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u00a0<strong>\u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u043f\u0442<\/strong>, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439\u00a0<code>.To(\"llm:\/\/\u2026\")<\/code>\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u043b, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043d\u0438\u0445:<\/p>\n<pre><code>From(\"kafka:\/\/questions\")    .Knowledge(\"handbook\", k: 5)    .To(\"llm:\/\/claude\");<\/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>\u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c\u00a0<code>IEmbeddingProvider<\/code>\u00a0(\u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u2192 \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u00a0<code>SearchAsync<\/code>), \u0438\u043d\u0430\u0447\u0435 \u2014 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u043e\u0438\u0441\u043a (<code>SearchTextAsync<\/code>, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439\u00a0<code>LIKE<\/code>\u00a0\u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043e\u043d\u043a\u0435). \u0415\u0441\u043b\u0438 \u0441\u0442\u043e\u0440 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d \u0438\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c \u2014 \u0448\u0430\u0433 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438 \u043d\u0435 \u043b\u043e\u043c\u0430\u0435\u0442 pipeline.<\/p>\n<\/li>\n<li>\n<p><code><strong>knowledge_search<\/strong><\/code><strong>\u00a0(\u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442)<\/strong>\u00a0\u2014\u00a0<code>.AsLlmTool<\/code>-\u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0430\u0434 \u043f\u043e\u0438\u0441\u043a\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0430\u0433\u0435\u043d\u0442 \u0441\u0430\u043c \u0445\u043e\u0434\u0438\u043b \u0432 \u0431\u0430\u0437\u0443 \u0437\u043d\u0430\u043d\u0438\u0439: \u0432\u0445\u043e\u0434\u00a0<code>{query, top_k?, collection?}<\/code>\u00a0\u2192\u00a0<code>{results:[\u2026]}<\/code>.\u00a0<code>collection<\/code>\u00a0\u043c\u043e\u0436\u043d\u043e\u00a0<strong>\u0437\u0430\u043f\u0438\u043d\u0438\u0442\u044c<\/strong>, \u0442\u043e\u0433\u0434\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u2014 \u0442\u0430\u043a \u0430\u0433\u0435\u043d\u0442 \u0437\u0430\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0442\u0435\u043d\u0430\u043d\u0442\u0435 \/ \u043d\u0430\u0431\u043e\u0440\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u043f\u0435\u0442\u043b\u044f:\u00a0<code>knowledge:\/\/<\/code>\u00a0ingest \u2192 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u2192 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439\/\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u0438\u0441\u043a \u2192 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00a0<code>knowledge_search<\/code>\u00a0\u0438\u043b\u0438 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f\u00a0<code>.Knowledge()<\/code>. \u0411\u0435\u0437 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0441\u0442\u043e\u0440\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d: \u0447\u0430\u043d\u043a\u0438 \u043b\u0435\u0436\u0430\u0442 \u0432 redb, \u043f\u043e\u0438\u0441\u043a \u0438\u0434\u0451\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c.<\/p>\n<p>\u0417\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u0443\u044e \u0432\u0435\u0449\u044c: \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e JSON-\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 LLM-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u044d\u043d\u043a\u043e\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0435-ASCII \u0441\u0438\u043c\u0432\u043e\u043b \u0432\u00a0<code>\\uXXXX<\/code>. \u041d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u044d\u0442\u043e \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u043b\u043e \u0447\u0438\u0441\u043b\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u044b\/CJK \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 6 \u0440\u0430\u0437 (\u0438 \u043c\u043e\u0433\u043b\u043e \u0432\u0441\u043f\u043b\u044b\u0442\u044c \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u043c\u0438\u00a0<code>\\u\u2026<\/code>\u00a0\u0432 \u0442\u0435\u043a\u0441\u0442\u0435), \u0430 \u0432 \u0431\u0430\u0437\u0435 \u0437\u043d\u0430\u043d\u0438\u0439 \u0445\u043e\u0440\u043e\u043d\u0438\u043b\u043e \u0442\u0435\u043a\u0441\u0442 \u0447\u0430\u043d\u043a\u0430 \u0442\u0430\u043a, \u0447\u0442\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439\u00a0<code>LIKE<\/code>\u00a0\u043d\u0435 \u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438 \u0441\u044b\u0440\u043e\u0439 \u043d\u0435-ASCII \u0437\u0430\u043f\u0440\u043e\u0441. \u041f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u043d\u0430\u00a0<code>UnsafeRelaxedJsonEscaping<\/code>\u00a0\u0432\u0435\u0437\u0434\u0435, \u0433\u0434\u0435 \u043d\u0430\u0434\u043e (<code>AgentEngine<\/code>,\u00a0<code>OpenAiProvider<\/code>,\u00a0<code>McpProtocol<\/code>, \u043a\u043e\u043d\u0432\u0435\u0440\u0442 \u0447\u0430\u043d\u043a\u0430). \u0414\u043b\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u044d\u0442\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u043e \u0438 \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c, \u0438 \u043f\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0443.<\/p>\n<h3>.Threads(N)\u00a0\u2014 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435<\/h3>\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0441\u044f Camel-style \u0448\u0430\u0433 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438-\u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438:\u00a0<code>From(...).Threads(N)\u2026EndThreads()<\/code>\u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0447\u0438\u0441\u043b\u043e\u043c N. \u0421\u043c\u044b\u0441\u043b: \u0434\u0430\u0436\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a (poll-\u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440, MQTT, \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 HTTP-\u043f\u043e\u0442\u043e\u043a) \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043e N \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u2014 \u0431\u0435\u0437 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0<code>seda:\/\/<\/code>.<\/p>\n<pre><code>From(\"mqtt:\/\/sensors\")          \/\/ \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u043e \u043f\u0440\u0438\u0440\u043e\u0434\u0435 \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u0439    .Threads(8)                 \/\/ \u0434\u043e 8 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e        .Process(ex =&gt; HeavyWork(ex))    .EndThreads();<\/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>\u0412\u0430\u0436\u043d\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u2014 \u0448\u0430\u0433\u00a0<strong>\u0430\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 \u043e\u0431\u043c\u0435\u043d\u0430<\/strong>. \u0414\u043b\u044f InOnly (fire-and-forget) \u044d\u0442\u043e hand-off: \u043a\u043b\u043e\u043d + \u043f\u0443\u043b \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u0433\u0440\u0430\u043d\u0438\u0446\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 (\u043a\u0430\u043a\u00a0<code>.To(\"seda:\/\/\")<\/code>). \u0414\u043b\u044f InOut \u0442\u0435\u043b\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f\u00a0<strong>inline \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 exchange \u043f\u043e\u0434\u00a0<\/strong><code><strong>SemaphoreSlim<\/strong><\/code><strong>-\u0433\u0435\u0439\u0442\u043e\u043c<\/strong>, \u0442\u0430\u043a \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442 (\u043d\u0430\u00a0<code>Out<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>In<\/code>) \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u044c, request\/reply (RPC) \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0433, \u0438 \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0442\u0435\u043a\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u044c. \u0415\u0441\u0442\u044c\u00a0<code>.MaxQueueSize(n)<\/code>\u00a0\u0438\u00a0<code>.EnqueueTimeout(TimeSpan)<\/code>. \u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u0438 N &gt; 1 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u2014 \u044d\u0442\u043e \u0446\u0435\u043d\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430, \u0438 \u043e\u043d\u0430 \u0447\u0435\u0441\u0442\u043d\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430.<\/p>\n<h3>\u0413\u043b\u0430\u0432\u043d\u043e\u0435:\u00a0ConcurrentConsumers(N)\u00a0\u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/h3>\n<p>\u0410 \u0432\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u2014 \u0441\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435 \u0438 \u0441\u0430\u043c\u043e\u0435 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u0438 \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438. \u0414\u0435\u0440\u0436\u0438\u0442\u0435\u0441\u044c.<\/p>\n<p><code><strong>ConcurrentConsumers(N)<\/strong><\/code><strong>\u00a0\u043d\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\u0445 \u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u0434\u0430\u0432\u0430\u043b \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430.<\/strong>\u00a0\u041e\u043f\u0446\u0438\u044f \u0431\u044b\u043b\u0430, \u0432 \u043d\u0435\u0451 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u0438 \u0447\u0438\u0441\u043b\u043e, \u043e\u043d\u043e \u0434\u0430\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044f\u043b\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439\u00a0<code>SemaphoreSlim<\/code>\u00a0\u2014 \u043d\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u043e. \u041f\u0440\u0438\u0447\u0438\u043d\u044b \u0431\u044b\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430\u0445, \u0430 \u0441\u0438\u043c\u043f\u0442\u043e\u043c \u043e\u0434\u0438\u043d: \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0437\u0430 \u0440\u0430\u0437,\u00a0<code>unacked<\/code>\u00a0\u0440\u0430\u0441\u0442\u0451\u0442 \u0434\u043e \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0430, \u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442.<\/p>\n<p>\u0427\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0431\u044b\u043b\u043e \u0438 \u0447\u0442\u043e \u0441\u0442\u0430\u043b\u043e:<\/p>\n<ul>\n<li>\n<p><strong>RabbitMQ.<\/strong>\u00a0\u041a\u0430\u043d\u0430\u043b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u043c\u00a0<code>CreateChannelOptions(...)<\/code>\u00a0\u0441 \u0442\u0440\u0435\u043c\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438, \u0447\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 (<code>consumerDispatchConcurrency<\/code>) \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0441\u044f \u043d\u0430 compile-time \u0434\u0435\u0444\u043e\u043b\u0442\u0435 \u2014 \u0430 \u0432\u00a0<code>RabbitMQ.Client<\/code>\u00a07.2.1 \u044d\u0442\u043e\u00a0<code>1<\/code>, \u043d\u0435\u00a0<code>null<\/code>. \u041d\u0435\u043d\u0443\u043b\u0435\u0432\u043e\u0435 per-channel \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00a0<strong>\u043f\u0435\u0440\u0435\u0431\u0438\u0432\u0430\u0435\u0442<\/strong>\u00a0connection-level \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0431\u044b\u043b \u0437\u0430\u0436\u0430\u0442 \u0432 \u0441\u0435\u0440\u0438\u0439\u043d\u0443\u044e \u0432\u044b\u0434\u0430\u0447\u0443, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 URI\/\u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043c\u043e\u043b\u0447\u0430 \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u043b\u043e\u0441\u044c. \u0422\u0435\u043f\u0435\u0440\u044c\u00a0<code>ConcurrentConsumers<\/code>\u00a0\u2014 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u044b\u0447\u0430\u0433 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430: \u043a\u0430\u043d\u0430\u043b \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u044f\u0432\u043d\u043e\u0439 dispatch concurrency. (<code>redb.Route.RabbitMQ<\/code>\u00a03.2.2.)<\/p>\n<\/li>\n<li>\n<p><strong>Kafka.<\/strong>\u00a0\u041f\u043b\u044e\u0441 \u043d\u043e\u0432\u0430\u044f \u043e\u043f\u0446\u0438\u044f\u00a0<code>EnableAutoCommit<\/code>\u00a0(\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00a0<code>true<\/code>) \u2014 \u043f\u0430\u0440\u0438\u0442\u0435\u0442 \u043a\u043e\u043c\u043c\u0438\u0442\u0430 \u043e\u0444\u0444\u0441\u0435\u0442\u0430 \u0441 post-process ack \u0443 RabbitMQ. \u0418 \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0447\u0438\u043d \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0438\u0434\u0430\u043b\u00a0<code>Local: Erroneous state<\/code>\u00a0\u043d\u0430 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435. (<code>redb.Route.Kafka<\/code>\u00a03.2.1.)<\/p>\n<\/li>\n<li>\n<p><strong>AMQP 1.0 \u0438 IBM MQ.<\/strong>\u00a0\u0422\u043e\u0442 \u0436\u0435 \u043a\u043b\u0430\u0441\u0441 \u0431\u0430\u0433\u0430: \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u0439 receive-loop\u00a0<code>await<\/code>\u0438\u043b\u00a0<code>Process<\/code>\u00a0inline \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u0438\u0451\u043c\u043e\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430\u00a0<code>SemaphoreSlim<\/code>\u00a0\u0431\u044b\u043b \u043c\u0451\u0440\u0442\u0432\u044b\u043c \u0433\u0435\u0439\u0442\u043e\u043c \u2014 \u0435\u0433\u043e \u0431\u0440\u0430\u043b \u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043b \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0446\u0438\u043a\u043b. \u0422\u0435\u043f\u0435\u0440\u044c\u00a0<code>ConcurrentConsumers(N)<\/code>\u00a0\u2014 \u044d\u0442\u043e\u00a0<strong>N \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432<\/strong>, \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u044f \u0441\u0435\u0441\u0441\u0438\u044f\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u0441\u0432\u043e\u0439 \u0446\u0438\u043a\u043b (\u0441\u0435\u0441\u0441\u0438\u0438 AMQPNetLite \u0438 managed-\u043a\u043b\u0438\u0435\u043d\u0442 IBM MQ \u043d\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u2014 \u043e\u0442 N \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u0430 \u043d\u0435 \u043e\u0442 \u0448\u0430\u0440\u0438\u043d\u0433\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u043b\u0438\u043d\u043a\u0430). \u0414\u043b\u044f IBM MQ \u044d\u0442\u043e \u0435\u0449\u0451 \u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439: syncpoint \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044e,\u00a0<code>Backout()<\/code>\u00a0\u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0451 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u043e\u0440\u043a\u0435\u0440 \u043e\u0431\u044f\u0437\u0430\u043d \u0432\u043b\u0430\u0434\u0435\u0442\u044c \u0441\u0432\u043e\u0438\u043c. \u0422\u043e\u043f\u0438\u043a\u0438 IBM MQ \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0437\u0430\u0436\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u0430 \u0441 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u2014 N \u043d\u0435\u0434\u043e\u043b\u0433\u043e\u0432\u0435\u0447\u043d\u044b\u0445 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0438 \u0431\u044b \u043f\u043e\u00a0<em>\u043a\u043e\u043f\u0438\u0438<\/em>\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430 \u043d\u0435 \u0434\u0435\u043b\u0438\u043b\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443. (<code>redb.Route.Amqp<\/code>\u00a0\/\u00a0<code>redb.Route.IbmMq<\/code>\u00a03.2.1.)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u0442\u0440\u0438 \u0445\u043e\u0442\u0444\u0438\u043a\u0441\u0430 (RabbitMQ 3.2.2, Kafka 3.2.1, Amqp\/IbmMq 3.2.1) \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0432\u0451\u0440\u043d\u0443\u0442\u044b \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0431\u0430\u043c\u043f 3.3.0. \u041a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u2014 \u0436\u0438\u0432\u043e\u0439 \u0440\u0435\u0433\u0440\u0435\u0441\u0441\u0438\u043e\u043d\u043d\u044b\u0439 \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0442\u0438\u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0440\u043e\u043a\u0435\u0440\u0430: \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u043f\u0430\u0447\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0441\u0442\u0430\u0432\u0438\u043c\u00a0<code>ConcurrentConsumers(5)<\/code>, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u0430\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 1, \u0430\u00a0<code>ConcurrentConsumers(1)<\/code>\u00a0\u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u043c.<\/p>\n<blockquote>\n<p><strong>\u041d\u0430 \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438.<\/strong>\u00a0\u0415\u0441\u043b\u0438 \u0432\u0430\u0448 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441\u0442\u0430\u0432\u0438\u043b\u00a0<code>ConcurrentConsumers(N &gt; 1)<\/code>\u00a0\u0438 \u00ab\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u00bb \u2014 \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 3.3.0 \u043e\u043d \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0442\u0441\u044f: \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0430\u043a\u043e\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435, \u0430 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043e\u0431\u044f\u0437\u0430\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438. \u041c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c\u00a0<code>1<\/code>\u00a0\u043d\u0435 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044b \u2014 \u043a\u0430\u043a \u0431\u044b\u043b\u0438 \u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u043c\u0438, \u0442\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c.<\/p>\n<\/blockquote>\n<p>\u041f\u043b\u044e\u0441 \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0435 \u2014 \u043d\u043e\u0432\u044b\u0439\u00a0<code>AutoAck<\/code>\u00a0\u0443 RabbitMQ (broker-side auto-ack \/ at-most-once, \u0430\u043d\u0430\u043b\u043e\u0433 Kafka\u00a0<code>EnableAutoCommit<\/code>) \u0438 \u043f\u043e\u0447\u0438\u043d \u0434\u0432\u043e\u0439\u043d\u043e\u0433\u043e\u00a0<code>BasicAck<\/code>, \u043a\u043e\u0433\u0434\u0430 route-level\u00a0<code>.Transacted()<\/code>\u00a0\u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440.<\/p>\n<h3>\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f per-exchange: \u043a\u043e\u043d\u0435\u0446 \u00abcaptive singleton\u00bb<\/h3>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u043b\u0430\u0441\u0442 \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u2014 \u0443\u0436\u0435 \u0432 \u044f\u0434\u0440\u0435 \u0434\u0432\u0438\u0436\u043a\u0430.\u00a0<code>IRedbService<\/code>\u00a0\u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043e\u0434\u043d\u043e, \u043d\u0435\u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0411\u0414 (\u043c\u043e\u0434\u0435\u043b\u044c EF-DbContext). \u0410 DSL-\u0448\u0430\u0433\u0438\u00a0<code>ProcessWithRedb(...)<\/code>,\u00a0<code>SetBodyFromRedb(...)<\/code>,\u00a0<code>SetHeaderFromRedb(...)<\/code>,\u00a0<code>BeginRedbTransaction()<\/code>\u00a0\u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u0430\u0434\u0430\u043b\u0438 \u0432\u00a0<strong>\u043e\u0434\u0438\u043d<\/strong>\u00a0<code>IRedbService<\/code>, \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e DI. \u041f\u043e\u0434 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e (Splitter \u0441 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u043e\u043c, SEDA, \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439\u00a0<code>ConcurrentConsumers(N)<\/code>, \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b) \u0434\u0432\u0430 exchange \u0433\u043d\u0430\u043b\u0438 \u043e\u0434\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u2014 \u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043a\u0438\u0434\u0430\u043b\u00a0<em>\u00abA command is already in progress\u00bb<\/em>\u00a0\/\u00a0<em>\u00abconnection is busy\u00bb<\/em>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 exchange \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u00a0<strong>\u0441\u0432\u043e\u0439 DI-scope \u2192 \u0441\u0432\u043e\u0439 scoped\u00a0<\/strong><code><strong>IRedbService<\/strong><\/code><strong>\u00a0\u2192 \u0441\u0432\u043e\u0451 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u0443\u043b\u0430<\/strong>, \u0437\u0430\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430 exchange \u0438 \u0443\u0442\u0438\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u043e\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0438\u043c. \u041d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 exchange \u043d\u0435\u0442 (\u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 \u0441\u0438\u0434). \u041f\u043b\u044e\u0441 \u2014\u00a0<code>controller.Redb()<\/code>\u00a0\u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432: \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442 per-request \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u0449\u0435\u0433\u043e captive-\u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u0430.<\/p>\n<p>\u0417\u0430\u043e\u0434\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u043b\u0438 \u0443\u0442\u0435\u0447\u043a\u0438 DI-scope\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043d\u0430 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 exchange:\u00a0<code>ThreadsProcessor<\/code>,\u00a0<code>SedaProducer<\/code>\/<code>VmProducer<\/code>\u00a0(\u0443\u0442\u0435\u043a\u0430\u043b \u043a\u043b\u043e\u043d \u043f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e\u043c hand-off),\u00a0<code>WireTapProcessor<\/code>\u00a0(\u0443\u0442\u0435\u043a\u0430\u043b tap-\u043a\u043b\u043e\u043d \u043f\u0440\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0432\u00a0<code>onPrepare<\/code>\/<code>newBody<\/code>), scheduled-\u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b\u00a0<code>llm:\/\/<\/code>\u00a0\u0438\u00a0<code>exec:\/\/<\/code>\u00a0(\u043d\u0435 \u0443\u0442\u0438\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 per-tick exchange). \u0412\u0441\u0451 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0438\u0441\u043f\u043e\u0437\u0438\u0442\u0441\u044f \u0432\u00a0<code>finally<\/code>. \u0418 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043b\u0435\u043d\u0438\u0432\u044b\u0439 \u0441\u0442\u0430\u0440\u0442 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u2014 \u043d\u0430 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0439\u043c\u0430\u0442\u044c\u00a0<code>NullReferenceException<\/code>\u00a0(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Redis-\u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u0441 \u0435\u0449\u0451 \u043d\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u00a0<code>_db<\/code>); \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u0430 \u043f\u0443\u0442\u0438 single-flight, \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u0432\u0438\u0434\u0435\u043d \u043a\u0430\u043a \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0432\u0448\u0438\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u043d\u043e\u0433\u043e\u00a0<code>ConnectAsync()<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e: 3.3.0 \u2014 \u044d\u0442\u043e \u0440\u0435\u043b\u0438\u0437, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e redb.Route \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e \u0438 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442 \u00ab\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u0434\u0435\u043c\u043e\u00bb \u043e\u0442 \u00ab\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043f\u0440\u043e\u0434\u0435\u00bb.<\/p>\n<h3>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0451 \u0432\u043c\u0435\u0441\u0442\u0435: RAG-\u0431\u043e\u0442 \u0432 Telegram \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438 \u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0438 \u0441\u043f\u0438\u0441\u043a\u043e\u043c, \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043e\u043d\u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 \u0432\u0435\u0449\u044c. \u0417\u0430\u0434\u0430\u0447\u0430: Telegram-\u0431\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043f\u043e \u0432\u0430\u0448\u0435\u0439 \u0431\u0430\u0437\u0435 \u0437\u043d\u0430\u043d\u0438\u0439 (\u043d\u0430\u0431\u043e\u0440 markdown-\u0444\u0430\u0439\u043b\u043e\u0432), \u0430 \u043d\u0435 \u0432\u044b\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u0442. \u0422\u0440\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u043d\u0430\u043d\u0438\u0439, \u043f\u0440\u0438\u0451\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u0438 \u043e\u0442\u0432\u0435\u0442, \u0438 \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0430 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0431\u0430\u0437\u0443 \u0437\u043d\u0430\u043d\u0438\u0439. \u041e\u0434\u0438\u043d \u043c\u0430\u0440\u0448\u0440\u0443\u0442: \u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b, \u0440\u0435\u0436\u0435\u043c \u043d\u0430 \u0447\u0430\u043d\u043a\u0438, \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043c, \u043a\u043b\u0430\u0434\u0451\u043c \u0432 \u0441\u0442\u043e\u0440. \u0421\u0442\u043e\u0440 \u2014 redb, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<pre><code>\/\/ 1. Ingest: \u043f\u0430\u043f\u043a\u0430 markdown \u2192 \u0447\u0430\u043d\u043a\u0438 \u0441 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430\u043c\u0438 \u0432 redbFrom(\"file:\/\/docs?include=*.md\")    .To(\"knowledge:\/\/handbook?chunkChars=1000&amp;overlap=100&amp;embed=true\");<\/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>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c \u0431\u043e\u0442. \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0430\u043f\u0434\u0435\u0439\u0442 \u0438\u0437 Telegram, \u0434\u043e\u0441\u0442\u0430\u0451\u043c \u0442\u043e\u043f-5 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u0445 \u0447\u0430\u043d\u043a\u043e\u0432 \u043f\u043e\u0434 \u0442\u0435\u043a\u0441\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u0430, \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u043f\u0442 \u0438 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c.\u00a0<code>.Knowledge()<\/code>\u00a0\u0441\u0430\u043c \u0440\u0435\u0448\u0438\u0442 \u2014 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 (\u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u00a0<code>IEmbeddingProvider<\/code>) \u0438\u043b\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u043e\u0438\u0441\u043a.<\/p>\n<pre><code>\/\/ 2. \u0412\u043e\u043f\u0440\u043e\u0441 \u0438\u0437 Telegram \u2192 RAG \u2192 \u043e\u0442\u0432\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u0442\u043e\u0442 \u0436\u0435 \u0447\u0430\u0442From(Tg.Receive(token))    .Threads(4)                         \/\/ \u0434\u043e 4 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e        .Knowledge(\"handbook\", k: 5)    \/\/ \u0442\u043e\u043f-5 \u0447\u0430\u043d\u043a\u043e\u0432 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u043f\u0442        .To(\"llm:\/\/claude\")             \/\/ \u043e\u0442\u0432\u0435\u0442, \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043d\u0438\u0445    .EndThreads()    .To(Tg.Send(token).ChatId(Header(TelegramHeaders.ChatId)));<\/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>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0451. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0435\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442: \u043d\u0435\u0442 \u0440\u0443\u0447\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438, \u043d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432, \u043d\u0435\u0442 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u043a\u043b\u0435\u044f \u043c\u0435\u0436\u0434\u0443 Telegram \u0438 LLM, \u043d\u0435\u0442 \u043f\u0443\u043b\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0430\u0434\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c.\u00a0<code>.Threads(4)<\/code>\u00a0\u0434\u0430\u0451\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432 \u043d\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u0432\u044b\u0434\u0430\u0451\u0442 \u0430\u043f\u0434\u0435\u0439\u0442\u044b \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443; \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a redb \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u0432\u043e\u0451 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0430\u043c\u0430 \u0440\u0435\u0448\u0430\u043b\u0430, \u043a\u043e\u0433\u0434\u0430 \u043b\u0435\u0437\u0442\u044c \u0432 \u0431\u0430\u0437\u0443 \u0437\u043d\u0430\u043d\u0438\u0439 (\u0430 \u043d\u0435 \u0436\u0451\u0441\u0442\u043a\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441), \u2014 \u0432\u043c\u0435\u0441\u0442\u043e\u00a0<code>.Knowledge()<\/code>\u00a0\u0434\u0430\u0451\u043c \u0430\u0433\u0435\u043d\u0442\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00a0<code>knowledge_search<\/code>\u00a0\u0438 \u043f\u0438\u043d\u0443\u0435\u043c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043d\u0435 \u043c\u043e\u0433 \u0432\u044b\u0439\u0442\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b\u00a0<code>handbook<\/code>:<\/p>\n<pre><code>\/\/ \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043e\u0434\u0438\u043d \u0440\u0430\u0437; \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0438\u043d\u0435\u043d\u0430 \u2014 \u0430\u0433\u0435\u043d\u0442 \u0437\u0430\u043f\u0435\u0440\u0442 \u0432 \u043d\u0435\u0439context.AddRoutes(new KnowledgeSearchTool(new KnowledgeSearchOptions {    Collection        = \"handbook\",    EmbeddingProvider = embeddings      \/\/ \u0435\u0441\u0442\u044c \u2192 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430; \u043d\u0435\u0442 \u2192 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u043e\u0438\u0441\u043a}));From(Tg.Receive(token))    .Threads(4)        .To(\"llm:\/\/claude?tools=knowledge_search\")    .EndThreads()    .To(Tg.Send(token).ChatId(Header(TelegramHeaders.ChatId)));<\/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>\u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043d\u0430\u0431\u043e\u0440 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u2014\u00a0<code>knowledge:\/\/<\/code>,\u00a0<code>embed:\/\/<\/code>,\u00a0<code>.Knowledge()<\/code>,\u00a0<code>knowledge_search<\/code>,\u00a0<code>telegram:\/\/<\/code>,\u00a0<code>.Threads()<\/code>\u00a0\u2014 \u0438 \u0432\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0438\u043b\u0438 \u0434\u043e\u0437\u0440\u0435\u043b\u043e \u0432 3.3.0. \u041f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0436\u0434\u0430\u044f \u0448\u0442\u0443\u043a\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f; \u0432\u043c\u0435\u0441\u0442\u0435 \u2014 \u044d\u0442\u043e RAG-\u0431\u043e\u0442 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0431\u0435\u0437 \u0435\u0434\u0438\u043d\u043e\u0439 \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0432\u0435\u0440\u0445 \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<hr\/>\n<h2>redb (\u044f\u0434\u0440\u043e \u0411\u0414): \u0447\u0442\u043e \u0432\u043e\u0448\u043b\u043e<\/h2>\n<p>\u0412 \u044f\u0434\u0440\u0435 \u2014 \u0442\u0440\u0438 \u043f\u043e\u0447\u0438\u043d\u0430 \u0438 \u043e\u0434\u0438\u043d \u0437\u0430\u0449\u0438\u0442\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u0438 \u0432\u0441\u0435 \u043e\u043d\u0438 \u0432 \u0442\u043e\u0439 \u0436\u0435 \u0442\u0435\u043c\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439.<\/p>\n<ul>\n<li>\n<p><strong>Fail-fast guard \u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430<\/strong>\u00a0(<code>RedBase.Postgres<\/code>,\u00a0<code>RedBase.MSSql<\/code>,\u00a0<code>RedBase.SQLite<\/code>\u00a0+\u00a0<code>.Pro<\/code>). \u0415\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435\u00a0<code>IRedbService<\/code>\u00a0\u0432\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u0440\u0430\u0437\u0443, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439\u00a0<code>InvalidOperationException<\/code>\u00a0\u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u2014 \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u0443\u0442\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 (<em>\u00abA command is already in progress\u00bb<\/em>,\u00a0<em>\u00abconnection is busy\u00bb<\/em>,\u00a0<em>\u00abanother read operation is already in progress\u00bb<\/em>). \u041b\u0451\u0433\u043a\u0430\u044f\u00a0<code>Interlocked<\/code>-\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u043d\u0443\u043b\u0435\u0432\u0430\u044f \u0446\u0435\u043d\u0430 \u043d\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u043c \u043f\u0443\u0442\u0438. \u042d\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442 per-exchange \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0432 redb.Route: \u0435\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0448\u0430\u0440\u0438\u0442 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u2014 \u0443\u0437\u043d\u0430\u0451\u0442 \u043e\u0431 \u044d\u0442\u043e\u043c \u0441\u0440\u0430\u0437\u0443 \u0438 \u043f\u043e-\u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:\u00a0<\/strong><code><strong>array.Contains(x)<\/strong><\/code><strong>\u00a0\u0432\u00a0<\/strong><code><strong>WhereRedb<\/strong><\/code><strong>\u00a0\u043f\u0430\u0434\u0430\u043b \u043d\u0430 .NET 9 \/ C# 13.<\/strong>\u00a0<code>string[]<\/code>\u00a0(\u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432)\u00a0<code>.Contains(x)<\/code>\u00a0\u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0438\u043d\u0434\u0438\u0442\u0441\u044f \u043a overload&#8217;\u0443\u00a0<code>ReadOnlySpan<\/code>\u00a0(<code>MemoryExtensions.Contains<\/code>), \u0430 \u043d\u0435\u00a0<code>Enumerable.Contains<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043e\u0442\u0432\u0435\u0440\u0433\u0430\u043b \u0441\u00a0<code>NotSupportedException<\/code>. \u041f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0451\u0442\u00a0<code>MemoryExtensions.Contains<\/code>, \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0441\u0438\u044e \u043c\u0430\u0441\u0441\u0438\u0432\u2192\u0441\u043f\u0430\u043d \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0432 \u0442\u043e\u0442 \u0436\u0435\u00a0<code>IN<\/code>, \u0447\u0442\u043e \u0438\u00a0<code>Enumerable.Contains<\/code>. \u041c\u0435\u043b\u043e\u0447\u044c, \u043d\u043e \u043d\u0430 \u043d\u043e\u0432\u043e\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u043b\u043e\u0432\u0438\u043b\u0430\u0441\u044c \u043d\u0430 \u0440\u043e\u0432\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<\/li>\n<li>\n<p><code><strong>ComputeHash()<\/strong><\/code><strong>\u00a0NRE \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0441\u00a0<\/strong><code><strong>Props == null<\/strong><\/code><strong>.<\/strong>\u00a0\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c\u00a0<code>ComputeFor&lt;TProps&gt;<\/code>\u00a0\u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u043b \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043e null-\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 guard \u2014 \u043f\u0443\u0442\u044c \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>null<\/code>\u00a0(\u2192\u00a0<code>Guid.Empty<\/code>) \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>\u0423\u0442\u0435\u0447\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0438\u0437 \u043f\u0443\u043b\u0430 \u043d\u0430 dispose \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f<\/strong>\u00a0(<code>RedBase.Postgres<\/code>,\u00a0<code>RedBase.MSSql<\/code>,\u00a0<code>RedBase.SQLite<\/code>\u00a0+\u00a0<code>.Pro<\/code>). \u0411\u0440\u043e\u0441\u043e\u043a \u0438\u0437\u00a0<code>DisposeAsync()<\/code>\u00a0\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 (\u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432 \u0440\u0430\u0437\u0433\u0430\u0440 \u00ab\u0448\u0442\u043e\u0440\u043c\u0430 \u043e\u0448\u0438\u0431\u043e\u043a\u00bb \u043d\u0430 \u0443\u0436\u0435 \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438) \u043f\u0440\u043e\u0441\u043a\u0430\u043a\u0438\u0432\u0430\u043b \u043c\u0438\u043c\u043e dispose \u0441\u0430\u043c\u043e\u0433\u043e\u00a0<code>_connection<\/code>\u00a0\u2014 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u0443\u043b. \u0410 \u0442\u0430\u043a \u043a\u0430\u043a\u00a0<code>SaveAsync<\/code>\u00a0\u0438\u0434\u0451\u0442 \u0432 \u044f\u0432\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u0437\u0432\u043e\u0434\u0438\u043b\u0430 \u044d\u0442\u043e\u0442 \u043f\u0443\u0442\u044c: \u043f\u043e\u0434 \u0432\u0441\u043f\u043b\u0435\u0441\u043a\u043e\u043c \u043e\u0448\u0438\u0431\u043e\u043a \u0443\u0442\u0435\u0447\u043a\u0430 \u0441\u0430\u043c\u0430 \u0441\u0435\u0431\u044f \u0443\u0441\u0438\u043b\u0438\u0432\u0430\u043b\u0430 \u0438 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0432\u044b\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u043b\u0430 \u043f\u0443\u043b (\u0441\u0438\u043c\u043f\u0442\u043e\u043c: \u0437\u0434\u043e\u0440\u043e\u0432\u044b\u0439 \u043f\u0443\u043b \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u043f\u0435\u0440\u0435\u043b\u0435\u0437\u0430\u0435\u0442 \u0437\u0430\u00a0<code>MaxPoolSize<\/code>\u00a0\u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430\u043c\u0438, \u043b\u0435\u0447\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u043e\u043c). \u0422\u0435\u043f\u0435\u0440\u044c dispose \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0438\u0434\u0443\u0442 \u0447\u0435\u0440\u0435\u0437\u00a0<code>try\/finally<\/code>\u00a0\u2014 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430, \u0430 \u0441\u0430\u043c \u0444\u043e\u043b\u0442 \u0434\u0438\u0441\u043f\u043e\u0437\u0430 \u043d\u0435 \u0433\u043b\u043e\u0442\u0430\u0435\u0442\u0441\u044f, \u0430 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0441\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u043c.<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<h2>redb.Tsak (\u0440\u0430\u043d\u0442\u0430\u0439\u043c): \u0447\u0442\u043e \u0432\u043e\u0448\u043b\u043e<\/h2>\n<p>\u0420\u0430\u043d\u0442\u0430\u0439\u043c \u0432 3.3.0 \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0451 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0451.<\/p>\n<ul>\n<li>\n<p><strong>\u041d\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0435.<\/strong>\u00a0<code>redb.Route.Sqs<\/code>\u00a0(<code>sqs:\/\/<\/code>,\u00a0<code>sns:\/\/<\/code>) \u0438\u00a0<code>redb.Route.Telegram<\/code>\u00a0(<code>telegram:\/\/<\/code>) \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432 \u2014 \u043c\u043e\u0434\u0443\u043b\u0438 \u043d\u0430 Tsak \u043c\u043e\u0433\u0443\u0442 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u0437 \u0440\u0443\u0447\u043d\u043e\u0439 \u0434\u043e\u0443\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0430\u0446\u0438\u0438. \u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u043a\u0430 shared-\u0441\u043b\u043e\u044f \u0441\u0431\u043e\u0440\u043a\u0438 (\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b \u043a\u043b\u0430\u0434\u0443\u0442\u0441\u044f \u0432\u00a0<code>Libs\/shared<\/code>), \u0438 \u2014 \u0441\u043f\u043e\u0439\u043b\u0435\u0440 \u0438\u0437 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043a\u0443\u0445\u043d\u0438 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u043f\u043e\u0439\u043c\u0430\u043b\u0438, \u0447\u0442\u043e \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u0430 \u043d\u0435 \u0437\u043d\u0430\u043b \u043f\u0440\u043e \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b: \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u043e\u0431\u0440\u0430\u0437 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u0434\u043d\u044f\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0443\u0432\u0438\u0434\u0435\u043b\u0438 \u0432 \u043b\u043e\u0433\u0430\u0445\u00a0<code>Loaded shared assembly redb.Route.Sqs<\/code>\u00a0\u0438\u00a0<code>redb.Route.Telegram<\/code>\u00a0\u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0414\u0430\u0448\u0431\u043e\u0440\u0434-\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 cron-\u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u0430\u0436\u0435 \u0431\u0435\u0437 \u0441\u0435\u043a\u0446\u0438\u0438\u00a0<\/strong><code><strong>Quartz<\/strong><\/code><strong>.<\/strong>\u00a0\u0420\u0430\u043d\u044c\u0448\u0435 \u0431\u0435\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0430\u00a0<code>Quartz<\/code>\u00a0Tsak \u043d\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043e\u0431\u0449\u0438\u0439\u00a0<code>IScheduler<\/code>, cron-\u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441\u0430\u043c \u0441\u0435\u0431\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u043b\u00a0<em>per-context<\/em>\u00a0in-memory \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435 \u0432\u0438\u0434\u0435\u043b \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439\u00a0<code>_system<\/code>-\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u2014 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0431\u044b\u043b\u0430 \u043f\u0443\u0441\u0442\u043e\u0439, \u0445\u043e\u0442\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u043b. \u0422\u0435\u043f\u0435\u0440\u044c Tsak \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0434\u0430\u0451\u0442 \u043e\u0434\u0438\u043d \u043e\u0431\u0449\u0438\u0439\u00a0<code>IScheduler<\/code>\u00a0(fallback \u043d\u0430 in-memory\u00a0<code>RAMJobStore<\/code>, \u0435\u0441\u043b\u0438 \u0441\u0435\u043a\u0446\u0438\u0438 \u043d\u0435\u0442). \u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u043d\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440, \u043d\u0438 \u0431\u0430\u0437\u0430;\u00a0<code>AdoJobStore<\/code>\u00a0\u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0438\u0442\u044c \u0438 \u0448\u0430\u0440\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u0435\u0436\u0434\u0443 \u0443\u0437\u043b\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>Users admin API \u2014 per-request scoped\u00a0<\/strong><code><strong>IRedbService<\/strong><\/code><strong>.<\/strong>\u00a0<code>UsersController<\/code>\u00a0\u0440\u0430\u043d\u044c\u0448\u0435 \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u043b \u043e\u0431\u0449\u0438\u0439 captive-\u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d, \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0430\u0434\u043c\u0438\u043d-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043c\u043e\u0433\u043b\u0438 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432\u0430\u0442\u044c. \u0422\u0435\u043f\u0435\u0440\u044c \u2014 per-request \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0447\u0435\u0440\u0435\u0437\u00a0<code>controller.Redb()<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0437 3.2.1<\/strong>\u00a0(\u0441\u0432\u0451\u0440\u043d\u0443\u0442\u043e \u0441\u044e\u0434\u0430): \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 Endpoints \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0440\u044f\u0447\u0435\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u043b\u0430 \u0432 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435; standalone-\u0430\u0440\u0445\u0438\u0432 web-\u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u043d\u0430 \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443 8080, \u0430 \u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c 5000.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0442\u0440\u0435\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: NuGet-\u043f\u0430\u043a\u0435\u0442\u044b, Docker-\u043e\u0431\u0440\u0430\u0437\u044b\u00a0<code>redb-tsak-{worker,web,stack}<\/code>\u00a0(.NET 9, \u0442\u0435\u0433\u0438\u00a0<code>:3.3.0-net9<\/code>,\u00a0<code>:3.3.0<\/code>,\u00a0<code>:latest<\/code>) \u043d\u0430\u00a0<code>ghcr.io\/redbase-app<\/code>\u00a0\u0441 cosign-\u043f\u043e\u0434\u043f\u0438\u0441\u044c\u044e, \u0438 standalone-\u0430\u0440\u0445\u0438\u0432\u044b\u00a0<code>redb-tsak-3.3.0-linux-x64.tar.gz<\/code>\u00a0\/\u00a0<a href=\"http:\/\/redb-tsak-3.3.0-win-x64.zip\" rel=\"noopener noreferrer nofollow\"><code>redb-tsak-3.3.0-win-x64.zip<\/code><\/a>\u00a0\u0441\u00a0<code>checksums.txt<\/code>\u00a0\u0438\u00a0<code>.bundle<\/code>-\u043f\u043e\u0434\u043f\u0438\u0441\u044f\u043c\u0438 \u043d\u0430 GitHub-\u0440\u0435\u043b\u0438\u0437\u0435. \u0412\u0441\u0451 \u043d\u0430\u00a0<strong>.NET 9<\/strong>.<\/p>\n<p><strong>[\u0421\u041a\u0420\u0418\u041d: \u0434\u0430\u0448\u0431\u043e\u0440\u0434 Tsak \u043d\u0430 localhost:8080 \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c echo-\u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c]<\/strong><\/p>\n<hr\/>\n<h3>\u041f\u0440\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 Pro \u2014 \u0435\u0449\u0451 \u0440\u0430\u0437, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435<\/h3>\n<p>\u042f \u0441\u043a\u0430\u0437\u0430\u043b \u044d\u0442\u043e \u0432\u043e \u0432\u0432\u043e\u0434\u043d\u043e\u0439, \u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u00ab\u0430 \u0432 \u0447\u0451\u043c \u043f\u043e\u0434\u0432\u043e\u0445\u00bb \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u043c. \u041f\u043e\u0434\u0432\u043e\u0445\u0430 \u043d\u0435\u0442. Pro \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u043e\u043f\u0440\u0438\u0435\u0442\u0430\u0440\u043d\u044b\u043c (\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u044b), \u043d\u043e \u043d\u0430 \u0432\u0441\u0435\u0439 \u043b\u0438\u043d\u0435\u0439\u043a\u0435 3.x \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0441\u044f\u00a0<strong>\u0434\u0430\u0440\u043e\u043c \u0438 \u0431\u0435\u0437 \u0432\u0441\u044f\u043a\u043e\u0433\u043e \u0443\u0447\u0451\u0442\u0430<\/strong>\u00a0\u2014 \u043d\u0435\u0442 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0439, \u043a\u043b\u044e\u0447\u0435\u0439, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u043b\u0438 \u043b\u0438\u043c\u0438\u0442\u043e\u0432 \u043f\u043e \u0443\u0437\u043b\u0430\u043c\/\u043e\u0431\u044a\u0451\u043c\u0443.<\/p>\n<p>\u0427\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b\u043e \u043f\u043b\u0430\u0442\u043d\u044b\u043c, \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e: \u0443 \u044f\u0434\u0440\u0430 redb \u2014 change tracking, bulk-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u043a\u044d\u0448, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b (\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u043e\u043a\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438); \u0443 Tsak \u2014 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c, \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u043b\u043e\u043a, leader election, failover. \u0422\u043e \u0435\u0441\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0437\u0430 \u0447\u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0435\u043a\u0430\u0445 \u0431\u0435\u0440\u0443\u0442 \u0434\u0435\u043d\u044c\u0433\u0438. \u0417\u0434\u0435\u0441\u044c \u2014\u00a0<code>dotnet add package<\/code>\u00a0\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435.<\/p>\n<hr\/>\n<h3>\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 3.2.x: \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0447\u0435\u043a-\u043b\u0438\u0441\u0442<\/h3>\n<p>\u0420\u0435\u043b\u0438\u0437 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c \u043f\u043e API, \u043d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u2014 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c.<\/p>\n<ul>\n<li>\n<p><strong>\u041f\u0440\u043e\u0439\u0434\u0438\u0442\u0435\u0441\u044c \u043f\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043c \u0441\u00a0<\/strong><code><strong>ConcurrentConsumers(N &gt; 1)<\/strong><\/code><strong>.<\/strong>\u00a0\u0420\u0430\u043d\u044c\u0448\u0435 \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441\u0435\u0440\u0438\u0439\u043d\u043e (\u0431\u0430\u0433), \u0442\u0435\u043f\u0435\u0440\u044c \u2014 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043d\u0430 \u0442\u0430\u043a\u0438\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b \u0438 \u0447\u0442\u043e \u0432\u044b \u043d\u0435 \u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u0415\u0441\u043b\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u043d \u2014 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435\u00a0<code>ConcurrentConsumers(1)<\/code>\u00a0(\u044d\u0442\u043e \u0434\u0435\u0444\u043e\u043b\u0442, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c).<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u0445.<\/strong>\u00a0\u0412\u0441\u0451, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u00ab\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e\u00bb, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0431\u044b\u043b \u0434\u0435-\u0444\u0430\u043a\u0442\u043e \u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u043c, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0438\u0437 N \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><code><strong>IRedbService<\/strong><\/code><strong>\u00a0\u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u0445 \u2014 \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e.<\/strong>\u00a0Per-exchange \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0432\u043a\u043b\u044e\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u0430\u043c\u0438; \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043f\u0440\u043e\u043f\u0430\u0434\u0443\u0442 \u043f\u0440\u0435\u0436\u043d\u0438\u0435\u00a0<em>\u00abA command is already in progress\u00bb<\/em>\u00a0\u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c\u044e. \u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043e\u0434\u0438\u043d\u00a0<code>IRedbService<\/code>\u00a0\u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e exchange \u0432 \u043e\u0431\u0445\u043e\u0434 DSL \u2014 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u044c\u0442\u0435, \u044f\u0434\u0440\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442 fail-fast.<\/p>\n<\/li>\n<li>\n<p><strong>\u0411\u0430\u043c\u043f \u0432\u0435\u0440\u0441\u0438\u0439 \u2014 \u0435\u0434\u0438\u043d\u044b\u0439.<\/strong>\u00a0\u0412\u0441\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0435\u0434\u0443\u0442 \u043d\u0430\u00a0<code>3.3.0<\/code>; \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c\u00a0<code>redb.Route<\/code>\u00a03.3.0 \u0441 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u043c 3.2.0 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e (\u0445\u043e\u0442\u044f \u0441\u0442\u0430\u0440\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b 3.2.x \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b \u043f\u043e API \u2014 \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0437 \u0441\u0432\u0435\u0436\u0438\u0445 \u0444\u0438\u043a\u0441\u043e\u0432 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438).<\/p>\n<\/li>\n<li>\n<p><strong>Tsak: \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0435\u0440\u0438\u0442\u0435 \u043e\u0431\u0440\u0430\u0437\/\u0432\u043e\u0437\u044c\u043c\u0438\u0442\u0435 \u043d\u043e\u0432\u044b\u0439.<\/strong>\u00a0\u0415\u0441\u043b\u0438 \u0433\u043e\u043d\u044f\u0435\u0442\u0435 \u0441\u0432\u043e\u044e \u0441\u0431\u043e\u0440\u043a\u0443 \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432\u0430 \u2014 \u043d\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b (<code>Sqs<\/code>,\u00a0<code>Telegram<\/code>) \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 shared-\u0441\u043b\u043e\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438; \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043e\u0431\u0440\u0430\u0437\u044b\u00a0<code>:3.3.0<\/code>\u00a0\u0443\u0436\u0435 \u0441 \u043d\u0438\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0438\u0447\u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0440\u043e\u0447\u043d\u043e \u0438 \u043d\u0435 \u043b\u043e\u043c\u0430\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0443 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e \u00ab\u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0433\u0434\u0435 \u0443 \u0432\u0430\u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u00bb.<\/p>\n<h3>\u041a\u0430\u043a \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c<\/h3>\n<p>\u042f\u0434\u0440\u043e \u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u2014 \u0441 NuGet:<\/p>\n<pre><code class=\"bash\">dotnet add package redb.Coredotnet add package redb.Postgres      # \u0438\u043b\u0438 redb.MSSql \/ redb.SQLitedotnet add package redb.Postgres.Pro  # Pro \u2014 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e, \u0431\u0435\u0437 \u043a\u043b\u044e\u0447\u0430<\/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>\u0414\u0432\u0438\u0436\u043e\u043a \u0438 \u043d\u0443\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b:<\/p>\n<pre><code class=\"bash\">dotnet add package redb.Routedotnet add package redb.Route.Sqsdotnet add package redb.Route.Telegramdotnet add package redb.Route.Llm<\/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\u043d\u0442\u0430\u0439\u043c \u2014 \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0438\u043b\u0438 \u0430\u0440\u0445\u0438\u0432\u043e\u043c:<\/p>\n<pre><code class=\"bash\">docker pull ghcr.io\/redbase-app\/redb-tsak-stack:3.3.0# \u043b\u0438\u0431\u043e standalone-\u0430\u0440\u0445\u0438\u0432 \u0441 GitHub-\u0440\u0435\u043b\u0438\u0437\u0430 v3.3.0 (linux-x64 \/ win-x64), \u0441 cosign-\u043f\u043e\u0434\u043f\u0438\u0441\u044c\u044e<\/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>\u041e\u0431\u0440\u0430\u0437\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b cosign, \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u2014 \u0432 \u0440\u0435\u043b\u0438\u0437\u0435 (<a href=\"http:\/\/cosign.pub\" rel=\"noopener noreferrer nofollow\"><code>cosign.pub<\/code><\/a>):<\/p>\n<pre><code class=\"bash\">cosign verify --key cosign.pub ghcr.io\/redbase-app\/redb-tsak-worker:3.3.0<\/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<hr\/>\n<h3>\u0418\u0442\u043e\u0433<\/h3>\n<p>3.3.0 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e \u0437\u0440\u0435\u043b\u043e\u0441\u0442\u044c. \u041d\u043e\u0432\u044b\u0435 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u044b (SQS\/SNS, Telegram) \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0439 RAG \u2014 \u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u043d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u043b\u0438\u0437\u0435 \u043d\u0435 \u043e\u043d\u0438. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u0438 \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438\u00a0<strong>\u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u0434\u044b\u0440\u0443 \u0432 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438<\/strong>:\u00a0<code>ConcurrentConsumers(N)<\/code>\u00a0\u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u043b \u043d\u0438 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0431\u0440\u043e\u043a\u0435\u0440\u0435, \u0430 \u043e\u0431\u0449\u0438\u0439 \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0439\u00a0<code>IRedbService<\/code>\u00a0\u0440\u0430\u0437\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u0441\u044f \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043c\u0443\u0442\u043d\u044b\u043c\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0430\u0433\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u0434\u0435\u043c\u043e \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0432\u0430\u0435\u0442 \u0432 \u043f\u0440\u043e\u0434\u0435 \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0447\u0435\u0441\u0442\u043d\u0430\u044f \u2014 \u043d\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\u0445, \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u0447\u0435\u0440\u0435\u0437\u00a0<code>.Threads(N)<\/code>, \u0438 \u0441 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\u043c\u0438 per-exchange.<\/p>\n<p>\u041f\u043b\u044e\u0441 \u2014 \u0432\u0435\u0441\u044c \u0441\u0442\u0435\u043a \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u043d\u0430 3.3.0, \u0432\u0441\u0451 \u043d\u0430 .NET 9, Pro \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u0435\u043d \u0431\u0435\u0437 \u043a\u043b\u044e\u0447\u0430. \u0421\u0432\u043e\u044f \u0411\u0414, \u0441\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a, \u0441\u0432\u043e\u0439 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0441 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u043e\u043c \u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u043c \u2014 \u043a\u0430\u043a \u043e\u0434\u043d\u0430 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0430 \u043d\u0435 \u0437\u043e\u043e\u043f\u0430\u0440\u043a.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u0443\u0435\u0442\u0435 \u2014 \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0447\u0442\u043e \u043b\u043e\u0432\u0438\u0442\u0441\u044f \u0432 \u0432\u0430\u0448\u0435\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438. \u041f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430\u043c \u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430\u043c EIP \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u044b \u0432 \u0441\u0435\u0440\u0438\u0438.<\/p>\n<blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0438 \u0440\u0435\u043b\u0438\u0437\u044b:\u00a0<a href=\"https:\/\/github.com\/redbase-app\/\" rel=\"noopener noreferrer nofollow\">github.com\/redbase-app<\/a>. \u041f\u0440\u043e \u0411\u0414 redb:\u00a0<a href=\"http:\/\/redb.ru\" rel=\"noopener noreferrer nofollow\">redb.ru<\/a>. \u041f\u0440\u043e\u0448\u043b\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u0432\u00a0<a href=\"https:\/\/habr.com\/ru\/users\/grelikt\/articles\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0444\u0438\u043b\u0435<\/a>.<\/p>\n<\/blockquote>\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\/1057616\/\">https:\/\/habr.com\/ru\/articles\/1057616\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>redb ecosystem\u0421\u0435\u0440\u0438\u044f:\u00a0redb ecosystem (\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043d\u044b\u0439 \u0430\u043d\u043e\u043d\u0441 3.3.0)  \u041a\u043e\u0433\u0434\u0430 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u00ab\u044d\u043d\u0442\u0435\u0440\u043f\u0440\u0430\u0439\u0437-\u0441\u0442\u0435\u043a \u043d\u0430 .NET\u00bb, \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u043c\u0435\u044e\u0442 \u0432 \u0432\u0438\u0434\u0443 \u0437\u043e\u043e\u043f\u0430\u0440\u043a: \u0431\u0430\u0437\u0430 \u043e\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u0435\u043d\u0434\u043e\u0440\u0430, \u0448\u0438\u043d\u0430 \u043e\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e, ORM \u0441 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0442\u043e\u0440, \u0435\u0449\u0451 \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043b\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u2014 \u0438 \u043a\u043b\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0435\u0448\u044c \u0441\u0430\u043c \u0438 \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0436\u0435 \u0447\u0438\u043d\u0438\u0448\u044c \u043f\u043e \u043d\u043e\u0447\u0430\u043c.\u041c\u044b \u043f\u043e\u0448\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0443\u0442\u0451\u043c \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u043b\u0433\u043e\u0434\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u044d\u0442\u043e \u043a\u0430\u043a\u00a0\u043e\u0434\u043d\u0443 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0443: \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u00a0redb\u00a0\u043f\u043e\u0432\u0435\u0440\u0445 Postgres\/MSSQL\/SQLite, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a\u00a0redb.Route\u00a0(\u043d\u0430\u0448 \u043e\u0442\u0432\u0435\u0442 Apache Camel \u043f\u043e\u0434 .NET) \u0438 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u00a0redb.Tsak\u00a0\u0441 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u043e\u043c, hot-reload \u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u043c. \u0422\u0440\u0438 \u0441\u043b\u043e\u044f, \u043e\u0434\u0438\u043d \u043a\u043e\u0434, \u043e\u0434\u0438\u043d \u0441\u0442\u0438\u043b\u044c.\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u044b\u0448\u043b\u0430 \u0432\u0435\u0440\u0441\u0438\u044f\u00a03.3.0\u00a0\u2014 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0431\u0430\u043c\u043f \u0432\u0441\u0435\u0439 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u043d\u0435 \u00ab\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043f\u0430\u0440\u0443 \u0444\u0438\u0447\u00bb: \u044d\u0442\u043e \u0440\u0435\u043b\u0438\u0437, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b\u00a0\u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438 \u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439\u00a0(\u0438 \u044d\u0442\u043e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0433\u043b\u0430\u0432\u043d\u043e\u0435), \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430, \u0434\u043e\u0432\u0435\u043b\u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 RAG-\u043f\u0435\u0442\u043b\u044e \u0434\u043b\u044f LLM \u0438 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435. \u041d\u0438\u0436\u0435 \u2014 \u043f\u043e \u0434\u0435\u043b\u0443, \u0441 \u043a\u043e\u0434\u043e\u043c.\u0418 \u0441\u0440\u0430\u0437\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0435: \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 3.3.0 \u0432\u0441\u0435 Pro-\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0439, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439, \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u0448\u044c \u043f\u0430\u043a\u0435\u0442 \u0438 \u044e\u0437\u0430\u0435\u0448\u044c.\u00a0Change tracking, bulk, \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u043a\u044d\u0448, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430, \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Tsak \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u0438 failover \u2014 \u0432\u0441\u0451 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0432 \u043f\u0440\u043e\u0434\u0435 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.\u00a0dotnet add package redb.Postgres.Pro\u00a0\u2014 \u0438 \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0435\u0439\u0432\u043e\u043b\u043b\u0430, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0438\u0447\u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e.\u0426\u0438\u043a\u043b \u043f\u0440\u043e redb \u0438 redb.Route.\u00a0\u042d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0438\u0438, \u0441\u0432\u0435\u0436\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u0441\u0432\u0435\u0440\u0445\u0443:redb.Route \u2014 \u0443\u0445\u043e\u0434\u0438\u043c \u043e\u0442 MassTransit, \u0438\u0434\u0451\u043c \u043a Apache Camel: Kafka, Scatter\u2011Gather \u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438Apache Camel \u043f\u043e\u0434 .NET: HTTP-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0431\u0435\u0437 ASP.NET MVC + Content-Based Routerredb.Route \u2014 Apache Camel \u0434\u043b\u044f .NET, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043d\u0435 \u0431\u044b\u043b\u043eredb \u2014 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f .NET \u043f\u043e\u0432\u0435\u0440\u0445 Postgres\/MSSQL: \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439, \u0431\u0435\u0437 Include, \u0441 \u043f\u043e\u043b\u043d\u044b\u043c LINQ\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u2014 \u0432\u00a0\u043f\u0440\u043e\u0444\u0438\u043b\u0435. \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438:\u00a0github.com\/redbase-app. \u041f\u0440\u043e \u0441\u0430\u043c\u0443 \u0411\u0414:\u00a0redb.ru.\u041a\u043e\u0440\u043e\u0442\u043a\u043e, \u0447\u0442\u043e \u0437\u0430 \u0442\u0440\u0438 \u0441\u043b\u043e\u044f\u0427\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0442\u043e:redb\u00a0\u2014 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f .NET. \u041f\u0438\u0448\u0435\u0448\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 POCO-\u043a\u043b\u0430\u0441\u0441, \u0432\u0435\u0448\u0430\u0435\u0448\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u2014 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u0441 \u043d\u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u043d\u044b\u0439 LINQ, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437\u00a0Include. \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b: Postgres, MSSQL, SQLite. \u0415\u0441\u0442\u044c Free \u0438 Pro (change tracking, bulk, \u043a\u044d\u0448, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430).redb.Route\u00a0\u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0432 \u0434\u0443\u0445\u0435 Apache Camel: DSL \u0438\u0437 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 (From(&#8230;).\u2026\u200b.To(&#8230;)), 30+ \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (Kafka, RabbitMQ, HTTP, gRPC, S3, LLM \u0438 \u0442.\u0434.), \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 (EIP), \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f. \u0422\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u00ab\u043a\u043b\u0435\u0439\u00bb, \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435, \u0430 \u0441 \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438.redb.Tsak\u00a0\u2014 \u0440\u0430\u043d\u0442\u0430\u0439\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0435\u0440\u0451\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b redb.Route \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043f\u0440\u043e\u0434-\u0441\u0435\u0440\u0432\u0438\u0441: \u0434\u0430\u0448\u0431\u043e\u0440\u0434, hot-reload \u043c\u043e\u0434\u0443\u043b\u0435\u0439 (.tpkg), \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438, \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c \u0438 failover. \u041f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f NuGet-\u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438, Docker-\u043e\u0431\u0440\u0430\u0437\u0430\u043c\u0438 \u0438 standalone-\u0430\u0440\u0445\u0438\u0432\u0430\u043c\u0438.\u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u2014 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u0432\u0435\u0441\u044c \u0442\u0435\u043a\u0441\u0442 \u2014 \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438. \u0412\u0441\u0451 \u043b\u0435\u0436\u0438\u0442 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c.\u0427\u0442\u043e\u0431\u044b \u043d\u0438\u0436\u043d\u0438\u0439 \u0441\u043b\u043e\u0439 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u043b\u043e\u0432\u0430\u0445 \u2014 \u0432\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 redb \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 LINQ \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u0431\u0435\u0437 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437\u00a0Include:[RedbScheme]public class Note{    public string Tag  { get; set; } = &#171;&#187;;    public string Text { get; set; } = &#171;&#187;;}\/\/ \u0437\u0430\u043f\u0438\u0441\u044cawait redb.SaveAsync(new RedbObject&lt;Note&gt; { Props = new() { Tag = &#171;work&#187;, Text = &#171;hello&#187; } });\/\/ \u0447\u0442\u0435\u043d\u0438\u0435 \u2014 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043a\u043e\u0434\u0430, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e Include\/JOIN \u0440\u0443\u043a\u0430\u043c\u0438var notes = await redb.Query&lt;Note&gt;()    .Where(n =&gt; n.Tag == &#171;work&#187;)    .ToListAsync();\u0421\u0445\u0435\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u00a0SyncSchemeAsync&lt;Note&gt;()\u00a0\u2014 \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0431\u0435\u0437 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0441\u043b\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442 \u0438 \u0447\u0430\u043d\u043a\u0438 \u0431\u0430\u0437\u044b \u0437\u043d\u0430\u043d\u0438\u0439 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435, \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u0430\u0448\u0435\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 \u2014 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.redb.Route: \u0447\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e\u041d\u0430\u0447\u043d\u0443 \u0441 \u0434\u0432\u0438\u0436\u043a\u0430 \u2014 \u0437\u0434\u0435\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044f\u0441\u0430.\u0414\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430: Amazon SQS\/SNS \u0438 Telegramredb.Route.Sqs\u00a0\u2014 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u0442\u043e\u043f\u0438\u043a AWS \u0432 \u043e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442\u041e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442, \u0434\u0432\u0435 \u0441\u0445\u0435\u043c\u044b:\u00a0sqs:\/\/\u00a0(\u043e\u0447\u0435\u0440\u0435\u0434\u044c: \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 + \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440) \u0438\u00a0sns:\/\/\u00a0(\u0442\u043e\u043f\u0438\u043a: publisher + fan-out SNS\u2192SQS). \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u2014 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 AWS SDK for .NET v4, \u043d\u0435 \u0441\u0430\u043c\u043e\u043f\u0430\u043b.using redb.Route.Sqs.Fluent;\/\/ \u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440: 5 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, long-poll, at-least-once (delete on success \u2014 ack \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439)From(Sqs.Queue(&#171;orders&#187;).WaitTimeSeconds(20).ConcurrentConsumers(5))    .Process(ex =&gt; Handle(ex.In.Body));\/\/ \u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 SNS-\u0442\u043e\u043f\u0438\u043a (fan-out \u0432 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438)From(&#171;timer:\/\/tick?period=5000&#187;)    .SetBody(_ =&gt; BuildEvent())    .To(Sns.Topic(&#171;order-events&#187;));\u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u0443\u043c\u0435\u0435\u0442 long-polling,\u00a0ConcurrentConsumers(N)\u00a0(\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0446\u0438\u043a\u043b\u044b), visibility timeout \u0441 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0434\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0439 ack \u0447\u0435\u0440\u0435\u0437\u00a0.Transacted()\u00a0\u0438 FIFO. \u041f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u2014 \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u0430\u044f \u0438 \u0431\u0430\u0442\u0447-\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430, FIFO group\/dedup id. SNS-publisher \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 subject, message structure, FIFO \u0438 \u0430\u0432\u0442\u043e-\u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 SNS\u2192SQS. \u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e \u0441 LocalStack \/ ElasticMQ \u0447\u0435\u0440\u0435\u0437\u00a0serviceUrl=, \u043f\u043e\u043b\u043d\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 AWS-\u043a\u0440\u0435\u0434\u0435\u043d\u0448\u0435\u043b\u043e\u0432, W3C trace-context \u043f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0445\u043e\u0434. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u2014 \u0432\u00a0redb.Route.Sqs\/README.md.redb.Route.Telegram\u00a0\u2014 \u0431\u043e\u0442 \u043a\u0430\u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0421\u0445\u0435\u043c\u0430\u00a0telegram:\/\/, \u043f\u043e\u0432\u0435\u0440\u0445\u00a0Telegram.Bot. \u041a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u2014 long-polling (receive, \u043e\u0434\u0438\u043d\u00a0getUpdates-\u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u0442\u043e\u043a\u0435\u043d), \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 \u2014 \u0440\u0435\u0436\u0438\u043c\u044b\u00a0send\u00a0\/\u00a0document\u00a0\/\u00a0photo\u00a0\/\u00a0edit\u00a0\/\u00a0delete\u00a0\/\u00a0answer.\/\/ \u042d\u0445\u043e-\u0431\u043e\u0442: \u043f\u0440\u0438\u043d\u044f\u043b \u0430\u043f\u0434\u0435\u0439\u0442, \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u0432 \u0442\u043e\u0442 \u0436\u0435 \u0447\u0430\u0442From(Tg.Receive(token))    .Process(ex =&gt; ex.Out.Body = $&#187;\u0412\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438: {ex.In.Body}&#187;)    .To(Tg.Send(token).ChatId(Header(TelegramHeaders.ChatId)));\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 429\u00a0retry_after\u00a0(\u0436\u0434\u0451\u0442 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442, \u0430 \u043d\u0435 \u0440\u043e\u043d\u044f\u0435\u0442), \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f\u00a0parseMode\u00a0(\u043a\u0438\u0434\u0430\u0435\u0442 \u043d\u0430 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0435, \u0430 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u044b\u0440\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043c\u043e\u043b\u0447\u0430), inline\/reply-\u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b (WithInlineKeyboard\u00a0\/\u00a0WithReplyKeyboard), pipeline \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u0432\u0435\u0431\u0445\u0443\u043a\u0430 (UnpackTelegramUpdate) \u0438 fluent-DSL (Tg.Receive\/Send\/Document\/&#8230;). \u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u2014\u00a0at-most-once\u00a0(Telegram \u0434\u0432\u0438\u0433\u0430\u0435\u0442 offset \u043f\u0440\u0438 \u0432\u044b\u0434\u0430\u0447\u0435 \u0430\u043f\u0434\u0435\u0439\u0442\u0430, \u044d\u0442\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e), \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c \u2014 \u0447\u0435\u0440\u0435\u0437\u00a0.Threads(N)\u00a0(\u0441\u043c. \u043d\u0438\u0436\u0435), \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0438 \u0441\u043f\u0430\u043d\u044b \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430.\u0414\u0432\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445, \u0436\u0438\u0432\u044b\u0445 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430 \u2014 SQS \u0434\u043b\u044f AWS-\u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 Telegram \u0434\u043b\u044f ChatOps\/\u0431\u043e\u0442\u043e\u0432. \u041e\u0431\u0430 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u0440\u043e\u0442\u0438\u0432 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u0432 (LocalStack \u0438 \u043c\u043e\u043a-\u0441\u0435\u0440\u0432\u0435\u0440).RAG \u043f\u043e\u0434 \u043a\u043b\u044e\u0447:\u00a0knowledge:\/\/,\u00a0embed:\/\/\u00a0\u0438\u00a0.Knowledge()\u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u0443\u00a0redb.Route.Llm\u00a0\u0443\u0436\u0435 \u0431\u044b\u043b \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 OpenAI-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Anthropic. \u0412 3.3.0 \u043c\u044b\u00a0\u0437\u0430\u043c\u043a\u043d\u0443\u043b\u0438 RAG-\u043f\u0435\u0442\u043b\u044e\u00a0\u2014 \u043e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043e \u043e\u0442\u0432\u0435\u0442\u0430, \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043d\u0438\u0445, \u0432\u0441\u0451 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432.\u0427\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c:knowledge:\/\/\u00a0(ingest-\u0441\u0445\u0435\u043c\u0430)\u00a0\u2014 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0435\u0440\u0451\u0442 \u0442\u0435\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u0440\u0435\u0436\u0435\u0442 \u043d\u0430 \u0447\u0430\u043d\u043a\u0438 (\u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u043a\u043d\u0430 \u043f\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c \u0441 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u0435\u043c), \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438\u00a0IEmbeddingProvider\u00a0\u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0438 \u0430\u043f\u0441\u0435\u0440\u0442\u0438\u0442 \u0432\u00a0IKnowledgeStore. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c:From(&#171;file:\/\/docs?include=*.md&#187;).To(&#171;knowledge:\/\/handbook&#187;);Id \u0447\u0430\u043d\u043a\u043e\u0432 \u2014\u00a0{docId}#{index}, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0433\u043e \u0436\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0438 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435.embed:\/\/\u00a0(\u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u043a\u0430\u043a \u0448\u0430\u0433)\u00a0\u2014 \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u043e\u00a0llm:\/\/:\u00a0To(&#171;embed:\/\/openai&#187;)\u00a0\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 (\u0438\u043b\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f) \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u0430\u00a0Out.Body. \u0425\u043e\u0441\u0442 URI \u2014 \u0438\u043c\u044f \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u043f\u043e \u0438\u043c\u0435\u043d\u0438..Knowledge(collection, k)\u00a0(retrieval-DSL)\u00a0\u2014 \u0448\u0430\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0430\u0451\u0442 \u0442\u043e\u043f-K \u0447\u0430\u043d\u043a\u043e\u0432 \u043f\u043e\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u00a0\u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u043f\u0442, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439\u00a0.To(&#171;llm:\/\/\u2026&#187;)\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u043b, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043d\u0438\u0445:From(&#171;kafka:\/\/questions&#187;)    .Knowledge(&#171;handbook&#187;, k: 5)    .To(&#171;llm:\/\/claude&#187;);\u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c\u00a0IEmbeddingProvider\u00a0(\u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u2192 \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u00a0SearchAsync), \u0438\u043d\u0430\u0447\u0435 \u2014 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043f\u043e\u0438\u0441\u043a (SearchTextAsync, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439\u00a0LIKE\u00a0\u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043e\u043d\u043a\u0435). \u0415\u0441\u043b\u0438 \u0441\u0442\u043e\u0440 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d \u0438\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c \u2014 \u0448\u0430\u0433 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438 \u043d\u0435 \u043b\u043e\u043c\u0430\u0435\u0442 pipeline.knowledge_search\u00a0(\u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442)\u00a0\u2014\u00a0.AsLlmTool-\u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0430\u0434 \u043f\u043e\u0438\u0441\u043a\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0430\u0433\u0435\u043d\u0442 \u0441\u0430\u043c \u0445\u043e\u0434\u0438\u043b \u0432 \u0431\u0430\u0437\u0443 \u0437\u043d\u0430\u043d\u0438\u0439: \u0432\u0445\u043e\u0434\u00a0{query, top_k?, collection?}\u00a0\u2192\u00a0{results:[\u2026]}.\u00a0collection\u00a0\u043c\u043e\u0436\u043d\u043e\u00a0\u0437\u0430\u043f\u0438\u043d\u0438\u0442\u044c, \u0442\u043e\u0433\u0434\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u2014 \u0442\u0430\u043a \u0430\u0433\u0435\u043d\u0442 \u0437\u0430\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0442\u0435\u043d\u0430\u043d\u0442\u0435 \/ \u043d\u0430\u0431\u043e\u0440\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432.\u041f\u043e\u043b\u043d\u0430\u044f \u043f\u0435\u0442\u043b\u044f:\u00a0knowledge:\/\/\u00a0ingest \u2192 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u2192 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439\/\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u0438\u0441\u043a \u2192 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00a0knowledge_search\u00a0\u0438\u043b\u0438 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f\u00a0.Knowledge(). \u0411\u0435\u0437 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0441\u0442\u043e\u0440\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d: \u0447\u0430\u043d\u043a\u0438 \u043b\u0435\u0436\u0430\u0442 \u0432 redb, \u043f\u043e\u0438\u0441\u043a \u0438\u0434\u0451\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c.\u0417\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u0443\u044e \u0432\u0435\u0449\u044c: \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e JSON-\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 LLM-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u044d\u043d\u043a\u043e\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0435-ASCII \u0441\u0438\u043c\u0432\u043e\u043b \u0432\u00a0\\uXXXX. \u041d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u044d\u0442\u043e \u0440\u0430\u0437\u0434\u0443\u0432\u0430\u043b\u043e \u0447\u0438\u0441\u043b\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u044b\/CJK \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 6 \u0440\u0430\u0437 (\u0438 \u043c\u043e\u0433\u043b\u043e \u0432\u0441\u043f\u043b\u044b\u0442\u044c \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044c\u043d\u044b\u043c\u0438\u00a0\\u\u2026\u00a0\u0432 \u0442\u0435\u043a\u0441\u0442\u0435), \u0430 \u0432 \u0431\u0430\u0437\u0435 \u0437\u043d\u0430\u043d\u0438\u0439 \u0445\u043e\u0440\u043e\u043d\u0438\u043b\u043e \u0442\u0435\u043a\u0441\u0442 \u0447\u0430\u043d\u043a\u0430 \u0442\u0430\u043a, \u0447\u0442\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439\u00a0LIKE\u00a0\u043d\u0435 \u043c\u043e\u0433 \u043d\u0430\u0439\u0442\u0438 \u0441\u044b\u0440\u043e\u0439 \u043d\u0435-ASCII \u0437\u0430\u043f\u0440\u043e\u0441. \u041f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u043d\u0430\u00a0UnsafeRelaxedJsonEscaping\u00a0\u0432\u0435\u0437\u0434\u0435, \u0433\u0434\u0435 \u043d\u0430\u0434\u043e (AgentEngine,\u00a0OpenAiProvider,\u00a0McpProtocol, \u043a\u043e\u043d\u0432\u0435\u0440\u0442 \u0447\u0430\u043d\u043a\u0430). \u0414\u043b\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u044d\u0442\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u043e \u0438 \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c, \u0438 \u043f\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0443..Threads(N)\u00a0\u2014 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435\u041f\u043e\u044f\u0432\u0438\u043b\u0441\u044f Camel-style \u0448\u0430\u0433 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438-\u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438:\u00a0From(&#8230;).Threads(N)\u2026EndThreads()\u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0447\u0438\u0441\u043b\u043e\u043c N. \u0421\u043c\u044b\u0441\u043b: \u0434\u0430\u0436\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a (poll-\u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440, MQTT, \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0439 HTTP-\u043f\u043e\u0442\u043e\u043a) \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043e N \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u2014 \u0431\u0435\u0437 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430\u00a0seda:\/\/.From(&#171;mqtt:\/\/sensors&#187;)          \/\/ \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u043e \u043f\u0440\u0438\u0440\u043e\u0434\u0435 \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u0439    .Threads(8)                 \/\/ \u0434\u043e 8 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e        .Process(ex =&gt; HeavyWork(ex))    .EndThreads();\u0412\u0430\u0436\u043d\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u2014 \u0448\u0430\u0433\u00a0\u0430\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 \u043e\u0431\u043c\u0435\u043d\u0430. \u0414\u043b\u044f InOnly (fire-and-forget) \u044d\u0442\u043e hand-off: \u043a\u043b\u043e\u043d + \u043f\u0443\u043b \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u0433\u0440\u0430\u043d\u0438\u0446\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 (\u043a\u0430\u043a\u00a0.To(&#171;seda:\/\/&#187;)). \u0414\u043b\u044f InOut \u0442\u0435\u043b\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f\u00a0inline \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 exchange \u043f\u043e\u0434\u00a0SemaphoreSlim-\u0433\u0435\u0439\u0442\u043e\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442 (\u043d\u0430\u00a0Out\u00a0\u0438\u043b\u0438\u00a0In) \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u044c, request\/reply (RPC) \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 \u0448\u0430\u0433, \u0438 \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0442\u0435\u043a\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u044c. \u0415\u0441\u0442\u044c\u00a0.MaxQueueSize(n)\u00a0\u0438\u00a0.EnqueueTimeout(TimeSpan). \u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u0438 N &gt; 1 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u2014 \u044d\u0442\u043e \u0446\u0435\u043d\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430, \u0438 \u043e\u043d\u0430 \u0447\u0435\u0441\u0442\u043d\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430.\u0413\u043b\u0430\u0432\u043d\u043e\u0435:\u00a0ConcurrentConsumers(N)\u00a0\u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0410 \u0432\u043e\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u2014 \u0441\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435 \u0438 \u0441\u0430\u043c\u043e\u0435 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u0438 \u043f\u043e\u0447\u0438\u043d\u0438\u043b\u0438. \u0414\u0435\u0440\u0436\u0438\u0442\u0435\u0441\u044c.ConcurrentConsumers(N)\u00a0\u043d\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\u0445 \u043c\u043e\u043b\u0447\u0430 \u043d\u0435 \u0434\u0430\u0432\u0430\u043b \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430.\u00a0\u041e\u043f\u0446\u0438\u044f \u0431\u044b\u043b\u0430, \u0432 \u043d\u0435\u0451 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u0438 \u0447\u0438\u0441\u043b\u043e, \u043e\u043d\u043e \u0434\u0430\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044f\u043b\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439\u00a0SemaphoreSlim\u00a0\u2014 \u043d\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u043e. \u041f\u0440\u0438\u0447\u0438\u043d\u044b \u0431\u044b\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430\u0445, \u0430 \u0441\u0438\u043c\u043f\u0442\u043e\u043c \u043e\u0434\u0438\u043d: \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440&#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-486791","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/486791","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=486791"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/486791\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=486791"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=486791"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=486791"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}