[{"data":1,"prerenderedAt":15934},["ShallowReactive",2],{"navigation":3,"/microservices-with-django/orchestrating-celery-rabbitmq":1016,"/microservices-with-django/orchestrating-celery-rabbitmq-surround":15929},[4,54,89,123,165,211,253,331,389,439,462,488,514,540,578,624,650,672,702,736,774,800,850,856,862,868,874,928],{"title":5,"path":6,"stem":7,"children":8},"Introduction and Foundations","/introduction-and-foundations","01.introduction-and-foundations/01.index",[9,10,14,18,22,26,30,34,38,42,46,50],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"What is Django","/introduction-and-foundations/what-is-django","01.introduction-and-foundations/02.what-is-django",{"title":15,"path":16,"stem":17},"Key Concepts and Philosophy","/introduction-and-foundations/key-concepts-and-philosophy","01.introduction-and-foundations/03.key-concepts-and-philosophy",{"title":19,"path":20,"stem":21},"MVC vs MVT: Understanding Django's Architecture","/introduction-and-foundations/mvc-vs-mvt","01.introduction-and-foundations/04.mvc-vs-mvt",{"title":23,"path":24,"stem":25},"Project Structure Overview","/introduction-and-foundations/project-structure-overview","01.introduction-and-foundations/05.project-structure-overview",{"title":27,"path":28,"stem":29},"Installing Django","/introduction-and-foundations/installing-django","01.introduction-and-foundations/06.installing-django",{"title":31,"path":32,"stem":33},"Creating Your First Django Project","/introduction-and-foundations/creating-first-project","01.introduction-and-foundations/07.creating-first-project",{"title":35,"path":36,"stem":37},"Creating Your First Django App","/introduction-and-foundations/creating-first-app","01.introduction-and-foundations/08.creating-first-app",{"title":39,"path":40,"stem":41},"Your First Django \"Hello World\"","/introduction-and-foundations/hello-world","01.introduction-and-foundations/09.hello-world",{"title":43,"path":44,"stem":45},"Django Quick Start Guide","/introduction-and-foundations/quick-start-guide","01.introduction-and-foundations/10.quick-start-guide",{"title":47,"path":48,"stem":49},"How Django Handles Requests","/introduction-and-foundations/how-django-handles-requests","01.introduction-and-foundations/11.how-django-handles-requests",{"title":51,"path":52,"stem":53},"Django Settings","/introduction-and-foundations/django-settings","01.introduction-and-foundations/12.django-settings",{"title":55,"path":56,"stem":57,"children":58},"The Development Environment","/development-environment","02.development-environment/1.index",[59,61,65,69,73,77,81,85],{"title":60,"path":56,"stem":57},"Development Environment",{"title":62,"path":63,"stem":64},"Recommended Tooling for Django Development","/development-environment/recommended-tooling","02.development-environment/2.recommended-tooling",{"title":66,"path":67,"stem":68},"Virtual Environments","/development-environment/virtual-environments","02.development-environment/3.virtual-environments",{"title":70,"path":71,"stem":72},"Django Admin and Management Commands","/development-environment/admin-and-management-commands","02.development-environment/4.admin-and-management-commands",{"title":74,"path":75,"stem":76},"Django Project Settings","/development-environment/project-settings","02.development-environment/5.project-settings",{"title":78,"path":79,"stem":80},"Managing Django Environments: Local, Staging, and Production","/development-environment/environments-local-staging-production","02.development-environment/6.environments-local-staging-production",{"title":82,"path":83,"stem":84},"Running Django Development Server","/development-environment/running-development-server","02.development-environment/7.running-development-server",{"title":86,"path":87,"stem":88},"Working with Django Shell","/development-environment/working-with-shell","02.development-environment/8.working-with-shell",{"title":90,"path":91,"stem":92,"children":93},"Templates and Presentation Layer","/templates-and-presentation","03.templates-and-presentation/1.index",[94,95,99,103,107,111,115,119],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Introduction to Django Templates","/templates-and-presentation/introduction-to-templates","03.templates-and-presentation/2.introduction-to-templates",{"title":100,"path":101,"stem":102},"The Django Template Language","/templates-and-presentation/django-template-language","03.templates-and-presentation/3.django-template-language",{"title":104,"path":105,"stem":106},"Template Inheritance","/templates-and-presentation/template-inheritance","03.templates-and-presentation/4.template-inheritance",{"title":108,"path":109,"stem":110},"Built-in Template Tags and Filters","/templates-and-presentation/built-in-template-tags-and-filters","03.templates-and-presentation/5.built-in-template-tags-and-filters",{"title":112,"path":113,"stem":114},"Including Static Files","/templates-and-presentation/including-static-files","03.templates-and-presentation/6.including-static-files",{"title":116,"path":117,"stem":118},"Working with Media Files","/templates-and-presentation/working-with-media-files","03.templates-and-presentation/7.working-with-media-files",{"title":120,"path":121,"stem":122},"Using Alternative Template Engines","/templates-and-presentation/using-alternative-template-engines","03.templates-and-presentation/8.using-alternative-template-engines",{"title":124,"path":125,"stem":126,"children":127},"URLs and Views","/urls-and-views","04.urls-and-views/01.index",[128,129,133,137,141,145,149,153,157,161],{"title":124,"path":125,"stem":126},{"title":130,"path":131,"stem":132},"The URL Dispatcher","/urls-and-views/the-url-dispatcher","04.urls-and-views/02.the-url-dispatcher",{"title":134,"path":135,"stem":136},"Writing Function-Based Views","/urls-and-views/writing-function-based-views","04.urls-and-views/03.writing-function-based-views",{"title":138,"path":139,"stem":140},"View Decorators","/urls-and-views/view-decorators","04.urls-and-views/04.view-decorators",{"title":142,"path":143,"stem":144},"Rendering Responses","/urls-and-views/rendering-responses","04.urls-and-views/05.rendering-responses",{"title":146,"path":147,"stem":148},"Redirects","/urls-and-views/redirects","04.urls-and-views/06.redirects",{"title":150,"path":151,"stem":152},"Handling HTTP Methods","/urls-and-views/handling-http-methods","04.urls-and-views/07.handling-http-methods",{"title":154,"path":155,"stem":156},"Conditional View Processing","/urls-and-views/conditional-view-processing","04.urls-and-views/08.conditional-view-processing",{"title":158,"path":159,"stem":160},"File Uploads","/urls-and-views/file-uploads","04.urls-and-views/09.file-uploads",{"title":162,"path":163,"stem":164},"Using Django Shortcut Functions","/urls-and-views/using-django-shortcut-functions","04.urls-and-views/10.using-django-shortcut-functions",{"title":166,"path":167,"stem":168,"children":169},"Class Based Views","/class-based-views","05.class-based-views/01.index",[170,171,175,179,183,187,191,195,199,203,207],{"title":166,"path":167,"stem":168},{"title":172,"path":173,"stem":174},"Introduction to Class-Based Views","/class-based-views/introduction-to-class-based-views","05.class-based-views/02.introduction-to-class-based-views",{"title":176,"path":177,"stem":178},"Common Base Classes","/class-based-views/common-base-classes","05.class-based-views/03.common-base-classes",{"title":180,"path":181,"stem":182},"Built-in Generic Views","/class-based-views/built-in-generic-views","05.class-based-views/04.built-in-generic-views",{"title":184,"path":185,"stem":186},"Views for CRUD Operations","/class-based-views/views-for-crud-operations","05.class-based-views/05.views-for-crud-operations",{"title":188,"path":189,"stem":190},"Handling Forms with Class-Based Views","/class-based-views/handling-forms-with-class-based-views","05.class-based-views/06.handling-forms-with-class-based-views",{"title":192,"path":193,"stem":194},"Using Mixins","/class-based-views/using-mixins","05.class-based-views/07.using-mixins",{"title":196,"path":197,"stem":198},"URL Configuration with Class-Based Views","/class-based-views/url-configuration-with-class-based-views","05.class-based-views/08.url-configuration-with-class-based-views",{"title":200,"path":201,"stem":202},"Subclassing Generic Views","/class-based-views/subclassing-generic-views","05.class-based-views/09.subclassing-generic-views",{"title":204,"path":205,"stem":206},"Asynchronous Class-Based Views","/class-based-views/asynchronous-class-based-views","05.class-based-views/10.asynchronous-class-based-views",{"title":208,"path":209,"stem":210},"Pagination","/class-based-views/pagination","05.class-based-views/11.pagination",{"title":212,"path":213,"stem":214,"children":215},"Forms and User Input","/forms-and-user-input","06.forms-and-user-input/01.index",[216,217,221,225,229,233,237,241,245,249],{"title":212,"path":213,"stem":214},{"title":218,"path":219,"stem":220},"Understanding HTML Forms","/forms-and-user-input/understanding-html-forms","06.forms-and-user-input/02.understanding-html-forms",{"title":222,"path":223,"stem":224},"Django's Role in Form Handling","/forms-and-user-input/djangos-role-in-form-handling","06.forms-and-user-input/03.djangos-role-in-form-handling",{"title":226,"path":227,"stem":228},"Creating Forms with Forms API","/forms-and-user-input/creating-forms-with-forms-api","06.forms-and-user-input/04.creating-forms-with-forms-api",{"title":230,"path":231,"stem":232},"Form Validation","/forms-and-user-input/form-validation","06.forms-and-user-input/05.form-validation",{"title":234,"path":235,"stem":236},"Built-in Fields and Widgets","/forms-and-user-input/built-in-fields-and-widgets","06.forms-and-user-input/06.built-in-fields-and-widgets",{"title":238,"path":239,"stem":240},"Form Rendering in Templates","/forms-and-user-input/form-rendering-in-templates","06.forms-and-user-input/07.form-rendering-in-templates",{"title":242,"path":243,"stem":244},"Model Forms","/forms-and-user-input/model-forms","06.forms-and-user-input/08.model-forms",{"title":246,"path":247,"stem":248},"Advanced Form Techniques","/forms-and-user-input/advanced-form-techniques","06.forms-and-user-input/09.advanced-form-techniques",{"title":250,"path":251,"stem":252},"Security Considerations for Forms","/forms-and-user-input/security-considerations-for-forms","06.forms-and-user-input/10.security-considerations-for-forms",{"title":254,"path":255,"stem":256,"children":257},"Models and Databases","/models-and-databases","07.models-and-databases/01.index",[258,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327],{"title":254,"path":255,"stem":256},{"title":260,"path":261,"stem":262},"Understanding Django Models","/models-and-databases/understanding-django-models","07.models-and-databases/02.understanding-django-models",{"title":264,"path":265,"stem":266},"Defining Fields","/models-and-databases/defining-fields","07.models-and-databases/03.defining-fields",{"title":268,"path":269,"stem":270},"Relationships and Foreign Keys","/models-and-databases/relationships-and-foreign-keys","07.models-and-databases/04.relationships-and-foreign-keys",{"title":272,"path":273,"stem":274},"Examples of Relationship Patterns","/models-and-databases/examples-of-relationship-patterns","07.models-and-databases/05.examples-of-relationship-patterns",{"title":276,"path":277,"stem":278},"Making Queries","/models-and-databases/making-queries","07.models-and-databases/06.making-queries",{"title":280,"path":281,"stem":282},"Filtering, Ordering, and Slicing","/models-and-databases/filtering-ordering-slicing","07.models-and-databases/07.filtering-ordering-slicing",{"title":284,"path":285,"stem":286},"Managers and QuerySets","/models-and-databases/managers-and-querysets","07.models-and-databases/08.managers-and-querysets",{"title":288,"path":289,"stem":290},"Aggregation","/models-and-databases/aggregation","07.models-and-databases/09.aggregation",{"title":292,"path":293,"stem":294},"Search","/models-and-databases/search","07.models-and-databases/10.search",{"title":296,"path":297,"stem":298},"Raw SQL Queries","/models-and-databases/raw-sql-queries","07.models-and-databases/11.raw-sql-queries",{"title":300,"path":301,"stem":302},"Transactions","/models-and-databases/transactions","07.models-and-databases/12.transactions",{"title":304,"path":305,"stem":306},"Multiple Databases","/models-and-databases/multiple-databases","07.models-and-databases/13.multiple-databases",{"title":308,"path":309,"stem":310},"Tablespaces","/models-and-databases/tablespaces","07.models-and-databases/14.tablespaces",{"title":312,"path":313,"stem":314},"Composite Primary Keys","/models-and-databases/composite-primary-keys","07.models-and-databases/15.composite-primary-keys",{"title":316,"path":317,"stem":318},"Database Instrumentation","/models-and-databases/database-instrumentation","07.models-and-databases/16.database-instrumentation",{"title":320,"path":321,"stem":322},"Database Optimization","/models-and-databases/database-optimization","07.models-and-databases/17.database-optimization",{"title":324,"path":325,"stem":326},"Fixtures","/models-and-databases/fixtures","07.models-and-databases/18.fixtures",{"title":328,"path":329,"stem":330},"Signals","/models-and-databases/signals","07.models-and-databases/19.signals",{"title":332,"path":333,"stem":334,"children":335},"Migrations","/migrations","08.migrations/01.index",[336,337,341,345,349,353,357,361,365,369,373,377,381,385],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"How Migrations Work","/migrations/how-migrations-work","08.migrations/02.how-migrations-work",{"title":342,"path":343,"stem":344},"Management Commands","/migrations/management-commands","08.migrations/03.management-commands",{"title":346,"path":347,"stem":348},"Dependencies and Workflow","/migrations/dependencies-and-workflow","08.migrations/04.dependencies-and-workflow",{"title":350,"path":351,"stem":352},"Transaction Handling","/migrations/transaction-handling","08.migrations/05.transaction-handling",{"title":354,"path":355,"stem":356},"Adding Migrations to Apps","/migrations/adding-migrations-to-apps","08.migrations/06.adding-migrations-to-apps",{"title":358,"path":359,"stem":360},"Reversing Migrations","/migrations/reversing-migrations","08.migrations/07.reversing-migrations",{"title":362,"path":363,"stem":364},"Historical Models","/migrations/historical-models","08.migrations/08.historical-models",{"title":366,"path":367,"stem":368},"Considerations When Removing Fields","/migrations/considerations-when-removing-fields","08.migrations/09.considerations-when-removing-fields",{"title":370,"path":371,"stem":372},"Data Migrations","/migrations/data-migrations","08.migrations/10.data-migrations",{"title":374,"path":375,"stem":376},"Squashing Migrations","/migrations/squashing-migrations","08.migrations/11.squashing-migrations",{"title":378,"path":379,"stem":380},"Serializing Values","/migrations/serializing-values","08.migrations/12.serializing-values",{"title":382,"path":383,"stem":384},"Supporting Multiple Django Versions","/migrations/supporting-multiple-django-versions","08.migrations/13.supporting-multiple-django-versions",{"title":386,"path":387,"stem":388},"Django Serialization Framework","/migrations/django-serialization-framework","08.migrations/14.django-serialization-framework",{"title":390,"path":391,"stem":392,"children":393},"Authentication and Authorization","/authentication-and-authorization","09.authentication-and-authorization/01.index",[394,395,399,403,407,411,415,419,423,427,431,435],{"title":390,"path":391,"stem":392},{"title":396,"path":397,"stem":398},"Overview of Django's Authentication System","/authentication-and-authorization/overview-of-django-authentication-system","09.authentication-and-authorization/02.overview-of-django-authentication-system",{"title":400,"path":401,"stem":402},"Users and Groups","/authentication-and-authorization/users-and-groups","09.authentication-and-authorization/03.users-and-groups",{"title":404,"path":405,"stem":406},"Permissions","/authentication-and-authorization/permissions","09.authentication-and-authorization/04.permissions",{"title":408,"path":409,"stem":410},"Password Management","/authentication-and-authorization/password-management","09.authentication-and-authorization/05.password-management",{"title":412,"path":413,"stem":414},"Authentication Views","/authentication-and-authorization/authentication-views","09.authentication-and-authorization/06.authentication-views",{"title":416,"path":417,"stem":418},"Login and Logout","/authentication-and-authorization/login-and-logout","09.authentication-and-authorization/07.login-and-logout",{"title":420,"path":421,"stem":422},"Custom User Models","/authentication-and-authorization/custom-user-models","09.authentication-and-authorization/08.custom-user-models",{"title":424,"path":425,"stem":426},"Middleware for Authentication","/authentication-and-authorization/middleware-for-authentication","09.authentication-and-authorization/09.middleware-for-authentication",{"title":428,"path":429,"stem":430},"Authorization in Views and Templates","/authentication-and-authorization/authorization-in-views-and-templates","09.authentication-and-authorization/10.authorization-in-views-and-templates",{"title":432,"path":433,"stem":434},"Integrating Social Authentication","/authentication-and-authorization/integrating-social-authentication","09.authentication-and-authorization/11.integrating-social-authentication",{"title":436,"path":437,"stem":438},"Security Best Practices","/authentication-and-authorization/security-best-practices","09.authentication-and-authorization/12.security-best-practices",{"title":440,"path":441,"stem":442,"children":443},"Sessions, Cookies, and State","/sessions-cookies-state","10.sessions-cookies-state/01.index",[444,446,450,454,458],{"title":445,"path":441,"stem":442},"Sessions, Cookies, and State Management",{"title":447,"path":448,"stem":449},"Introduction to Sessions","/sessions-cookies-state/introduction-to-sessions","10.sessions-cookies-state/02.introduction-to-sessions",{"title":451,"path":452,"stem":453},"Working with Cookies","/sessions-cookies-state/working-with-cookies","10.sessions-cookies-state/03.working-with-cookies",{"title":455,"path":456,"stem":457},"Server-Side Session Storage Options","/sessions-cookies-state/server-side-session-storage-options","10.sessions-cookies-state/04.server-side-session-storage-options",{"title":459,"path":460,"stem":461},"Session Security","/sessions-cookies-state/session-security","10.sessions-cookies-state/05.session-security",{"title":463,"path":464,"stem":465,"children":466},"Working with Files","/working-with-files","11.working-with-files/01.index",[467,468,472,476,480,484],{"title":463,"path":464,"stem":465},{"title":469,"path":470,"stem":471},"Files in Models","/working-with-files/files-in-models","11.working-with-files/02.files-in-models",{"title":473,"path":474,"stem":475},"The File Object","/working-with-files/the-file-object","11.working-with-files/03.the-file-object",{"title":477,"path":478,"stem":479},"Storage Backends","/working-with-files/storage-backends","11.working-with-files/04.storage-backends",{"title":481,"path":482,"stem":483},"Using Cloud Storage Providers","/working-with-files/using-cloud-storage-providers","11.working-with-files/05.using-cloud-storage-providers",{"title":485,"path":486,"stem":487},"Managing Media in Production","/working-with-files/managing-media-in-production","11.working-with-files/06.managing-media-in-production",{"title":489,"path":490,"stem":491,"children":492},"Admin Site","/admin-site","12.admin-site/01.index",[493,494,498,502,506,510],{"title":489,"path":490,"stem":491},{"title":495,"path":496,"stem":497},"Enabling the Admin","/admin-site/enabling-the-admin","12.admin-site/02.enabling-the-admin",{"title":499,"path":500,"stem":501},"Registering Models","/admin-site/registering-models","12.admin-site/03.registering-models",{"title":503,"path":504,"stem":505},"Customizing Admin Display","/admin-site/customizing-admin-display","12.admin-site/04.customizing-admin-display",{"title":507,"path":508,"stem":509},"Admin Actions","/admin-site/admin-actions","12.admin-site/05.admin-actions",{"title":511,"path":512,"stem":513},"Admin Security Best Practices","/admin-site/admin-security-best-practices","12.admin-site/06.admin-security-best-practices",{"title":515,"path":516,"stem":517,"children":518},"Middleware","/middleware","13.middleware/01.index",[519,520,524,528,532,536],{"title":515,"path":516,"stem":517},{"title":521,"path":522,"stem":523},"Middleware Overview","/middleware/middleware-overview","13.middleware/02.middleware-overview",{"title":525,"path":526,"stem":527},"Built-in Middleware","/middleware/built-in-middleware","13.middleware/03.built-in-middleware",{"title":529,"path":530,"stem":531},"Creating Custom Middleware","/middleware/creating-custom-middleware","13.middleware/04.creating-custom-middleware",{"title":533,"path":534,"stem":535},"Middleware Ordering","/middleware/middleware-ordering","13.middleware/05.middleware-ordering",{"title":537,"path":538,"stem":539},"Performance and Debugging","/middleware/performance-and-debugging","13.middleware/06.performance-and-debugging",{"title":541,"path":542,"stem":543,"children":544},"Security","/security","14.security/01.index",[545,546,550,554,558,562,566,570,574],{"title":541,"path":542,"stem":543},{"title":547,"path":548,"stem":549},"Django Security Philosophy","/security/django-security-philosophy","14.security/02.django-security-philosophy",{"title":551,"path":552,"stem":553},"Cross Site Request Forgery","/security/cross-site-request-forgery","14.security/03.cross-site-request-forgery",{"title":555,"path":556,"stem":557},"Cross Site Scripting","/security/cross-site-scripting","14.security/04.cross-site-scripting",{"title":559,"path":560,"stem":561},"SQL Injection Protection","/security/sql-injection-protection","14.security/05.sql-injection-protection",{"title":563,"path":564,"stem":565},"Clickjacking Protection","/security/clickjacking-protection","14.security/06.clickjacking-protection",{"title":567,"path":568,"stem":569},"HTTPS Setup and HSTS","/security/https-setup-and-hsts","14.security/07.https-setup-and-hsts",{"title":571,"path":572,"stem":573},"Password Storage and Cryptography","/security/password-storage-and-cryptography","14.security/08.password-storage-and-cryptography",{"title":575,"path":576,"stem":577},"Secure Deployment Checklist","/security/secure-deployment-checklist","14.security/09.secure-deployment-checklist",{"title":579,"path":580,"stem":581,"children":582},"Testing","/testing","15.testing/01.index",[583,584,588,592,596,600,604,608,612,616,620],{"title":579,"path":580,"stem":581},{"title":585,"path":586,"stem":587},"Introduction to Django Testing","/testing/introduction-to-django-testing","15.testing/02.introduction-to-django-testing",{"title":589,"path":590,"stem":591},"Writing and Running Tests","/testing/writing-and-running-tests","15.testing/03.writing-and-running-tests",{"title":593,"path":594,"stem":595},"Test Tools","/testing/test-tools","15.testing/04.test-tools",{"title":597,"path":598,"stem":599},"Testing Models","/testing/testing-models","15.testing/05.testing-models",{"title":601,"path":602,"stem":603},"Testing Views","/testing/testing-views","15.testing/06.testing-views",{"title":605,"path":606,"stem":607},"Testing Forms","/testing/testing-forms","15.testing/07.testing-forms",{"title":609,"path":610,"stem":611},"Testing Templates","/testing/testing-templates","15.testing/08.testing-templates",{"title":613,"path":614,"stem":615},"Testing Authentication","/testing/testing-authentication","15.testing/09.testing-authentication",{"title":617,"path":618,"stem":619},"Advanced Testing Topics","/testing/advanced-testing-topics","15.testing/10.advanced-testing-topics",{"title":621,"path":622,"stem":623},"Performance Testing","/testing/performance-testing","15.testing/11.performance-testing",{"title":625,"path":626,"stem":627,"children":628},"Static Assets and Frontend Integration","/static-assets-and-frontend-integration","16.static-assets-and-frontend-integration/01.index",[629,630,634,638,642,646],{"title":625,"path":626,"stem":627},{"title":631,"path":632,"stem":633},"Working with Static Files","/static-assets-and-frontend-integration/working-with-static-files","16.static-assets-and-frontend-integration/02.working-with-static-files",{"title":635,"path":636,"stem":637},"Integrating CSS and JavaScript","/static-assets-and-frontend-integration/integrating-css-and-javascript","16.static-assets-and-frontend-integration/03.integrating-css-and-javascript",{"title":639,"path":640,"stem":641},"Using Build Tools like Vite or Webpack","/static-assets-and-frontend-integration/using-build-tools-like-vite-or-webpack","16.static-assets-and-frontend-integration/04.using-build-tools-like-vite-or-webpack",{"title":643,"path":644,"stem":645},"Using React or Vue with Django","/static-assets-and-frontend-integration/using-react-or-vue-with-django","16.static-assets-and-frontend-integration/05.using-react-or-vue-with-django",{"title":647,"path":648,"stem":649},"Managing CORS","/static-assets-and-frontend-integration/managing-cors","16.static-assets-and-frontend-integration/06.managing-cors",{"title":651,"path":652,"stem":653,"children":654},"Internationalization and Localization","/internationalization-and-localization","17.internationalization-and-localization/01.index",[655,656,660,664,668],{"title":651,"path":652,"stem":653},{"title":657,"path":658,"stem":659},"Enabling Translation","/internationalization-and-localization/enabling-translation","17.internationalization-and-localization/02.enabling-translation",{"title":661,"path":662,"stem":663},"Translating Text in Code and Templates","/internationalization-and-localization/translating-text-in-code-and-templates","17.internationalization-and-localization/03.translating-text-in-code-and-templates",{"title":665,"path":666,"stem":667},"Timezone Support","/internationalization-and-localization/timezone-support","17.internationalization-and-localization/04.timezone-support",{"title":669,"path":670,"stem":671},"Locale Middleware","/internationalization-and-localization/locale-middleware","17.internationalization-and-localization/05.locale-middleware",{"title":673,"path":674,"stem":675,"children":676},"Caching","/caching","18.caching/01.index",[677,678,682,686,690,694,698],{"title":673,"path":674,"stem":675},{"title":679,"path":680,"stem":681},"Introduction to Caching","/caching/introduction-to-caching","18.caching/02.introduction-to-caching",{"title":683,"path":684,"stem":685},"Cache Backends","/caching/cache-backends","18.caching/03.cache-backends",{"title":687,"path":688,"stem":689},"Per View Caching","/caching/per-view-caching","18.caching/04.per-view-caching",{"title":691,"path":692,"stem":693},"Low Level Cache API","/caching/low-level-cache-api","18.caching/05.low-level-cache-api",{"title":695,"path":696,"stem":697},"Template Fragment Caching","/caching/template-fragment-caching","18.caching/06.template-fragment-caching",{"title":699,"path":700,"stem":701},"Deployment Level Caching Patterns","/caching/deployment-level-caching-patterns","18.caching/07.deployment-level-caching-patterns",{"title":703,"path":704,"stem":705,"children":706},"Asynchronous Django","/asynchronous-django","19.asynchronous-django/01.index",[707,708,712,716,720,724,728,732],{"title":703,"path":704,"stem":705},{"title":709,"path":710,"stem":711},"Introduction to ASGI","/asynchronous-django/introduction-to-asgi","19.asynchronous-django/02.introduction-to-asgi",{"title":713,"path":714,"stem":715},"Async Views","/asynchronous-django/async-views","19.asynchronous-django/03.async-views",{"title":717,"path":718,"stem":719},"Async ORM Status","/asynchronous-django/async-orm-status","19.asynchronous-django/04.async-orm-status",{"title":721,"path":722,"stem":723},"WebSockets with Channels","/asynchronous-django/websockets-with-channels","19.asynchronous-django/05.websockets-with-channels",{"title":725,"path":726,"stem":727},"Background Tasks with Celery or RQ","/asynchronous-django/background-tasks-with-celery-or-rq","19.asynchronous-django/06.background-tasks-with-celery-or-rq",{"title":729,"path":730,"stem":731},"Asynchronous Support","/asynchronous-django/asynchronous-support","19.asynchronous-django/07.asynchronous-support",{"title":733,"path":734,"stem":735},"Django's Tasks Framework","/asynchronous-django/django-tasks-framework","19.asynchronous-django/08.django-tasks-framework",{"title":737,"path":738,"stem":739,"children":740},"Deployment","/deployment","20.deployment/01.index",[741,742,746,750,754,758,762,766,770],{"title":737,"path":738,"stem":739},{"title":743,"path":744,"stem":745},"Preparing for Production","/deployment/preparing-for-production","20.deployment/02.preparing-for-production",{"title":747,"path":748,"stem":749},"Using WSGI and ASGI Servers","/deployment/using-wsgi-and-asgi-servers","20.deployment/03.using-wsgi-and-asgi-servers",{"title":751,"path":752,"stem":753},"Deploying on Linux Servers","/deployment/deploying-on-linux-servers","20.deployment/04.deploying-on-linux-servers",{"title":755,"path":756,"stem":757},"Using Docker","/deployment/using-docker","20.deployment/05.using-docker",{"title":759,"path":760,"stem":761},"Cloud Deployment Guides","/deployment/cloud-deployment-guides","20.deployment/06.cloud-deployment-guides",{"title":763,"path":764,"stem":765},"Scaling and Load Balancing","/deployment/scaling-and-load-balancing","20.deployment/07.scaling-and-load-balancing",{"title":767,"path":768,"stem":769},"Monitoring and Logging","/deployment/monitoring-and-logging","20.deployment/08.monitoring-and-logging",{"title":771,"path":772,"stem":773},"Backup Strategies","/deployment/backup-strategies","20.deployment/09.backup-strategies",{"title":775,"path":776,"stem":777,"children":778},"Performance and Optimization","/performance-and-optimization","21.performance-and-optimization/01.index",[779,780,784,788,792,796],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Query Optimization","/performance-and-optimization/query-optimization","21.performance-and-optimization/02.query-optimization",{"title":785,"path":786,"stem":787},"Template Rendering Optimization","/performance-and-optimization/template-rendering-optimization","21.performance-and-optimization/03.template-rendering-optimization",{"title":789,"path":790,"stem":791},"Using Select Related and Prefetch Related","/performance-and-optimization/using-select-related-and-prefetch-related","21.performance-and-optimization/04.using-select-related-and-prefetch-related",{"title":793,"path":794,"stem":795},"Caching Strategies","/performance-and-optimization/caching-strategies","21.performance-and-optimization/05.caching-strategies",{"title":797,"path":798,"stem":799},"Profiling Django Apps","/performance-and-optimization/profiling-django-apps","21.performance-and-optimization/06.profiling-django-apps",{"title":801,"path":802,"stem":803,"children":804},"Advanced and Expert Topics","/advanced-and-expert-topics","22.advanced-and-expert-topics/01.index",[805,806,810,814,818,822,826,830,834,838,842,846],{"title":801,"path":802,"stem":803},{"title":807,"path":808,"stem":809},"System Architecture Patterns","/advanced-and-expert-topics/system-architecture-patterns","22.advanced-and-expert-topics/02.system-architecture-patterns",{"title":811,"path":812,"stem":813},"Domain Driven Design with Django","/advanced-and-expert-topics/domain-driven-design-with-django","22.advanced-and-expert-topics/03.domain-driven-design-with-django",{"title":815,"path":816,"stem":817},"Building Large Scale Django Projects","/advanced-and-expert-topics/building-large-scale-django-projects","22.advanced-and-expert-topics/04.building-large-scale-django-projects",{"title":819,"path":820,"stem":821},"Plugin Architectures for Django Apps","/advanced-and-expert-topics/plugin-architectures-for-django-apps","22.advanced-and-expert-topics/05.plugin-architectures-for-django-apps",{"title":823,"path":824,"stem":825},"Extending Django's Core","/advanced-and-expert-topics/extending-djangos-core","22.advanced-and-expert-topics/06.extending-djangos-core",{"title":827,"path":828,"stem":829},"Custom ORM Expressions","/advanced-and-expert-topics/custom-orm-expressions","22.advanced-and-expert-topics/07.custom-orm-expressions",{"title":831,"path":832,"stem":833},"Custom Management Commands","/advanced-and-expert-topics/custom-management-commands","22.advanced-and-expert-topics/08.custom-management-commands",{"title":835,"path":836,"stem":837},"Working with Signals","/advanced-and-expert-topics/working-with-signals","22.advanced-and-expert-topics/09.working-with-signals",{"title":839,"path":840,"stem":841},"Building Reusable Django Packages","/advanced-and-expert-topics/building-reusable-django-packages","22.advanced-and-expert-topics/10.building-reusable-django-packages",{"title":843,"path":844,"stem":845},"Integrating Microservices","/advanced-and-expert-topics/integrating-microservices","22.advanced-and-expert-topics/11.integrating-microservices",{"title":847,"path":848,"stem":849},"Advanced Security Hardening","/advanced-and-expert-topics/advanced-security-hardening","22.advanced-and-expert-topics/12.advanced-security-hardening",{"title":851,"path":852,"stem":853,"children":854},"Logging in Django","/logging-in-django","23.logging-in-django/01.index",[855],{"title":851,"path":852,"stem":853},{"title":857,"path":858,"stem":859,"children":860},"FAQ and Troubleshooting","/faq-and-troubleshooting","24.faq-and-troubleshooting/01.index",[861],{"title":857,"path":858,"stem":859},{"title":863,"path":864,"stem":865,"children":866},"External Packages and Ecosystem","/external-packages-and-ecosystem","25.external-packages-and-ecosystem/01.index",[867],{"title":863,"path":864,"stem":865},{"title":869,"path":870,"stem":871,"children":872},"Django Internals and Contributing","/django-internals-and-contributing","26.django-internals-and-contributing/01.index",[873],{"title":869,"path":870,"stem":871},{"title":875,"path":876,"stem":877,"children":878},"Microservices with Django","/microservices-with-django","27.microservices-with-django/01.index",[879,880,884,888,892,896,900,904,908,912,916,920,924],{"title":875,"path":876,"stem":877},{"title":881,"path":882,"stem":883},"What Is a Microservice?","/microservices-with-django/what-is-a-microservice","27.microservices-with-django/02.what-is-a-microservice",{"title":885,"path":886,"stem":887},"Introducing the Django Microservices Architecture","/microservices-with-django/django-microservices-architecture","27.microservices-with-django/03.django-microservices-architecture",{"title":889,"path":890,"stem":891},"Setting Up the Development and Runtime Environment","/microservices-with-django/development-environment","27.microservices-with-django/04.development-environment",{"title":893,"path":894,"stem":895},"Cloud-native Data Processing with MongoDB","/microservices-with-django/cloud-native-data-processing","27.microservices-with-django/05.cloud-native-data-processing",{"title":897,"path":898,"stem":899},"Creating RESTful APIs for Microservices","/microservices-with-django/restful-apis","27.microservices-with-django/06.restful-apis",{"title":901,"path":902,"stem":903},"Orchestrating Microservices with Celery and RabbitMQ","/microservices-with-django/orchestrating-celery-rabbitmq","27.microservices-with-django/07.orchestrating-celery-rabbitmq",{"title":905,"path":906,"stem":907},"Testing Microservices","/microservices-with-django/testing-microservices","27.microservices-with-django/08.testing-microservices",{"title":909,"path":910,"stem":911},"Deploying Microservices","/microservices-with-django/deploying-microservices","27.microservices-with-django/09.deploying-microservices",{"title":913,"path":914,"stem":915},"Securing Microservices","/microservices-with-django/securing-microservices","27.microservices-with-django/10.securing-microservices",{"title":917,"path":918,"stem":919},"Improving Microservices Performance with Caching","/microservices-with-django/performance-caching","27.microservices-with-django/11.performance-caching",{"title":921,"path":922,"stem":923},"Best Practices","/microservices-with-django/best-practices","27.microservices-with-django/12.best-practices",{"title":925,"path":926,"stem":927},"Transforming a Monolithic Web App into a Microservice version","/microservices-with-django/monolith-to-microservices","27.microservices-with-django/13.monolith-to-microservices",{"title":929,"path":930,"stem":931,"children":932},"Releases","/releases","releases",[933,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012],{"title":934,"path":930,"stem":935},"Django Releases","releases/index",{"title":937,"path":938,"stem":939},"Django 5.1.10 release notes","/releases/5.1.10","releases/5.1.10",{"title":941,"path":942,"stem":943},"Django 5.1.11 release notes","/releases/5.1.11","releases/5.1.11",{"title":945,"path":946,"stem":947},"Django 5.1.12 release notes","/releases/5.1.12","releases/5.1.12",{"title":949,"path":950,"stem":951},"Django 5.1.13 release notes","/releases/5.1.13","releases/5.1.13",{"title":953,"path":954,"stem":955},"Django 5.1.14 release notes","/releases/5.1.14","releases/5.1.14",{"title":957,"path":958,"stem":959},"Django 5.1.15 release notes","/releases/5.1.15","releases/5.1.15",{"title":961,"path":962,"stem":963},"Django 5.2 release notes","/releases/5.2","releases/5.2",{"title":965,"path":966,"stem":967},"Django 5.2.1 release notes","/releases/5.2.1","releases/5.2.1",{"title":969,"path":970,"stem":971},"Django 5.2.10 release notes","/releases/5.2.10","releases/5.2.10",{"title":973,"path":974,"stem":975},"Django 5.2.2 release notes","/releases/5.2.2","releases/5.2.2",{"title":977,"path":978,"stem":979},"Django 5.2.3 release notes","/releases/5.2.3","releases/5.2.3",{"title":981,"path":982,"stem":983},"Django 5.2.4 release notes","/releases/5.2.4","releases/5.2.4",{"title":985,"path":986,"stem":987},"Django 5.2.5 release notes","/releases/5.2.5","releases/5.2.5",{"title":989,"path":990,"stem":991},"Django 5.2.6 release notes","/releases/5.2.6","releases/5.2.6",{"title":993,"path":994,"stem":995},"Django 5.2.7 release notes","/releases/5.2.7","releases/5.2.7",{"title":997,"path":998,"stem":999},"Django 5.2.8 release notes","/releases/5.2.8","releases/5.2.8",{"title":1001,"path":1002,"stem":1003},"Django 5.2.9 release notes","/releases/5.2.9","releases/5.2.9",{"title":1005,"path":1006,"stem":1007},"Django 6.0 release notes","/releases/6.0","releases/6.0",{"title":1009,"path":1010,"stem":1011},"Django 6.0.1 release notes","/releases/6.0.1","releases/6.0.1",{"title":1013,"path":1014,"stem":1015},"Django 6.1 release notes - UNDER DEVELOPMENT","/releases/6.1","releases/6.1",{"id":1017,"title":901,"body":1018,"description":1028,"extension":15924,"links":15925,"meta":15926,"navigation":1471,"path":902,"seo":15927,"stem":903,"__hash__":15928},"docs/27.microservices-with-django/07.orchestrating-celery-rabbitmq.md",{"type":1019,"value":1020,"toc":15888},"minimark",[1021,1025,1029,1034,1037,1040,1043,1072,1076,1079,1085,1099,1105,1119,1125,1131,1134,1209,1212,1238,1242,1245,1250,1253,1285,1289,1292,1591,1596,1633,1637,1640,1748,1753,1768,1773,1822,1826,1829,1833,1836,1844,1849,1863,1867,1870,2475,2480,2509,2513,2516,2834,2839,2865,2868,2929,2934,2945,2950,3047,3051,3054,3058,3069,3074,3100,3104,3107,4665,4670,4695,4699,4702,7791,7796,7832,7836,7839,7843,7846,7878,7882,7885,10169,10174,10199,10203,10206,10211,10236,12612,12617,12649,12653,12657,13633,13637,14434,14438,14442,14581,14585,15119,15123,15127,15844,15848,15881,15884],[1022,1023,901],"h1",{"id":1024},"orchestrating-microservices-with-celery-and-rabbitmq",[1026,1027,1028],"p",{},"Microservices architecture often requires asynchronous task processing and inter-service communication. Celery, combined with RabbitMQ as a message broker, provides a robust solution for orchestrating tasks across your Django microservices ecosystem.",[1030,1031,1033],"h2",{"id":1032},"understanding-task-orchestration-in-microservices","Understanding Task Orchestration in Microservices",[1026,1035,1036],{},"When you build microservices, you quickly realize that services need to work together to accomplish complex business processes. Imagine an e-commerce system where creating an order involves multiple steps: validating inventory, processing payment, sending confirmation emails, and updating analytics. In a monolithic application, these would all happen in sequence within a single process. But in microservices, each of these tasks might be handled by different services.",[1026,1038,1039],{},"This is where task orchestration becomes crucial. Think of it like conducting an orchestra - you need a conductor (orchestrator) to coordinate when each musician (service) plays their part to create beautiful music (complete business process).",[1026,1041,1042],{},"Task orchestration involves several key concepts:",[1044,1045,1046,1054,1060,1066],"ul",{},[1047,1048,1049,1053],"li",{},[1050,1051,1052],"strong",{},"Asynchronous Processing",": Instead of making users wait while you send emails or generate reports, you can queue these tasks to run in the background. This keeps your web application responsive while heavy work happens behind the scenes.",[1047,1055,1056,1059],{},[1050,1057,1058],{},"Inter-service Communication",": Services need to talk to each other reliably. Rather than direct HTTP calls (which can fail), message queues provide a robust way for services to communicate even when some services are temporarily unavailable.",[1047,1061,1062,1065],{},[1050,1063,1064],{},"Load Distribution",": When you have multiple instances of a service running, you want to distribute work evenly among them. This prevents any single instance from becoming overwhelmed while others sit idle.",[1047,1067,1068,1071],{},[1050,1069,1070],{},"Fault Tolerance",": In distributed systems, things will go wrong. Networks fail, services crash, and databases become unavailable. Good orchestration ensures your system can handle these failures gracefully and retry operations when appropriate.",[1030,1073,1075],{"id":1074},"technical-requirements","Technical Requirements",[1026,1077,1078],{},"Before we dive into implementing Celery and RabbitMQ orchestration, let's understand what each component does and why we need them:",[1026,1080,1081,1084],{},[1050,1082,1083],{},"Celery"," is a distributed task queue system for Python. Think of it as a sophisticated job scheduler that can:",[1044,1086,1087,1090,1093,1096],{},[1047,1088,1089],{},"Execute tasks asynchronously (in the background)",[1047,1091,1092],{},"Distribute tasks across multiple worker processes",[1047,1094,1095],{},"Handle task failures and retries automatically",[1047,1097,1098],{},"Schedule tasks to run at specific times",[1026,1100,1101,1104],{},[1050,1102,1103],{},"RabbitMQ"," is a message broker - it's like a post office for your services. It:",[1044,1106,1107,1110,1113,1116],{},[1047,1108,1109],{},"Receives messages from one service and delivers them to another",[1047,1111,1112],{},"Ensures messages aren't lost even if services are temporarily down",[1047,1114,1115],{},"Can route messages to different queues based on rules you define",[1047,1117,1118],{},"Provides reliability through message acknowledgments",[1026,1120,1121,1124],{},[1050,1122,1123],{},"Redis"," (optional but recommended) serves as a result backend where Celery stores the results of completed tasks. This is useful when you need to check if a task completed successfully or retrieve its return value.",[1026,1126,1127,1130],{},[1050,1128,1129],{},"Docker"," helps us package and deploy all these components consistently across different environments.",[1026,1132,1133],{},"Here's how to install the required packages:",[1135,1136,1141],"pre",{"className":1137,"code":1138,"language":1139,"meta":1140,"style":1140},"language-bash shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# Install required packages\npip install celery[redis]==5.2.7\npip install kombu==5.2.4\npip install django-celery-beat==2.4.0\npip install django-celery-results==2.4.0\n","bash","",[1142,1143,1144,1153,1171,1184,1197],"code",{"__ignoreMap":1140},[1145,1146,1149],"span",{"class":1147,"line":1148},"line",1,[1145,1150,1152],{"class":1151},"s9Tkl","# Install required packages\n",[1145,1154,1156,1160,1164,1167],{"class":1147,"line":1155},2,[1145,1157,1159],{"class":1158},"sYn-s","pip",[1145,1161,1163],{"class":1162},"sTbE_"," install",[1145,1165,1166],{"class":1162}," celery[redis]==",[1145,1168,1170],{"class":1169},"s7CZa","5.2.7\n",[1145,1172,1174,1176,1178,1181],{"class":1147,"line":1173},3,[1145,1175,1159],{"class":1158},[1145,1177,1163],{"class":1162},[1145,1179,1180],{"class":1162}," kombu==",[1145,1182,1183],{"class":1169},"5.2.4\n",[1145,1185,1187,1189,1191,1194],{"class":1147,"line":1186},4,[1145,1188,1159],{"class":1158},[1145,1190,1163],{"class":1162},[1145,1192,1193],{"class":1162}," django-celery-beat==",[1145,1195,1196],{"class":1169},"2.4.0\n",[1145,1198,1200,1202,1204,1207],{"class":1147,"line":1199},5,[1145,1201,1159],{"class":1158},[1145,1203,1163],{"class":1162},[1145,1205,1206],{"class":1162}," django-celery-results==",[1145,1208,1196],{"class":1169},[1026,1210,1211],{},"Let's break down what each package does:",[1044,1213,1214,1220,1226,1232],{},[1047,1215,1216,1219],{},[1142,1217,1218],{},"celery[redis]",": The main Celery package with Redis support",[1047,1221,1222,1225],{},[1142,1223,1224],{},"kombu",": Low-level messaging library that Celery uses to communicate with message brokers",[1047,1227,1228,1231],{},[1142,1229,1230],{},"django-celery-beat",": Enables periodic task scheduling (like cron jobs)",[1047,1233,1234,1237],{},[1142,1235,1236],{},"django-celery-results",": Stores task results in your Django database",[1030,1239,1241],{"id":1240},"setting-up-rabbitmq","Setting Up RabbitMQ",[1026,1243,1244],{},"RabbitMQ acts as the message broker between your Django services and Celery workers. Think of it as a reliable postal service that ensures messages get delivered even if the recipient isn't immediately available.",[1246,1247,1249],"h3",{"id":1248},"why-rabbitmq","Why RabbitMQ?",[1026,1251,1252],{},"RabbitMQ is particularly well-suited for microservices because it:",[1044,1254,1255,1261,1267,1273,1279],{},[1047,1256,1257,1260],{},[1050,1258,1259],{},"Guarantees message delivery",": Messages won't be lost even if services restart",[1047,1262,1263,1266],{},[1050,1264,1265],{},"Supports complex routing",": You can route different types of messages to different queues",[1047,1268,1269,1272],{},[1050,1270,1271],{},"Provides monitoring",": Built-in web interface to see what's happening",[1047,1274,1275,1278],{},[1050,1276,1277],{},"Handles high throughput",": Can process thousands of messages per second",[1047,1280,1281,1284],{},[1050,1282,1283],{},"Offers clustering",": Can run across multiple servers for high availability",[1246,1286,1288],{"id":1287},"docker-setup-recommended-for-development","Docker Setup (Recommended for Development)",[1026,1290,1291],{},"Using Docker is the easiest way to get RabbitMQ running locally. The configuration below sets up both RabbitMQ and Redis in containers:",[1135,1293,1297],{"className":1294,"code":1295,"language":1296,"meta":1140,"style":1140},"language-yaml shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# docker-compose.yml\nversion: '3.8'\nservices:\n  rabbitmq:\n    image: rabbitmq:3.11-management\n    container_name: microservices_rabbitmq\n    ports:\n      - \"5672:5672\"    # AMQP port for applications\n      - \"15672:15672\"  # Management web interface\n    environment:\n      RABBITMQ_DEFAULT_USER: admin\n      RABBITMQ_DEFAULT_PASS: password123\n    volumes:\n      - rabbitmq_data:/var/lib/rabbitmq  # Persist data between restarts\n    networks:\n      - microservices_network\n\n  redis:\n    image: redis:7-alpine\n    container_name: microservices_redis\n    ports:\n      - \"6379:6379\"\n    networks:\n      - microservices_network\n\nvolumes:\n  rabbitmq_data:  # Named volume for data persistence\n\nnetworks:\n  microservices_network:\n    driver: bridge\n","yaml",[1142,1298,1299,1304,1324,1332,1339,1349,1360,1368,1386,1401,1409,1420,1431,1439,1450,1458,1466,1473,1481,1491,1501,1508,1521,1528,1535,1540,1548,1559,1564,1572,1580],{"__ignoreMap":1140},[1145,1300,1301],{"class":1147,"line":1148},[1145,1302,1303],{"class":1151},"# docker-compose.yml\n",[1145,1305,1306,1310,1314,1318,1321],{"class":1147,"line":1155},[1145,1307,1309],{"class":1308},"suXOh","version",[1145,1311,1313],{"class":1312},"soVBu",":",[1145,1315,1317],{"class":1316},"sbYkP"," '",[1145,1319,1320],{"class":1162},"3.8",[1145,1322,1323],{"class":1316},"'\n",[1145,1325,1326,1329],{"class":1147,"line":1173},[1145,1327,1328],{"class":1308},"services",[1145,1330,1331],{"class":1312},":\n",[1145,1333,1334,1337],{"class":1147,"line":1186},[1145,1335,1336],{"class":1308},"  rabbitmq",[1145,1338,1331],{"class":1312},[1145,1340,1341,1344,1346],{"class":1147,"line":1199},[1145,1342,1343],{"class":1308},"    image",[1145,1345,1313],{"class":1312},[1145,1347,1348],{"class":1162}," rabbitmq:3.11-management\n",[1145,1350,1352,1355,1357],{"class":1147,"line":1351},6,[1145,1353,1354],{"class":1308},"    container_name",[1145,1356,1313],{"class":1312},[1145,1358,1359],{"class":1162}," microservices_rabbitmq\n",[1145,1361,1363,1366],{"class":1147,"line":1362},7,[1145,1364,1365],{"class":1308},"    ports",[1145,1367,1331],{"class":1312},[1145,1369,1371,1374,1377,1380,1383],{"class":1147,"line":1370},8,[1145,1372,1373],{"class":1312},"      -",[1145,1375,1376],{"class":1316}," \"",[1145,1378,1379],{"class":1162},"5672:5672",[1145,1381,1382],{"class":1316},"\"",[1145,1384,1385],{"class":1151},"    # AMQP port for applications\n",[1145,1387,1389,1391,1393,1396,1398],{"class":1147,"line":1388},9,[1145,1390,1373],{"class":1312},[1145,1392,1376],{"class":1316},[1145,1394,1395],{"class":1162},"15672:15672",[1145,1397,1382],{"class":1316},[1145,1399,1400],{"class":1151},"  # Management web interface\n",[1145,1402,1404,1407],{"class":1147,"line":1403},10,[1145,1405,1406],{"class":1308},"    environment",[1145,1408,1331],{"class":1312},[1145,1410,1412,1415,1417],{"class":1147,"line":1411},11,[1145,1413,1414],{"class":1308},"      RABBITMQ_DEFAULT_USER",[1145,1416,1313],{"class":1312},[1145,1418,1419],{"class":1162}," admin\n",[1145,1421,1423,1426,1428],{"class":1147,"line":1422},12,[1145,1424,1425],{"class":1308},"      RABBITMQ_DEFAULT_PASS",[1145,1427,1313],{"class":1312},[1145,1429,1430],{"class":1162}," password123\n",[1145,1432,1434,1437],{"class":1147,"line":1433},13,[1145,1435,1436],{"class":1308},"    volumes",[1145,1438,1331],{"class":1312},[1145,1440,1442,1444,1447],{"class":1147,"line":1441},14,[1145,1443,1373],{"class":1312},[1145,1445,1446],{"class":1162}," rabbitmq_data:/var/lib/rabbitmq",[1145,1448,1449],{"class":1151},"  # Persist data between restarts\n",[1145,1451,1453,1456],{"class":1147,"line":1452},15,[1145,1454,1455],{"class":1308},"    networks",[1145,1457,1331],{"class":1312},[1145,1459,1461,1463],{"class":1147,"line":1460},16,[1145,1462,1373],{"class":1312},[1145,1464,1465],{"class":1162}," microservices_network\n",[1145,1467,1469],{"class":1147,"line":1468},17,[1145,1470,1472],{"emptyLinePlaceholder":1471},true,"\n",[1145,1474,1476,1479],{"class":1147,"line":1475},18,[1145,1477,1478],{"class":1308},"  redis",[1145,1480,1331],{"class":1312},[1145,1482,1484,1486,1488],{"class":1147,"line":1483},19,[1145,1485,1343],{"class":1308},[1145,1487,1313],{"class":1312},[1145,1489,1490],{"class":1162}," redis:7-alpine\n",[1145,1492,1494,1496,1498],{"class":1147,"line":1493},20,[1145,1495,1354],{"class":1308},[1145,1497,1313],{"class":1312},[1145,1499,1500],{"class":1162}," microservices_redis\n",[1145,1502,1504,1506],{"class":1147,"line":1503},21,[1145,1505,1365],{"class":1308},[1145,1507,1331],{"class":1312},[1145,1509,1511,1513,1515,1518],{"class":1147,"line":1510},22,[1145,1512,1373],{"class":1312},[1145,1514,1376],{"class":1316},[1145,1516,1517],{"class":1162},"6379:6379",[1145,1519,1520],{"class":1316},"\"\n",[1145,1522,1524,1526],{"class":1147,"line":1523},23,[1145,1525,1455],{"class":1308},[1145,1527,1331],{"class":1312},[1145,1529,1531,1533],{"class":1147,"line":1530},24,[1145,1532,1373],{"class":1312},[1145,1534,1465],{"class":1162},[1145,1536,1538],{"class":1147,"line":1537},25,[1145,1539,1472],{"emptyLinePlaceholder":1471},[1145,1541,1543,1546],{"class":1147,"line":1542},26,[1145,1544,1545],{"class":1308},"volumes",[1145,1547,1331],{"class":1312},[1145,1549,1551,1554,1556],{"class":1147,"line":1550},27,[1145,1552,1553],{"class":1308},"  rabbitmq_data",[1145,1555,1313],{"class":1312},[1145,1557,1558],{"class":1151},"  # Named volume for data persistence\n",[1145,1560,1562],{"class":1147,"line":1561},28,[1145,1563,1472],{"emptyLinePlaceholder":1471},[1145,1565,1567,1570],{"class":1147,"line":1566},29,[1145,1568,1569],{"class":1308},"networks",[1145,1571,1331],{"class":1312},[1145,1573,1575,1578],{"class":1147,"line":1574},30,[1145,1576,1577],{"class":1308},"  microservices_network",[1145,1579,1331],{"class":1312},[1145,1581,1583,1586,1588],{"class":1147,"line":1582},31,[1145,1584,1585],{"class":1308},"    driver",[1145,1587,1313],{"class":1312},[1145,1589,1590],{"class":1162}," bridge\n",[1026,1592,1593],{},[1050,1594,1595],{},"What each part does:",[1044,1597,1598,1604,1611,1624,1627,1630],{},[1047,1599,1600,1603],{},[1142,1601,1602],{},"rabbitmq:3.11-management",": Uses RabbitMQ with the management plugin enabled",[1047,1605,1606,1607,1610],{},"Port ",[1142,1608,1609],{},"5672",": The main AMQP port where your applications connect",[1047,1612,1606,1613,1616,1617,1623],{},[1142,1614,1615],{},"15672",": Web management interface (visit ",[1618,1619,1620],"a",{"href":1620,"rel":1621},"http://localhost:15672",[1622],"nofollow",")",[1047,1625,1626],{},"Environment variables: Set default username/password for security",[1047,1628,1629],{},"Volume: Ensures your queues and messages survive container restarts",[1047,1631,1632],{},"Network: Allows containers to communicate with each other",[1246,1634,1636],{"id":1635},"manual-installation-alternative-to-docker","Manual Installation (Alternative to Docker)",[1026,1638,1639],{},"If you prefer to install RabbitMQ directly on your system, here's how:",[1135,1641,1643],{"className":1137,"code":1642,"language":1139,"meta":1140,"style":1140},"# Ubuntu/Debian\nsudo apt-get update\nsudo apt-get install rabbitmq-server\n\n# macOS (using Homebrew)\nbrew install rabbitmq\n\n# Start RabbitMQ service\nsudo systemctl start rabbitmq-server\nsudo systemctl enable rabbitmq-server  # Start automatically on boot\n\n# Enable management plugin for web interface\nsudo rabbitmq-plugins enable rabbitmq_management\n",[1142,1644,1645,1650,1661,1672,1676,1681,1691,1695,1700,1712,1727,1731,1736],{"__ignoreMap":1140},[1145,1646,1647],{"class":1147,"line":1148},[1145,1648,1649],{"class":1151},"# Ubuntu/Debian\n",[1145,1651,1652,1655,1658],{"class":1147,"line":1155},[1145,1653,1654],{"class":1158},"sudo",[1145,1656,1657],{"class":1162}," apt-get",[1145,1659,1660],{"class":1162}," update\n",[1145,1662,1663,1665,1667,1669],{"class":1147,"line":1173},[1145,1664,1654],{"class":1158},[1145,1666,1657],{"class":1162},[1145,1668,1163],{"class":1162},[1145,1670,1671],{"class":1162}," rabbitmq-server\n",[1145,1673,1674],{"class":1147,"line":1186},[1145,1675,1472],{"emptyLinePlaceholder":1471},[1145,1677,1678],{"class":1147,"line":1199},[1145,1679,1680],{"class":1151},"# macOS (using Homebrew)\n",[1145,1682,1683,1686,1688],{"class":1147,"line":1351},[1145,1684,1685],{"class":1158},"brew",[1145,1687,1163],{"class":1162},[1145,1689,1690],{"class":1162}," rabbitmq\n",[1145,1692,1693],{"class":1147,"line":1362},[1145,1694,1472],{"emptyLinePlaceholder":1471},[1145,1696,1697],{"class":1147,"line":1370},[1145,1698,1699],{"class":1151},"# Start RabbitMQ service\n",[1145,1701,1702,1704,1707,1710],{"class":1147,"line":1388},[1145,1703,1654],{"class":1158},[1145,1705,1706],{"class":1162}," systemctl",[1145,1708,1709],{"class":1162}," start",[1145,1711,1671],{"class":1162},[1145,1713,1714,1716,1718,1721,1724],{"class":1147,"line":1403},[1145,1715,1654],{"class":1158},[1145,1717,1706],{"class":1162},[1145,1719,1720],{"class":1162}," enable",[1145,1722,1723],{"class":1162}," rabbitmq-server",[1145,1725,1726],{"class":1151},"  # Start automatically on boot\n",[1145,1728,1729],{"class":1147,"line":1411},[1145,1730,1472],{"emptyLinePlaceholder":1471},[1145,1732,1733],{"class":1147,"line":1422},[1145,1734,1735],{"class":1151},"# Enable management plugin for web interface\n",[1145,1737,1738,1740,1743,1745],{"class":1147,"line":1433},[1145,1739,1654],{"class":1158},[1145,1741,1742],{"class":1162}," rabbitmq-plugins",[1145,1744,1720],{"class":1162},[1145,1746,1747],{"class":1162}," rabbitmq_management\n",[1026,1749,1750],{},[1050,1751,1752],{},"After installation:",[1754,1755,1756,1759,1765],"ol",{},[1047,1757,1758],{},"RabbitMQ will be running on port 5672",[1047,1760,1761,1762],{},"Management interface available at ",[1618,1763,1620],{"href":1620,"rel":1764},[1622],[1047,1766,1767],{},"Default credentials: guest/guest (change these in production!)",[1026,1769,1770],{},[1050,1771,1772],{},"Testing your installation:",[1135,1774,1776],{"className":1137,"code":1775,"language":1139,"meta":1140,"style":1140},"# Check if RabbitMQ is running\nsudo systemctl status rabbitmq-server\n\n# Or check if the port is listening\nnetstat -tlnp | grep 5672\n",[1142,1777,1778,1783,1794,1798,1803],{"__ignoreMap":1140},[1145,1779,1780],{"class":1147,"line":1148},[1145,1781,1782],{"class":1151},"# Check if RabbitMQ is running\n",[1145,1784,1785,1787,1789,1792],{"class":1147,"line":1155},[1145,1786,1654],{"class":1158},[1145,1788,1706],{"class":1162},[1145,1790,1791],{"class":1162}," status",[1145,1793,1671],{"class":1162},[1145,1795,1796],{"class":1147,"line":1173},[1145,1797,1472],{"emptyLinePlaceholder":1471},[1145,1799,1800],{"class":1147,"line":1186},[1145,1801,1802],{"class":1151},"# Or check if the port is listening\n",[1145,1804,1805,1808,1812,1816,1819],{"class":1147,"line":1199},[1145,1806,1807],{"class":1158},"netstat",[1145,1809,1811],{"class":1810},"sz9Cv"," -tlnp",[1145,1813,1815],{"class":1814},"sVsLi"," |",[1145,1817,1818],{"class":1158}," grep",[1145,1820,1821],{"class":1169}," 5672\n",[1030,1823,1825],{"id":1824},"configuring-celery-in-django","Configuring Celery in Django",[1026,1827,1828],{},"Now let's set up Celery to work with your Django microservices. The key concept here is that each service can have its own Celery configuration while sharing the same message broker (RabbitMQ).",[1246,1830,1832],{"id":1831},"understanding-the-project-structure","Understanding the Project Structure",[1026,1834,1835],{},"In a microservices architecture, you'll typically have multiple Django projects (services) that need to communicate. Here's a recommended structure:",[1135,1837,1842],{"className":1838,"code":1840,"language":1841},[1839],"language-text","microservices_project/\n├── user_service/              # Django project for user management\n│   ├── __init__.py\n│   ├── settings.py\n│   ├── celery.py             # Celery configuration for this service\n│   ├── tasks.py              # Tasks specific to user service\n│   └── views.py\n├── order_service/             # Django project for order management\n│   ├── __init__.py\n│   ├── settings.py\n│   ├── celery.py             # Celery configuration for this service\n│   ├── tasks.py              # Tasks specific to order service\n│   └── views.py\n└── shared/                    # Shared configuration and utilities\n    ├── __init__.py\n    └── celery_config.py       # Common Celery settings\n","text",[1142,1843,1840],{"__ignoreMap":1140},[1026,1845,1846],{},[1050,1847,1848],{},"Why this structure?",[1044,1850,1851,1854,1857,1860],{},[1047,1852,1853],{},"Each service maintains its own Celery instance and tasks",[1047,1855,1856],{},"Shared configuration ensures consistency across services",[1047,1858,1859],{},"Services can communicate through message queues",[1047,1861,1862],{},"Easy to scale individual services independently",[1246,1864,1866],{"id":1865},"shared-celery-configuration","Shared Celery Configuration",[1026,1868,1869],{},"The shared configuration file contains settings that all services should use. This ensures consistency and makes it easier to manage your infrastructure:",[1135,1871,1875],{"className":1872,"code":1873,"language":1874,"meta":1140,"style":1140},"language-python shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# shared/celery_config.py\nfrom kombu import Queue, Exchange\n\n# Broker settings - this is where Celery connects to RabbitMQ\nCELERY_BROKER_URL = 'amqp://admin:password123@localhost:5672//'\nCELERY_RESULT_BACKEND = 'redis://localhost:6379/0'\n\n# Task serialization - how tasks are converted to messages\nCELERY_TASK_SERIALIZER = 'json'        # Use JSON for task arguments\nCELERY_RESULT_SERIALIZER = 'json'      # Use JSON for task results\nCELERY_ACCEPT_CONTENT = ['json']       # Only accept JSON content\n\n# Timezone settings\nCELERY_TIMEZONE = 'UTC'                # Use UTC for consistency\nCELERY_ENABLE_UTC = True\n\n# Task routing - this is crucial for microservices!\n# It determines which queue each task goes to\nCELERY_TASK_ROUTES = {\n    'user_service.tasks.*': {'queue': 'user_queue'},           # All user service tasks\n    'order_service.tasks.*': {'queue': 'order_queue'},         # All order service tasks\n    'notification_service.tasks.*': {'queue': 'notification_queue'},  # Notification tasks\n}\n\n# Queue configuration - define the actual queues\nCELERY_TASK_DEFAULT_QUEUE = 'default'\nCELERY_TASK_QUEUES = (\n    Queue('default', Exchange('default'), routing_key='default'),\n    Queue('user_queue', Exchange('user'), routing_key='user.#'),\n    Queue('order_queue', Exchange('order'), routing_key='order.#'),\n    Queue('notification_queue', Exchange('notification'), routing_key='notification.#'),\n)\n\n# Worker configuration - these settings optimize performance\nCELERY_WORKER_PREFETCH_MULTIPLIER = 1  # Process one task at a time (safer)\nCELERY_TASK_ACKS_LATE = True          # Acknowledge tasks only after completion\nCELERY_WORKER_MAX_TASKS_PER_CHILD = 1000  # Restart workers after 1000 tasks (prevents memory leaks)\n\n# Task execution limits - prevent runaway tasks\nCELERY_TASK_TIME_LIMIT = 300          # 5 minutes hard limit\nCELERY_TASK_SOFT_TIME_LIMIT = 240     # 4 minutes soft limit (sends signal to task)\n","python",[1142,1876,1877,1882,1904,1908,1913,1929,1943,1947,1952,1970,1986,2008,2012,2017,2034,2045,2049,2054,2059,2069,2106,2139,2172,2177,2181,2186,2200,2210,2257,2297,2337,2377,2383,2388,2394,2408,2422,2436,2441,2447,2461],{"__ignoreMap":1140},[1145,1878,1879],{"class":1147,"line":1148},[1145,1880,1881],{"class":1151},"# shared/celery_config.py\n",[1145,1883,1884,1888,1892,1895,1898,1901],{"class":1147,"line":1155},[1145,1885,1887],{"class":1886},"siDh9","from",[1145,1889,1891],{"class":1890},"sftqT"," kombu ",[1145,1893,1894],{"class":1886},"import",[1145,1896,1897],{"class":1890}," Queue",[1145,1899,1900],{"class":1312},",",[1145,1902,1903],{"class":1890}," Exchange\n",[1145,1905,1906],{"class":1147,"line":1173},[1145,1907,1472],{"emptyLinePlaceholder":1471},[1145,1909,1910],{"class":1147,"line":1186},[1145,1911,1912],{"class":1151},"# Broker settings - this is where Celery connects to RabbitMQ\n",[1145,1914,1915,1919,1922,1924,1927],{"class":1147,"line":1199},[1145,1916,1918],{"class":1917},"se3Ec","CELERY_BROKER_URL",[1145,1920,1921],{"class":1312}," =",[1145,1923,1317],{"class":1316},[1145,1925,1926],{"class":1162},"amqp://admin:password123@localhost:5672//",[1145,1928,1323],{"class":1316},[1145,1930,1931,1934,1936,1938,1941],{"class":1147,"line":1351},[1145,1932,1933],{"class":1917},"CELERY_RESULT_BACKEND",[1145,1935,1921],{"class":1312},[1145,1937,1317],{"class":1316},[1145,1939,1940],{"class":1162},"redis://localhost:6379/0",[1145,1942,1323],{"class":1316},[1145,1944,1945],{"class":1147,"line":1362},[1145,1946,1472],{"emptyLinePlaceholder":1471},[1145,1948,1949],{"class":1147,"line":1370},[1145,1950,1951],{"class":1151},"# Task serialization - how tasks are converted to messages\n",[1145,1953,1954,1957,1959,1961,1964,1967],{"class":1147,"line":1388},[1145,1955,1956],{"class":1917},"CELERY_TASK_SERIALIZER",[1145,1958,1921],{"class":1312},[1145,1960,1317],{"class":1316},[1145,1962,1963],{"class":1162},"json",[1145,1965,1966],{"class":1316},"'",[1145,1968,1969],{"class":1151},"        # Use JSON for task arguments\n",[1145,1971,1972,1975,1977,1979,1981,1983],{"class":1147,"line":1403},[1145,1973,1974],{"class":1917},"CELERY_RESULT_SERIALIZER",[1145,1976,1921],{"class":1312},[1145,1978,1317],{"class":1316},[1145,1980,1963],{"class":1162},[1145,1982,1966],{"class":1316},[1145,1984,1985],{"class":1151},"      # Use JSON for task results\n",[1145,1987,1988,1991,1993,1996,1998,2000,2002,2005],{"class":1147,"line":1411},[1145,1989,1990],{"class":1917},"CELERY_ACCEPT_CONTENT",[1145,1992,1921],{"class":1312},[1145,1994,1995],{"class":1312}," [",[1145,1997,1966],{"class":1316},[1145,1999,1963],{"class":1162},[1145,2001,1966],{"class":1316},[1145,2003,2004],{"class":1312},"]",[1145,2006,2007],{"class":1151},"       # Only accept JSON content\n",[1145,2009,2010],{"class":1147,"line":1422},[1145,2011,1472],{"emptyLinePlaceholder":1471},[1145,2013,2014],{"class":1147,"line":1433},[1145,2015,2016],{"class":1151},"# Timezone settings\n",[1145,2018,2019,2022,2024,2026,2029,2031],{"class":1147,"line":1441},[1145,2020,2021],{"class":1917},"CELERY_TIMEZONE",[1145,2023,1921],{"class":1312},[1145,2025,1317],{"class":1316},[1145,2027,2028],{"class":1162},"UTC",[1145,2030,1966],{"class":1316},[1145,2032,2033],{"class":1151},"                # Use UTC for consistency\n",[1145,2035,2036,2039,2041],{"class":1147,"line":1452},[1145,2037,2038],{"class":1917},"CELERY_ENABLE_UTC",[1145,2040,1921],{"class":1312},[1145,2042,2044],{"class":2043},"s8XtY"," True\n",[1145,2046,2047],{"class":1147,"line":1460},[1145,2048,1472],{"emptyLinePlaceholder":1471},[1145,2050,2051],{"class":1147,"line":1468},[1145,2052,2053],{"class":1151},"# Task routing - this is crucial for microservices!\n",[1145,2055,2056],{"class":1147,"line":1475},[1145,2057,2058],{"class":1151},"# It determines which queue each task goes to\n",[1145,2060,2061,2064,2066],{"class":1147,"line":1483},[1145,2062,2063],{"class":1917},"CELERY_TASK_ROUTES",[1145,2065,1921],{"class":1312},[1145,2067,2068],{"class":1312}," {\n",[1145,2070,2071,2074,2077,2079,2081,2084,2086,2089,2091,2093,2095,2098,2100,2103],{"class":1147,"line":1493},[1145,2072,2073],{"class":1316},"    '",[1145,2075,2076],{"class":1162},"user_service.tasks.*",[1145,2078,1966],{"class":1316},[1145,2080,1313],{"class":1312},[1145,2082,2083],{"class":1312}," {",[1145,2085,1966],{"class":1316},[1145,2087,2088],{"class":1162},"queue",[1145,2090,1966],{"class":1316},[1145,2092,1313],{"class":1312},[1145,2094,1317],{"class":1316},[1145,2096,2097],{"class":1162},"user_queue",[1145,2099,1966],{"class":1316},[1145,2101,2102],{"class":1312},"},",[1145,2104,2105],{"class":1151},"           # All user service tasks\n",[1145,2107,2108,2110,2113,2115,2117,2119,2121,2123,2125,2127,2129,2132,2134,2136],{"class":1147,"line":1503},[1145,2109,2073],{"class":1316},[1145,2111,2112],{"class":1162},"order_service.tasks.*",[1145,2114,1966],{"class":1316},[1145,2116,1313],{"class":1312},[1145,2118,2083],{"class":1312},[1145,2120,1966],{"class":1316},[1145,2122,2088],{"class":1162},[1145,2124,1966],{"class":1316},[1145,2126,1313],{"class":1312},[1145,2128,1317],{"class":1316},[1145,2130,2131],{"class":1162},"order_queue",[1145,2133,1966],{"class":1316},[1145,2135,2102],{"class":1312},[1145,2137,2138],{"class":1151},"         # All order service tasks\n",[1145,2140,2141,2143,2146,2148,2150,2152,2154,2156,2158,2160,2162,2165,2167,2169],{"class":1147,"line":1510},[1145,2142,2073],{"class":1316},[1145,2144,2145],{"class":1162},"notification_service.tasks.*",[1145,2147,1966],{"class":1316},[1145,2149,1313],{"class":1312},[1145,2151,2083],{"class":1312},[1145,2153,1966],{"class":1316},[1145,2155,2088],{"class":1162},[1145,2157,1966],{"class":1316},[1145,2159,1313],{"class":1312},[1145,2161,1317],{"class":1316},[1145,2163,2164],{"class":1162},"notification_queue",[1145,2166,1966],{"class":1316},[1145,2168,2102],{"class":1312},[1145,2170,2171],{"class":1151},"  # Notification tasks\n",[1145,2173,2174],{"class":1147,"line":1523},[1145,2175,2176],{"class":1312},"}\n",[1145,2178,2179],{"class":1147,"line":1530},[1145,2180,1472],{"emptyLinePlaceholder":1471},[1145,2182,2183],{"class":1147,"line":1537},[1145,2184,2185],{"class":1151},"# Queue configuration - define the actual queues\n",[1145,2187,2188,2191,2193,2195,2198],{"class":1147,"line":1542},[1145,2189,2190],{"class":1917},"CELERY_TASK_DEFAULT_QUEUE",[1145,2192,1921],{"class":1312},[1145,2194,1317],{"class":1316},[1145,2196,2197],{"class":1162},"default",[1145,2199,1323],{"class":1316},[1145,2201,2202,2205,2207],{"class":1147,"line":1550},[1145,2203,2204],{"class":1917},"CELERY_TASK_QUEUES",[1145,2206,1921],{"class":1312},[1145,2208,2209],{"class":1312}," (\n",[1145,2211,2212,2216,2219,2221,2223,2225,2227,2230,2232,2234,2236,2238,2241,2245,2248,2250,2252,2254],{"class":1147,"line":1561},[1145,2213,2215],{"class":2214},"siWMO","    Queue",[1145,2217,2218],{"class":1312},"(",[1145,2220,1966],{"class":1316},[1145,2222,2197],{"class":1162},[1145,2224,1966],{"class":1316},[1145,2226,1900],{"class":1312},[1145,2228,2229],{"class":2214}," Exchange",[1145,2231,2218],{"class":1312},[1145,2233,1966],{"class":1316},[1145,2235,2197],{"class":1162},[1145,2237,1966],{"class":1316},[1145,2239,2240],{"class":1312},"),",[1145,2242,2244],{"class":2243},"sqOPj"," routing_key",[1145,2246,2247],{"class":1312},"=",[1145,2249,1966],{"class":1316},[1145,2251,2197],{"class":1162},[1145,2253,1966],{"class":1316},[1145,2255,2256],{"class":1312},"),\n",[1145,2258,2259,2261,2263,2265,2267,2269,2271,2273,2275,2277,2280,2282,2284,2286,2288,2290,2293,2295],{"class":1147,"line":1566},[1145,2260,2215],{"class":2214},[1145,2262,2218],{"class":1312},[1145,2264,1966],{"class":1316},[1145,2266,2097],{"class":1162},[1145,2268,1966],{"class":1316},[1145,2270,1900],{"class":1312},[1145,2272,2229],{"class":2214},[1145,2274,2218],{"class":1312},[1145,2276,1966],{"class":1316},[1145,2278,2279],{"class":1162},"user",[1145,2281,1966],{"class":1316},[1145,2283,2240],{"class":1312},[1145,2285,2244],{"class":2243},[1145,2287,2247],{"class":1312},[1145,2289,1966],{"class":1316},[1145,2291,2292],{"class":1162},"user.#",[1145,2294,1966],{"class":1316},[1145,2296,2256],{"class":1312},[1145,2298,2299,2301,2303,2305,2307,2309,2311,2313,2315,2317,2320,2322,2324,2326,2328,2330,2333,2335],{"class":1147,"line":1574},[1145,2300,2215],{"class":2214},[1145,2302,2218],{"class":1312},[1145,2304,1966],{"class":1316},[1145,2306,2131],{"class":1162},[1145,2308,1966],{"class":1316},[1145,2310,1900],{"class":1312},[1145,2312,2229],{"class":2214},[1145,2314,2218],{"class":1312},[1145,2316,1966],{"class":1316},[1145,2318,2319],{"class":1162},"order",[1145,2321,1966],{"class":1316},[1145,2323,2240],{"class":1312},[1145,2325,2244],{"class":2243},[1145,2327,2247],{"class":1312},[1145,2329,1966],{"class":1316},[1145,2331,2332],{"class":1162},"order.#",[1145,2334,1966],{"class":1316},[1145,2336,2256],{"class":1312},[1145,2338,2339,2341,2343,2345,2347,2349,2351,2353,2355,2357,2360,2362,2364,2366,2368,2370,2373,2375],{"class":1147,"line":1582},[1145,2340,2215],{"class":2214},[1145,2342,2218],{"class":1312},[1145,2344,1966],{"class":1316},[1145,2346,2164],{"class":1162},[1145,2348,1966],{"class":1316},[1145,2350,1900],{"class":1312},[1145,2352,2229],{"class":2214},[1145,2354,2218],{"class":1312},[1145,2356,1966],{"class":1316},[1145,2358,2359],{"class":1162},"notification",[1145,2361,1966],{"class":1316},[1145,2363,2240],{"class":1312},[1145,2365,2244],{"class":2243},[1145,2367,2247],{"class":1312},[1145,2369,1966],{"class":1316},[1145,2371,2372],{"class":1162},"notification.#",[1145,2374,1966],{"class":1316},[1145,2376,2256],{"class":1312},[1145,2378,2380],{"class":1147,"line":2379},32,[1145,2381,2382],{"class":1312},")\n",[1145,2384,2386],{"class":1147,"line":2385},33,[1145,2387,1472],{"emptyLinePlaceholder":1471},[1145,2389,2391],{"class":1147,"line":2390},34,[1145,2392,2393],{"class":1151},"# Worker configuration - these settings optimize performance\n",[1145,2395,2397,2400,2402,2405],{"class":1147,"line":2396},35,[1145,2398,2399],{"class":1917},"CELERY_WORKER_PREFETCH_MULTIPLIER",[1145,2401,1921],{"class":1312},[1145,2403,2404],{"class":1169}," 1",[1145,2406,2407],{"class":1151},"  # Process one task at a time (safer)\n",[1145,2409,2411,2414,2416,2419],{"class":1147,"line":2410},36,[1145,2412,2413],{"class":1917},"CELERY_TASK_ACKS_LATE",[1145,2415,1921],{"class":1312},[1145,2417,2418],{"class":2043}," True",[1145,2420,2421],{"class":1151},"          # Acknowledge tasks only after completion\n",[1145,2423,2425,2428,2430,2433],{"class":1147,"line":2424},37,[1145,2426,2427],{"class":1917},"CELERY_WORKER_MAX_TASKS_PER_CHILD",[1145,2429,1921],{"class":1312},[1145,2431,2432],{"class":1169}," 1000",[1145,2434,2435],{"class":1151},"  # Restart workers after 1000 tasks (prevents memory leaks)\n",[1145,2437,2439],{"class":1147,"line":2438},38,[1145,2440,1472],{"emptyLinePlaceholder":1471},[1145,2442,2444],{"class":1147,"line":2443},39,[1145,2445,2446],{"class":1151},"# Task execution limits - prevent runaway tasks\n",[1145,2448,2450,2453,2455,2458],{"class":1147,"line":2449},40,[1145,2451,2452],{"class":1917},"CELERY_TASK_TIME_LIMIT",[1145,2454,1921],{"class":1312},[1145,2456,2457],{"class":1169}," 300",[1145,2459,2460],{"class":1151},"          # 5 minutes hard limit\n",[1145,2462,2464,2467,2469,2472],{"class":1147,"line":2463},41,[1145,2465,2466],{"class":1917},"CELERY_TASK_SOFT_TIME_LIMIT",[1145,2468,1921],{"class":1312},[1145,2470,2471],{"class":1169}," 240",[1145,2473,2474],{"class":1151},"     # 4 minutes soft limit (sends signal to task)\n",[1026,2476,2477],{},[1050,2478,2479],{},"Key concepts explained:",[1754,2481,2482,2491,2497,2503],{},[1047,2483,2484,2487,2488,2490],{},[1050,2485,2486],{},"Task Routing",": This is how Celery knows which queue to send each task to. By using patterns like ",[1142,2489,2076],{},", all tasks in the user service automatically go to the user queue.",[1047,2492,2493,2496],{},[1050,2494,2495],{},"Exchanges and Queues",": Think of exchanges as post offices and queues as mailboxes. Messages go to exchanges first, then get routed to the appropriate queue based on routing keys.",[1047,2498,2499,2502],{},[1050,2500,2501],{},"Worker Configuration",": These settings help prevent common issues like memory leaks and stuck tasks.",[1047,2504,2505,2508],{},[1050,2506,2507],{},"Time Limits",": Prevent tasks from running forever, which could block workers.",[1246,2510,2512],{"id":2511},"service-specific-celery-setup","Service-Specific Celery Setup",[1026,2514,2515],{},"Each Django service needs its own Celery application instance. This allows services to run independently while still communicating through the shared message broker.",[1135,2517,2519],{"className":1872,"code":2518,"language":1874,"meta":1140,"style":1140},"# user_service/celery.py\nimport os\nfrom celery import Celery\nfrom django.conf import settings\n\n# Set the default Django settings module for the 'celery' program.\n# This tells Celery which Django settings to use\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'user_service.settings')\n\n# Create the Celery application instance\n# The name 'user_service' will appear in logs and monitoring tools\napp = Celery('user_service')\n\n# Load configuration from the shared config file\n# The namespace='CELERY' means it will look for settings starting with CELERY_\napp.config_from_object('shared.celery_config', namespace='CELERY')\n\n# Auto-discover tasks from all installed Django apps\n# This automatically finds tasks.py files in your Django apps\napp.autodiscover_tasks()\n\n# Debug task - useful for testing your setup\n@app.task(bind=True)\ndef debug_task(self):\n    \"\"\"A simple task to test if Celery is working\"\"\"\n    print(f'Request: {self.request!r}')\n    return f'Debug task executed successfully'\n",[1142,2520,2521,2526,2533,2545,2563,2567,2572,2577,2613,2617,2622,2627,2648,2652,2657,2662,2697,2701,2706,2711,2723,2727,2732,2757,2775,2788,2823],{"__ignoreMap":1140},[1145,2522,2523],{"class":1147,"line":1148},[1145,2524,2525],{"class":1151},"# user_service/celery.py\n",[1145,2527,2528,2530],{"class":1147,"line":1155},[1145,2529,1894],{"class":1886},[1145,2531,2532],{"class":1890}," os\n",[1145,2534,2535,2537,2540,2542],{"class":1147,"line":1173},[1145,2536,1887],{"class":1886},[1145,2538,2539],{"class":1890}," celery ",[1145,2541,1894],{"class":1886},[1145,2543,2544],{"class":1890}," Celery\n",[1145,2546,2547,2549,2552,2555,2558,2560],{"class":1147,"line":1186},[1145,2548,1887],{"class":1886},[1145,2550,2551],{"class":1890}," django",[1145,2553,2554],{"class":1312},".",[1145,2556,2557],{"class":1890},"conf ",[1145,2559,1894],{"class":1886},[1145,2561,2562],{"class":1890}," settings\n",[1145,2564,2565],{"class":1147,"line":1199},[1145,2566,1472],{"emptyLinePlaceholder":1471},[1145,2568,2569],{"class":1147,"line":1351},[1145,2570,2571],{"class":1151},"# Set the default Django settings module for the 'celery' program.\n",[1145,2573,2574],{"class":1147,"line":1362},[1145,2575,2576],{"class":1151},"# This tells Celery which Django settings to use\n",[1145,2578,2579,2582,2584,2588,2590,2593,2595,2597,2600,2602,2604,2606,2609,2611],{"class":1147,"line":1370},[1145,2580,2581],{"class":1890},"os",[1145,2583,2554],{"class":1312},[1145,2585,2587],{"class":2586},"sBPpx","environ",[1145,2589,2554],{"class":1312},[1145,2591,2592],{"class":2214},"setdefault",[1145,2594,2218],{"class":1312},[1145,2596,1966],{"class":1316},[1145,2598,2599],{"class":1162},"DJANGO_SETTINGS_MODULE",[1145,2601,1966],{"class":1316},[1145,2603,1900],{"class":1312},[1145,2605,1317],{"class":1316},[1145,2607,2608],{"class":1162},"user_service.settings",[1145,2610,1966],{"class":1316},[1145,2612,2382],{"class":1312},[1145,2614,2615],{"class":1147,"line":1388},[1145,2616,1472],{"emptyLinePlaceholder":1471},[1145,2618,2619],{"class":1147,"line":1403},[1145,2620,2621],{"class":1151},"# Create the Celery application instance\n",[1145,2623,2624],{"class":1147,"line":1411},[1145,2625,2626],{"class":1151},"# The name 'user_service' will appear in logs and monitoring tools\n",[1145,2628,2629,2632,2634,2637,2639,2641,2644,2646],{"class":1147,"line":1422},[1145,2630,2631],{"class":1890},"app ",[1145,2633,2247],{"class":1312},[1145,2635,2636],{"class":2214}," Celery",[1145,2638,2218],{"class":1312},[1145,2640,1966],{"class":1316},[1145,2642,2643],{"class":1162},"user_service",[1145,2645,1966],{"class":1316},[1145,2647,2382],{"class":1312},[1145,2649,2650],{"class":1147,"line":1433},[1145,2651,1472],{"emptyLinePlaceholder":1471},[1145,2653,2654],{"class":1147,"line":1441},[1145,2655,2656],{"class":1151},"# Load configuration from the shared config file\n",[1145,2658,2659],{"class":1147,"line":1452},[1145,2660,2661],{"class":1151},"# The namespace='CELERY' means it will look for settings starting with CELERY_\n",[1145,2663,2664,2667,2669,2672,2674,2676,2679,2681,2683,2686,2688,2690,2693,2695],{"class":1147,"line":1460},[1145,2665,2666],{"class":1890},"app",[1145,2668,2554],{"class":1312},[1145,2670,2671],{"class":2214},"config_from_object",[1145,2673,2218],{"class":1312},[1145,2675,1966],{"class":1316},[1145,2677,2678],{"class":1162},"shared.celery_config",[1145,2680,1966],{"class":1316},[1145,2682,1900],{"class":1312},[1145,2684,2685],{"class":2243}," namespace",[1145,2687,2247],{"class":1312},[1145,2689,1966],{"class":1316},[1145,2691,2692],{"class":1162},"CELERY",[1145,2694,1966],{"class":1316},[1145,2696,2382],{"class":1312},[1145,2698,2699],{"class":1147,"line":1468},[1145,2700,1472],{"emptyLinePlaceholder":1471},[1145,2702,2703],{"class":1147,"line":1475},[1145,2704,2705],{"class":1151},"# Auto-discover tasks from all installed Django apps\n",[1145,2707,2708],{"class":1147,"line":1483},[1145,2709,2710],{"class":1151},"# This automatically finds tasks.py files in your Django apps\n",[1145,2712,2713,2715,2717,2720],{"class":1147,"line":1493},[1145,2714,2666],{"class":1890},[1145,2716,2554],{"class":1312},[1145,2718,2719],{"class":2214},"autodiscover_tasks",[1145,2721,2722],{"class":1312},"()\n",[1145,2724,2725],{"class":1147,"line":1503},[1145,2726,1472],{"emptyLinePlaceholder":1471},[1145,2728,2729],{"class":1147,"line":1510},[1145,2730,2731],{"class":1151},"# Debug task - useful for testing your setup\n",[1145,2733,2734,2737,2740,2742,2745,2747,2750,2752,2755],{"class":1147,"line":1523},[1145,2735,2736],{"class":1312},"@",[1145,2738,2666],{"class":2739},"sljsM",[1145,2741,2554],{"class":1312},[1145,2743,2744],{"class":2739},"task",[1145,2746,2218],{"class":1312},[1145,2748,2749],{"class":2243},"bind",[1145,2751,2247],{"class":1312},[1145,2753,2754],{"class":2043},"True",[1145,2756,2382],{"class":1312},[1145,2758,2759,2763,2766,2768,2772],{"class":1147,"line":1530},[1145,2760,2762],{"class":2761},"s5Kfy","def",[1145,2764,2765],{"class":2739}," debug_task",[1145,2767,2218],{"class":1312},[1145,2769,2771],{"class":2770},"sRjD_","self",[1145,2773,2774],{"class":1312},"):\n",[1145,2776,2777,2781,2785],{"class":1147,"line":1537},[1145,2778,2780],{"class":2779},"sm7ve","    \"\"\"",[1145,2782,2784],{"class":2783},"sVyVU","A simple task to test if Celery is working",[1145,2786,2787],{"class":2779},"\"\"\"\n",[1145,2789,2790,2794,2796,2799,2802,2806,2808,2810,2813,2816,2819,2821],{"class":1147,"line":1542},[1145,2791,2793],{"class":2792},"sJdAF","    print",[1145,2795,2218],{"class":1312},[1145,2797,2798],{"class":2761},"f",[1145,2800,2801],{"class":1162},"'Request: ",[1145,2803,2805],{"class":2804},"s3h35","{",[1145,2807,2771],{"class":1917},[1145,2809,2554],{"class":1312},[1145,2811,2812],{"class":2586},"request",[1145,2814,2815],{"class":2761},"!r",[1145,2817,2818],{"class":2804},"}",[1145,2820,1966],{"class":1162},[1145,2822,2382],{"class":1312},[1145,2824,2825,2828,2831],{"class":1147,"line":1550},[1145,2826,2827],{"class":1886},"    return",[1145,2829,2830],{"class":2761}," f",[1145,2832,2833],{"class":1162},"'Debug task executed successfully'\n",[1026,2835,2836],{},[1050,2837,2838],{},"Important concepts:",[1754,2840,2841,2847,2853,2859],{},[1047,2842,2843,2846],{},[1050,2844,2845],{},"App Instance",": Each service has its own Celery app instance. This allows them to run independently.",[1047,2848,2849,2852],{},[1050,2850,2851],{},"Settings Module",": We tell Celery which Django settings to use. This is crucial for database connections and other Django features.",[1047,2854,2855,2858],{},[1050,2856,2857],{},"Auto-discovery",": Celery automatically finds tasks in your Django apps, so you don't have to manually register them.",[1047,2860,2861,2864],{},[1050,2862,2863],{},"Debug Task",": Always include a simple test task to verify your setup is working.",[1026,2866,2867],{},"Now, make sure Celery is imported when Django starts:",[1135,2869,2871],{"className":1872,"code":2870,"language":1874,"meta":1140,"style":1140},"# user_service/__init__.py\nfrom .celery import app as celery_app\n\n# This ensures that the Celery app is loaded when Django starts\n__all__ = ('celery_app',)\n",[1142,2872,2873,2878,2899,2903,2908],{"__ignoreMap":1140},[1145,2874,2875],{"class":1147,"line":1148},[1145,2876,2877],{"class":1151},"# user_service/__init__.py\n",[1145,2879,2880,2882,2885,2888,2890,2893,2896],{"class":1147,"line":1155},[1145,2881,1887],{"class":1886},[1145,2883,2884],{"class":1312}," .",[1145,2886,2887],{"class":1890},"celery ",[1145,2889,1894],{"class":1886},[1145,2891,2892],{"class":1890}," app ",[1145,2894,2895],{"class":1886},"as",[1145,2897,2898],{"class":1890}," celery_app\n",[1145,2900,2901],{"class":1147,"line":1173},[1145,2902,1472],{"emptyLinePlaceholder":1471},[1145,2904,2905],{"class":1147,"line":1186},[1145,2906,2907],{"class":1151},"# This ensures that the Celery app is loaded when Django starts\n",[1145,2909,2910,2914,2916,2919,2921,2924,2926],{"class":1147,"line":1199},[1145,2911,2913],{"class":2912},"s131V","__all__",[1145,2915,1921],{"class":1312},[1145,2917,2918],{"class":1312}," (",[1145,2920,1966],{"class":1316},[1145,2922,2923],{"class":1162},"celery_app",[1145,2925,1966],{"class":1316},[1145,2927,2928],{"class":1312},",)\n",[1026,2930,2931],{},[1050,2932,2933],{},"Why this import is necessary:",[1044,2935,2936,2939,2942],{},[1047,2937,2938],{},"Django needs to know about your Celery app",[1047,2940,2941],{},"This import happens when Django starts up",[1047,2943,2944],{},"Without it, your tasks won't be registered properly",[1026,2946,2947],{},[1050,2948,2949],{},"Testing your setup:",[1135,2951,2953],{"className":1137,"code":2952,"language":1139,"meta":1140,"style":1140},"# Start a Celery worker for the user service\ncelery -A user_service worker --loglevel=info -Q user_queue\n\n# In another terminal, test the debug task\npython manage.py shell\n>>> from user_service.celery import debug_task\n>>> result = debug_task.delay()\n>>> print(result.get())\n",[1142,2954,2955,2960,2983,2987,2992,3002,3018,3032],{"__ignoreMap":1140},[1145,2956,2957],{"class":1147,"line":1148},[1145,2958,2959],{"class":1151},"# Start a Celery worker for the user service\n",[1145,2961,2962,2965,2968,2971,2974,2977,2980],{"class":1147,"line":1155},[1145,2963,2964],{"class":1158},"celery",[1145,2966,2967],{"class":1810}," -A",[1145,2969,2970],{"class":1162}," user_service",[1145,2972,2973],{"class":1162}," worker",[1145,2975,2976],{"class":1810}," --loglevel=info",[1145,2978,2979],{"class":1810}," -Q",[1145,2981,2982],{"class":1162}," user_queue\n",[1145,2984,2985],{"class":1147,"line":1173},[1145,2986,1472],{"emptyLinePlaceholder":1471},[1145,2988,2989],{"class":1147,"line":1186},[1145,2990,2991],{"class":1151},"# In another terminal, test the debug task\n",[1145,2993,2994,2996,2999],{"class":1147,"line":1199},[1145,2995,1874],{"class":1158},[1145,2997,2998],{"class":1162}," manage.py",[1145,3000,3001],{"class":1162}," shell\n",[1145,3003,3004,3007,3009,3012,3015],{"class":1147,"line":1351},[1145,3005,3006],{"class":1890},">>> ",[1145,3008,1887],{"class":1158},[1145,3010,3011],{"class":1162}," user_service.celery",[1145,3013,3014],{"class":1162}," import",[1145,3016,3017],{"class":1162}," debug_task\n",[1145,3019,3020,3022,3025,3027,3030],{"class":1147,"line":1362},[1145,3021,3006],{"class":1890},[1145,3023,3024],{"class":1158},"result",[1145,3026,1921],{"class":1162},[1145,3028,3029],{"class":1162}," debug_task.delay",[1145,3031,2722],{"class":1312},[1145,3033,3034,3036,3039,3041,3044],{"class":1147,"line":1370},[1145,3035,3006],{"class":1890},[1145,3037,3038],{"class":2792},"print",[1145,3040,2218],{"class":1890},[1145,3042,3043],{"class":1162},"result.get",[1145,3045,3046],{"class":1890},"())\n",[1030,3048,3050],{"id":3049},"implementing-task-based-communication","Implementing Task-Based Communication",[1026,3052,3053],{},"Now that we have Celery configured, let's create actual tasks that demonstrate how microservices can communicate and coordinate work. We'll start with the user service, which handles user-related operations.",[1246,3055,3057],{"id":3056},"understanding-celery-tasks","Understanding Celery Tasks",[1026,3059,3060,3061,3064,3065,3068],{},"A Celery task is simply a Python function decorated with ",[1142,3062,3063],{},"@shared_task"," or ",[1142,3066,3067],{},"@app.task",". When you call a task, instead of executing immediately, it gets serialized and sent to a message queue. A Celery worker then picks up the task and executes it.",[1026,3070,3071],{},[1050,3072,3073],{},"Key benefits of tasks:",[1044,3075,3076,3082,3088,3094],{},[1047,3077,3078,3081],{},[1050,3079,3080],{},"Asynchronous execution",": Your web request doesn't wait for the task to complete",[1047,3083,3084,3087],{},[1050,3085,3086],{},"Reliability",": Tasks are persisted in the queue and won't be lost if workers restart",[1047,3089,3090,3093],{},[1050,3091,3092],{},"Scalability",": You can run multiple workers to process tasks in parallel",[1047,3095,3096,3099],{},[1050,3097,3098],{},"Retry logic",": Tasks can automatically retry if they fail",[1246,3101,3103],{"id":3102},"user-service-tasks","User Service Tasks",[1026,3105,3106],{},"Let's create tasks for the user service that demonstrate common patterns:",[1135,3108,3110],{"className":1872,"code":3109,"language":1874,"meta":1140,"style":1140},"# user_service/tasks.py\nfrom celery import shared_task\nfrom django.core.mail import send_mail\nfrom django.contrib.auth.models import User\nfrom django.utils import timezone\nimport requests\nimport logging\n\n# Set up logging to track task execution\nlogger = logging.getLogger(__name__)\n\n@shared_task(bind=True, max_retries=3)\ndef send_welcome_email(self, user_id):\n    \"\"\"\n    Send welcome email to new user\n    \n    Args:\n        user_id: The ID of the user to send email to\n        \n    Returns:\n        str: Success message or raises exception\n        \n    This task demonstrates:\n    - Database access from tasks\n    - Email sending (I/O operation)\n    - Error handling and retries\n    - Logging for debugging\n    \"\"\"\n    try:\n        # Get user from database\n        # Note: We pass user_id instead of user object because\n        # Celery can only serialize simple data types (JSON)\n        user = User.objects.get(id=user_id)\n        \n        # Send the welcome email\n        send_mail(\n            subject='Welcome to Our Platform',\n            message=f'Hello {user.first_name}, welcome to our microservices platform!',\n            from_email='noreply@example.com',\n            recipient_list=[user.email],\n            fail_silently=False,  # Raise exception if email fails\n        )\n        \n        # Log successful execution\n        logger.info(f\"Welcome email sent to user {user_id}\")\n        return f\"Email sent to {user.email}\"\n        \n    except User.DoesNotExist:\n        # User not found - this is a permanent error, don't retry\n        logger.error(f\"User {user_id} not found\")\n        raise\n        \n    except Exception as exc:\n        # Email sending failed - this might be temporary, so retry\n        logger.error(f\"Failed to send email to user {user_id}: {exc}\")\n        \n        # Retry with exponential backoff\n        # First retry: 60 seconds, second: 120 seconds, third: 240 seconds\n        raise self.retry(exc=exc, countdown=60 * (2 ** self.request.retries))\n\n@shared_task\ndef update_user_profile(user_id, profile_data):\n    \"\"\"\n    Update user profile asynchronously\n    \n    This task demonstrates:\n    - Updating database records\n    - Triggering other tasks (task chaining)\n    - Error handling for data operations\n    \"\"\"\n    try:\n        user = User.objects.get(id=user_id)\n        \n        # Update user fields from profile_data\n        for field, value in profile_data.items():\n            if hasattr(user, field):\n                setattr(user, field, value)\n        \n        user.save()\n        \n        # Trigger another task to notify other services\n        # This is called \"task chaining\" - one task triggers another\n        notify_profile_update.delay(user_id, profile_data)\n        \n        logger.info(f\"Profile updated for user {user_id}\")\n        return f\"Profile updated for user {user_id}\"\n        \n    except User.DoesNotExist:\n        logger.error(f\"User {user_id} not found for profile update\")\n        raise\n    except Exception as exc:\n        logger.error(f\"Failed to update profile for user {user_id}: {exc}\")\n        raise\n\n@shared_task\ndef notify_profile_update(user_id, profile_data):\n    \"\"\"\n    Notify other services about profile updates\n    \n    This task demonstrates:\n    - Inter-service communication via HTTP\n    - Handling multiple service calls\n    - Graceful error handling for external services\n    \"\"\"\n    # List of services that need to know about profile updates\n    services = [\n        'http://order-service:8001/api/user-updated/',\n        'http://notification-service:8002/api/user-updated/',\n    ]\n    \n    # Prepare the payload to send to other services\n    payload = {\n        'user_id': user_id,\n        'profile_data': profile_data,\n        'timestamp': timezone.now().isoformat(),\n        'event_type': 'user_profile_updated'\n    }\n    \n    # Notify each service\n    for service_url in services:\n        try:\n            response = requests.post(\n                service_url,\n                json=payload,\n                timeout=10,  # Don't wait more than 10 seconds\n                headers={'Content-Type': 'application/json'}\n            )\n            response.raise_for_status()  # Raise exception for HTTP errors\n            \n            logger.info(f\"Notified {service_url} about user {user_id} update\")\n            \n        except requests.RequestException as exc:\n            # Log the error but don't fail the entire task\n            # In production, you might want to retry failed notifications\n            logger.error(f\"Failed to notify {service_url}: {exc}\")\n",[1142,3111,3112,3117,3128,3149,3175,3191,3198,3205,3209,3214,3236,3240,3267,3286,3291,3296,3301,3306,3311,3316,3321,3326,3330,3335,3340,3345,3350,3355,3359,3366,3371,3376,3381,3413,3417,3422,3430,3447,3475,3491,3509,3524,3530,3535,3541,3569,3592,3597,3612,3618,3646,3652,3657,3674,3680,3716,3721,3727,3733,3790,3795,3803,3822,3827,3833,3838,3843,3849,3855,3861,3866,3873,3900,3905,3911,3938,3957,3978,3983,3996,4001,4007,4013,4034,4039,4065,4082,4087,4100,4126,4131,4144,4178,4183,4188,4195,4213,4218,4224,4229,4234,4240,4246,4252,4257,4263,4274,4287,4299,4305,4310,4316,4326,4341,4357,4386,4405,4411,4416,4422,4438,4446,4464,4472,4485,4501,4528,4534,4551,4557,4595,4600,4619,4625,4631],{"__ignoreMap":1140},[1145,3113,3114],{"class":1147,"line":1148},[1145,3115,3116],{"class":1151},"# user_service/tasks.py\n",[1145,3118,3119,3121,3123,3125],{"class":1147,"line":1155},[1145,3120,1887],{"class":1886},[1145,3122,2539],{"class":1890},[1145,3124,1894],{"class":1886},[1145,3126,3127],{"class":1890}," shared_task\n",[1145,3129,3130,3132,3134,3136,3139,3141,3144,3146],{"class":1147,"line":1173},[1145,3131,1887],{"class":1886},[1145,3133,2551],{"class":1890},[1145,3135,2554],{"class":1312},[1145,3137,3138],{"class":1890},"core",[1145,3140,2554],{"class":1312},[1145,3142,3143],{"class":1890},"mail ",[1145,3145,1894],{"class":1886},[1145,3147,3148],{"class":1890}," send_mail\n",[1145,3150,3151,3153,3155,3157,3160,3162,3165,3167,3170,3172],{"class":1147,"line":1186},[1145,3152,1887],{"class":1886},[1145,3154,2551],{"class":1890},[1145,3156,2554],{"class":1312},[1145,3158,3159],{"class":1890},"contrib",[1145,3161,2554],{"class":1312},[1145,3163,3164],{"class":1890},"auth",[1145,3166,2554],{"class":1312},[1145,3168,3169],{"class":1890},"models ",[1145,3171,1894],{"class":1886},[1145,3173,3174],{"class":1890}," User\n",[1145,3176,3177,3179,3181,3183,3186,3188],{"class":1147,"line":1199},[1145,3178,1887],{"class":1886},[1145,3180,2551],{"class":1890},[1145,3182,2554],{"class":1312},[1145,3184,3185],{"class":1890},"utils ",[1145,3187,1894],{"class":1886},[1145,3189,3190],{"class":1890}," timezone\n",[1145,3192,3193,3195],{"class":1147,"line":1351},[1145,3194,1894],{"class":1886},[1145,3196,3197],{"class":1890}," requests\n",[1145,3199,3200,3202],{"class":1147,"line":1362},[1145,3201,1894],{"class":1886},[1145,3203,3204],{"class":1890}," logging\n",[1145,3206,3207],{"class":1147,"line":1370},[1145,3208,1472],{"emptyLinePlaceholder":1471},[1145,3210,3211],{"class":1147,"line":1388},[1145,3212,3213],{"class":1151},"# Set up logging to track task execution\n",[1145,3215,3216,3219,3221,3224,3226,3229,3231,3234],{"class":1147,"line":1403},[1145,3217,3218],{"class":1890},"logger ",[1145,3220,2247],{"class":1312},[1145,3222,3223],{"class":1890}," logging",[1145,3225,2554],{"class":1312},[1145,3227,3228],{"class":2214},"getLogger",[1145,3230,2218],{"class":1312},[1145,3232,3233],{"class":2912},"__name__",[1145,3235,2382],{"class":1312},[1145,3237,3238],{"class":1147,"line":1411},[1145,3239,1472],{"emptyLinePlaceholder":1471},[1145,3241,3242,3244,3247,3249,3251,3253,3255,3257,3260,3262,3265],{"class":1147,"line":1422},[1145,3243,2736],{"class":1312},[1145,3245,3246],{"class":2739},"shared_task",[1145,3248,2218],{"class":1312},[1145,3250,2749],{"class":2243},[1145,3252,2247],{"class":1312},[1145,3254,2754],{"class":2043},[1145,3256,1900],{"class":1312},[1145,3258,3259],{"class":2243}," max_retries",[1145,3261,2247],{"class":1312},[1145,3263,3264],{"class":1169},"3",[1145,3266,2382],{"class":1312},[1145,3268,3269,3271,3274,3276,3278,3280,3284],{"class":1147,"line":1433},[1145,3270,2762],{"class":2761},[1145,3272,3273],{"class":2739}," send_welcome_email",[1145,3275,2218],{"class":1312},[1145,3277,2771],{"class":2770},[1145,3279,1900],{"class":1312},[1145,3281,3283],{"class":3282},"sCyAa"," user_id",[1145,3285,2774],{"class":1312},[1145,3287,3288],{"class":1147,"line":1441},[1145,3289,3290],{"class":2779},"    \"\"\"\n",[1145,3292,3293],{"class":1147,"line":1452},[1145,3294,3295],{"class":2783},"    Send welcome email to new user\n",[1145,3297,3298],{"class":1147,"line":1460},[1145,3299,3300],{"class":2783},"    \n",[1145,3302,3303],{"class":1147,"line":1468},[1145,3304,3305],{"class":2783},"    Args:\n",[1145,3307,3308],{"class":1147,"line":1475},[1145,3309,3310],{"class":2783},"        user_id: The ID of the user to send email to\n",[1145,3312,3313],{"class":1147,"line":1483},[1145,3314,3315],{"class":2783},"        \n",[1145,3317,3318],{"class":1147,"line":1493},[1145,3319,3320],{"class":2783},"    Returns:\n",[1145,3322,3323],{"class":1147,"line":1503},[1145,3324,3325],{"class":2783},"        str: Success message or raises exception\n",[1145,3327,3328],{"class":1147,"line":1510},[1145,3329,3315],{"class":2783},[1145,3331,3332],{"class":1147,"line":1523},[1145,3333,3334],{"class":2783},"    This task demonstrates:\n",[1145,3336,3337],{"class":1147,"line":1530},[1145,3338,3339],{"class":2783},"    - Database access from tasks\n",[1145,3341,3342],{"class":1147,"line":1537},[1145,3343,3344],{"class":2783},"    - Email sending (I/O operation)\n",[1145,3346,3347],{"class":1147,"line":1542},[1145,3348,3349],{"class":2783},"    - Error handling and retries\n",[1145,3351,3352],{"class":1147,"line":1550},[1145,3353,3354],{"class":2783},"    - Logging for debugging\n",[1145,3356,3357],{"class":1147,"line":1561},[1145,3358,3290],{"class":2779},[1145,3360,3361,3364],{"class":1147,"line":1566},[1145,3362,3363],{"class":1886},"    try",[1145,3365,1331],{"class":1312},[1145,3367,3368],{"class":1147,"line":1574},[1145,3369,3370],{"class":1151},"        # Get user from database\n",[1145,3372,3373],{"class":1147,"line":1582},[1145,3374,3375],{"class":1151},"        # Note: We pass user_id instead of user object because\n",[1145,3377,3378],{"class":1147,"line":2379},[1145,3379,3380],{"class":1151},"        # Celery can only serialize simple data types (JSON)\n",[1145,3382,3383,3386,3388,3391,3393,3396,3398,3401,3403,3406,3408,3411],{"class":1147,"line":2385},[1145,3384,3385],{"class":1890},"        user ",[1145,3387,2247],{"class":1312},[1145,3389,3390],{"class":1890}," User",[1145,3392,2554],{"class":1312},[1145,3394,3395],{"class":2586},"objects",[1145,3397,2554],{"class":1312},[1145,3399,3400],{"class":2214},"get",[1145,3402,2218],{"class":1312},[1145,3404,3405],{"class":2243},"id",[1145,3407,2247],{"class":1312},[1145,3409,3410],{"class":2214},"user_id",[1145,3412,2382],{"class":1312},[1145,3414,3415],{"class":1147,"line":2390},[1145,3416,3315],{"class":1890},[1145,3418,3419],{"class":1147,"line":2396},[1145,3420,3421],{"class":1151},"        # Send the welcome email\n",[1145,3423,3424,3427],{"class":1147,"line":2410},[1145,3425,3426],{"class":2214},"        send_mail",[1145,3428,3429],{"class":1312},"(\n",[1145,3431,3432,3435,3437,3439,3442,3444],{"class":1147,"line":2424},[1145,3433,3434],{"class":2243},"            subject",[1145,3436,2247],{"class":1312},[1145,3438,1966],{"class":1316},[1145,3440,3441],{"class":1162},"Welcome to Our Platform",[1145,3443,1966],{"class":1316},[1145,3445,3446],{"class":1312},",\n",[1145,3448,3449,3452,3454,3456,3459,3461,3463,3465,3468,3470,3473],{"class":1147,"line":2438},[1145,3450,3451],{"class":2243},"            message",[1145,3453,2247],{"class":1312},[1145,3455,2798],{"class":2761},[1145,3457,3458],{"class":1162},"'Hello ",[1145,3460,2805],{"class":2804},[1145,3462,2279],{"class":2214},[1145,3464,2554],{"class":1312},[1145,3466,3467],{"class":2586},"first_name",[1145,3469,2818],{"class":2804},[1145,3471,3472],{"class":1162},", welcome to our microservices platform!'",[1145,3474,3446],{"class":1312},[1145,3476,3477,3480,3482,3484,3487,3489],{"class":1147,"line":2443},[1145,3478,3479],{"class":2243},"            from_email",[1145,3481,2247],{"class":1312},[1145,3483,1966],{"class":1316},[1145,3485,3486],{"class":1162},"noreply@example.com",[1145,3488,1966],{"class":1316},[1145,3490,3446],{"class":1312},[1145,3492,3493,3496,3499,3501,3503,3506],{"class":1147,"line":2449},[1145,3494,3495],{"class":2243},"            recipient_list",[1145,3497,3498],{"class":1312},"=[",[1145,3500,2279],{"class":2214},[1145,3502,2554],{"class":1312},[1145,3504,3505],{"class":2586},"email",[1145,3507,3508],{"class":1312},"],\n",[1145,3510,3511,3514,3516,3519,3521],{"class":1147,"line":2463},[1145,3512,3513],{"class":2243},"            fail_silently",[1145,3515,2247],{"class":1312},[1145,3517,3518],{"class":2043},"False",[1145,3520,1900],{"class":1312},[1145,3522,3523],{"class":1151},"  # Raise exception if email fails\n",[1145,3525,3527],{"class":1147,"line":3526},42,[1145,3528,3529],{"class":1312},"        )\n",[1145,3531,3533],{"class":1147,"line":3532},43,[1145,3534,3315],{"class":1890},[1145,3536,3538],{"class":1147,"line":3537},44,[1145,3539,3540],{"class":1151},"        # Log successful execution\n",[1145,3542,3544,3547,3549,3552,3554,3556,3559,3561,3563,3565,3567],{"class":1147,"line":3543},45,[1145,3545,3546],{"class":1890},"        logger",[1145,3548,2554],{"class":1312},[1145,3550,3551],{"class":2214},"info",[1145,3553,2218],{"class":1312},[1145,3555,2798],{"class":2761},[1145,3557,3558],{"class":1162},"\"Welcome email sent to user ",[1145,3560,2805],{"class":2804},[1145,3562,3410],{"class":2214},[1145,3564,2818],{"class":2804},[1145,3566,1382],{"class":1162},[1145,3568,2382],{"class":1312},[1145,3570,3572,3575,3577,3580,3582,3584,3586,3588,3590],{"class":1147,"line":3571},46,[1145,3573,3574],{"class":1886},"        return",[1145,3576,2830],{"class":2761},[1145,3578,3579],{"class":1162},"\"Email sent to ",[1145,3581,2805],{"class":2804},[1145,3583,2279],{"class":1890},[1145,3585,2554],{"class":1312},[1145,3587,3505],{"class":2586},[1145,3589,2818],{"class":2804},[1145,3591,1520],{"class":1162},[1145,3593,3595],{"class":1147,"line":3594},47,[1145,3596,3315],{"class":1890},[1145,3598,3600,3603,3605,3607,3610],{"class":1147,"line":3599},48,[1145,3601,3602],{"class":1886},"    except",[1145,3604,3390],{"class":1890},[1145,3606,2554],{"class":1312},[1145,3608,3609],{"class":2586},"DoesNotExist",[1145,3611,1331],{"class":1312},[1145,3613,3615],{"class":1147,"line":3614},49,[1145,3616,3617],{"class":1151},"        # User not found - this is a permanent error, don't retry\n",[1145,3619,3621,3623,3625,3628,3630,3632,3635,3637,3639,3641,3644],{"class":1147,"line":3620},50,[1145,3622,3546],{"class":1890},[1145,3624,2554],{"class":1312},[1145,3626,3627],{"class":2214},"error",[1145,3629,2218],{"class":1312},[1145,3631,2798],{"class":2761},[1145,3633,3634],{"class":1162},"\"User ",[1145,3636,2805],{"class":2804},[1145,3638,3410],{"class":2214},[1145,3640,2818],{"class":2804},[1145,3642,3643],{"class":1162}," not found\"",[1145,3645,2382],{"class":1312},[1145,3647,3649],{"class":1147,"line":3648},51,[1145,3650,3651],{"class":1886},"        raise\n",[1145,3653,3655],{"class":1147,"line":3654},52,[1145,3656,3315],{"class":1890},[1145,3658,3660,3662,3666,3669,3672],{"class":1147,"line":3659},53,[1145,3661,3602],{"class":1886},[1145,3663,3665],{"class":3664},"sa2tF"," Exception",[1145,3667,3668],{"class":1886}," as",[1145,3670,3671],{"class":1890}," exc",[1145,3673,1331],{"class":1312},[1145,3675,3677],{"class":1147,"line":3676},54,[1145,3678,3679],{"class":1151},"        # Email sending failed - this might be temporary, so retry\n",[1145,3681,3683,3685,3687,3689,3691,3693,3696,3698,3700,3702,3705,3707,3710,3712,3714],{"class":1147,"line":3682},55,[1145,3684,3546],{"class":1890},[1145,3686,2554],{"class":1312},[1145,3688,3627],{"class":2214},[1145,3690,2218],{"class":1312},[1145,3692,2798],{"class":2761},[1145,3694,3695],{"class":1162},"\"Failed to send email to user ",[1145,3697,2805],{"class":2804},[1145,3699,3410],{"class":2214},[1145,3701,2818],{"class":2804},[1145,3703,3704],{"class":1162},": ",[1145,3706,2805],{"class":2804},[1145,3708,3709],{"class":2214},"exc",[1145,3711,2818],{"class":2804},[1145,3713,1382],{"class":1162},[1145,3715,2382],{"class":1312},[1145,3717,3719],{"class":1147,"line":3718},56,[1145,3720,3315],{"class":1890},[1145,3722,3724],{"class":1147,"line":3723},57,[1145,3725,3726],{"class":1151},"        # Retry with exponential backoff\n",[1145,3728,3730],{"class":1147,"line":3729},58,[1145,3731,3732],{"class":1151},"        # First retry: 60 seconds, second: 120 seconds, third: 240 seconds\n",[1145,3734,3736,3739,3742,3744,3747,3749,3751,3753,3755,3757,3760,3762,3765,3768,3770,3773,3776,3778,3780,3782,3784,3787],{"class":1147,"line":3735},59,[1145,3737,3738],{"class":1886},"        raise",[1145,3740,3741],{"class":1917}," self",[1145,3743,2554],{"class":1312},[1145,3745,3746],{"class":2214},"retry",[1145,3748,2218],{"class":1312},[1145,3750,3709],{"class":2243},[1145,3752,2247],{"class":1312},[1145,3754,3709],{"class":2214},[1145,3756,1900],{"class":1312},[1145,3758,3759],{"class":2243}," countdown",[1145,3761,2247],{"class":1312},[1145,3763,3764],{"class":1169},"60",[1145,3766,3767],{"class":1814}," *",[1145,3769,2918],{"class":1312},[1145,3771,3772],{"class":1169},"2",[1145,3774,3775],{"class":1814}," **",[1145,3777,3741],{"class":1917},[1145,3779,2554],{"class":1312},[1145,3781,2812],{"class":2586},[1145,3783,2554],{"class":1312},[1145,3785,3786],{"class":2586},"retries",[1145,3788,3789],{"class":1312},"))\n",[1145,3791,3793],{"class":1147,"line":3792},60,[1145,3794,1472],{"emptyLinePlaceholder":1471},[1145,3796,3798,3800],{"class":1147,"line":3797},61,[1145,3799,2736],{"class":1312},[1145,3801,3802],{"class":2739},"shared_task\n",[1145,3804,3806,3808,3811,3813,3815,3817,3820],{"class":1147,"line":3805},62,[1145,3807,2762],{"class":2761},[1145,3809,3810],{"class":2739}," update_user_profile",[1145,3812,2218],{"class":1312},[1145,3814,3410],{"class":3282},[1145,3816,1900],{"class":1312},[1145,3818,3819],{"class":3282}," profile_data",[1145,3821,2774],{"class":1312},[1145,3823,3825],{"class":1147,"line":3824},63,[1145,3826,3290],{"class":2779},[1145,3828,3830],{"class":1147,"line":3829},64,[1145,3831,3832],{"class":2783},"    Update user profile asynchronously\n",[1145,3834,3836],{"class":1147,"line":3835},65,[1145,3837,3300],{"class":2783},[1145,3839,3841],{"class":1147,"line":3840},66,[1145,3842,3334],{"class":2783},[1145,3844,3846],{"class":1147,"line":3845},67,[1145,3847,3848],{"class":2783},"    - Updating database records\n",[1145,3850,3852],{"class":1147,"line":3851},68,[1145,3853,3854],{"class":2783},"    - Triggering other tasks (task chaining)\n",[1145,3856,3858],{"class":1147,"line":3857},69,[1145,3859,3860],{"class":2783},"    - Error handling for data operations\n",[1145,3862,3864],{"class":1147,"line":3863},70,[1145,3865,3290],{"class":2779},[1145,3867,3869,3871],{"class":1147,"line":3868},71,[1145,3870,3363],{"class":1886},[1145,3872,1331],{"class":1312},[1145,3874,3876,3878,3880,3882,3884,3886,3888,3890,3892,3894,3896,3898],{"class":1147,"line":3875},72,[1145,3877,3385],{"class":1890},[1145,3879,2247],{"class":1312},[1145,3881,3390],{"class":1890},[1145,3883,2554],{"class":1312},[1145,3885,3395],{"class":2586},[1145,3887,2554],{"class":1312},[1145,3889,3400],{"class":2214},[1145,3891,2218],{"class":1312},[1145,3893,3405],{"class":2243},[1145,3895,2247],{"class":1312},[1145,3897,3410],{"class":2214},[1145,3899,2382],{"class":1312},[1145,3901,3903],{"class":1147,"line":3902},73,[1145,3904,3315],{"class":1890},[1145,3906,3908],{"class":1147,"line":3907},74,[1145,3909,3910],{"class":1151},"        # Update user fields from profile_data\n",[1145,3912,3914,3917,3920,3922,3925,3928,3930,3932,3935],{"class":1147,"line":3913},75,[1145,3915,3916],{"class":1886},"        for",[1145,3918,3919],{"class":1890}," field",[1145,3921,1900],{"class":1312},[1145,3923,3924],{"class":1890}," value ",[1145,3926,3927],{"class":1886},"in",[1145,3929,3819],{"class":1890},[1145,3931,2554],{"class":1312},[1145,3933,3934],{"class":2214},"items",[1145,3936,3937],{"class":1312},"():\n",[1145,3939,3941,3944,3947,3949,3951,3953,3955],{"class":1147,"line":3940},76,[1145,3942,3943],{"class":1886},"            if",[1145,3945,3946],{"class":2792}," hasattr",[1145,3948,2218],{"class":1312},[1145,3950,2279],{"class":2214},[1145,3952,1900],{"class":1312},[1145,3954,3919],{"class":2214},[1145,3956,2774],{"class":1312},[1145,3958,3960,3963,3965,3967,3969,3971,3973,3976],{"class":1147,"line":3959},77,[1145,3961,3962],{"class":2792},"                setattr",[1145,3964,2218],{"class":1312},[1145,3966,2279],{"class":2214},[1145,3968,1900],{"class":1312},[1145,3970,3919],{"class":2214},[1145,3972,1900],{"class":1312},[1145,3974,3975],{"class":2214}," value",[1145,3977,2382],{"class":1312},[1145,3979,3981],{"class":1147,"line":3980},78,[1145,3982,3315],{"class":1890},[1145,3984,3986,3989,3991,3994],{"class":1147,"line":3985},79,[1145,3987,3988],{"class":1890},"        user",[1145,3990,2554],{"class":1312},[1145,3992,3993],{"class":2214},"save",[1145,3995,2722],{"class":1312},[1145,3997,3999],{"class":1147,"line":3998},80,[1145,4000,3315],{"class":1890},[1145,4002,4004],{"class":1147,"line":4003},81,[1145,4005,4006],{"class":1151},"        # Trigger another task to notify other services\n",[1145,4008,4010],{"class":1147,"line":4009},82,[1145,4011,4012],{"class":1151},"        # This is called \"task chaining\" - one task triggers another\n",[1145,4014,4016,4019,4021,4024,4026,4028,4030,4032],{"class":1147,"line":4015},83,[1145,4017,4018],{"class":1890},"        notify_profile_update",[1145,4020,2554],{"class":1312},[1145,4022,4023],{"class":2214},"delay",[1145,4025,2218],{"class":1312},[1145,4027,3410],{"class":2214},[1145,4029,1900],{"class":1312},[1145,4031,3819],{"class":2214},[1145,4033,2382],{"class":1312},[1145,4035,4037],{"class":1147,"line":4036},84,[1145,4038,3315],{"class":1890},[1145,4040,4042,4044,4046,4048,4050,4052,4055,4057,4059,4061,4063],{"class":1147,"line":4041},85,[1145,4043,3546],{"class":1890},[1145,4045,2554],{"class":1312},[1145,4047,3551],{"class":2214},[1145,4049,2218],{"class":1312},[1145,4051,2798],{"class":2761},[1145,4053,4054],{"class":1162},"\"Profile updated for user ",[1145,4056,2805],{"class":2804},[1145,4058,3410],{"class":2214},[1145,4060,2818],{"class":2804},[1145,4062,1382],{"class":1162},[1145,4064,2382],{"class":1312},[1145,4066,4068,4070,4072,4074,4076,4078,4080],{"class":1147,"line":4067},86,[1145,4069,3574],{"class":1886},[1145,4071,2830],{"class":2761},[1145,4073,4054],{"class":1162},[1145,4075,2805],{"class":2804},[1145,4077,3410],{"class":1890},[1145,4079,2818],{"class":2804},[1145,4081,1520],{"class":1162},[1145,4083,4085],{"class":1147,"line":4084},87,[1145,4086,3315],{"class":1890},[1145,4088,4090,4092,4094,4096,4098],{"class":1147,"line":4089},88,[1145,4091,3602],{"class":1886},[1145,4093,3390],{"class":1890},[1145,4095,2554],{"class":1312},[1145,4097,3609],{"class":2586},[1145,4099,1331],{"class":1312},[1145,4101,4103,4105,4107,4109,4111,4113,4115,4117,4119,4121,4124],{"class":1147,"line":4102},89,[1145,4104,3546],{"class":1890},[1145,4106,2554],{"class":1312},[1145,4108,3627],{"class":2214},[1145,4110,2218],{"class":1312},[1145,4112,2798],{"class":2761},[1145,4114,3634],{"class":1162},[1145,4116,2805],{"class":2804},[1145,4118,3410],{"class":2214},[1145,4120,2818],{"class":2804},[1145,4122,4123],{"class":1162}," not found for profile update\"",[1145,4125,2382],{"class":1312},[1145,4127,4129],{"class":1147,"line":4128},90,[1145,4130,3651],{"class":1886},[1145,4132,4134,4136,4138,4140,4142],{"class":1147,"line":4133},91,[1145,4135,3602],{"class":1886},[1145,4137,3665],{"class":3664},[1145,4139,3668],{"class":1886},[1145,4141,3671],{"class":1890},[1145,4143,1331],{"class":1312},[1145,4145,4147,4149,4151,4153,4155,4157,4160,4162,4164,4166,4168,4170,4172,4174,4176],{"class":1147,"line":4146},92,[1145,4148,3546],{"class":1890},[1145,4150,2554],{"class":1312},[1145,4152,3627],{"class":2214},[1145,4154,2218],{"class":1312},[1145,4156,2798],{"class":2761},[1145,4158,4159],{"class":1162},"\"Failed to update profile for user ",[1145,4161,2805],{"class":2804},[1145,4163,3410],{"class":2214},[1145,4165,2818],{"class":2804},[1145,4167,3704],{"class":1162},[1145,4169,2805],{"class":2804},[1145,4171,3709],{"class":2214},[1145,4173,2818],{"class":2804},[1145,4175,1382],{"class":1162},[1145,4177,2382],{"class":1312},[1145,4179,4181],{"class":1147,"line":4180},93,[1145,4182,3651],{"class":1886},[1145,4184,4186],{"class":1147,"line":4185},94,[1145,4187,1472],{"emptyLinePlaceholder":1471},[1145,4189,4191,4193],{"class":1147,"line":4190},95,[1145,4192,2736],{"class":1312},[1145,4194,3802],{"class":2739},[1145,4196,4198,4200,4203,4205,4207,4209,4211],{"class":1147,"line":4197},96,[1145,4199,2762],{"class":2761},[1145,4201,4202],{"class":2739}," notify_profile_update",[1145,4204,2218],{"class":1312},[1145,4206,3410],{"class":3282},[1145,4208,1900],{"class":1312},[1145,4210,3819],{"class":3282},[1145,4212,2774],{"class":1312},[1145,4214,4216],{"class":1147,"line":4215},97,[1145,4217,3290],{"class":2779},[1145,4219,4221],{"class":1147,"line":4220},98,[1145,4222,4223],{"class":2783},"    Notify other services about profile updates\n",[1145,4225,4227],{"class":1147,"line":4226},99,[1145,4228,3300],{"class":2783},[1145,4230,4232],{"class":1147,"line":4231},100,[1145,4233,3334],{"class":2783},[1145,4235,4237],{"class":1147,"line":4236},101,[1145,4238,4239],{"class":2783},"    - Inter-service communication via HTTP\n",[1145,4241,4243],{"class":1147,"line":4242},102,[1145,4244,4245],{"class":2783},"    - Handling multiple service calls\n",[1145,4247,4249],{"class":1147,"line":4248},103,[1145,4250,4251],{"class":2783},"    - Graceful error handling for external services\n",[1145,4253,4255],{"class":1147,"line":4254},104,[1145,4256,3290],{"class":2779},[1145,4258,4260],{"class":1147,"line":4259},105,[1145,4261,4262],{"class":1151},"    # List of services that need to know about profile updates\n",[1145,4264,4266,4269,4271],{"class":1147,"line":4265},106,[1145,4267,4268],{"class":1890},"    services ",[1145,4270,2247],{"class":1312},[1145,4272,4273],{"class":1312}," [\n",[1145,4275,4277,4280,4283,4285],{"class":1147,"line":4276},107,[1145,4278,4279],{"class":1316},"        '",[1145,4281,4282],{"class":1162},"http://order-service:8001/api/user-updated/",[1145,4284,1966],{"class":1316},[1145,4286,3446],{"class":1312},[1145,4288,4290,4292,4295,4297],{"class":1147,"line":4289},108,[1145,4291,4279],{"class":1316},[1145,4293,4294],{"class":1162},"http://notification-service:8002/api/user-updated/",[1145,4296,1966],{"class":1316},[1145,4298,3446],{"class":1312},[1145,4300,4302],{"class":1147,"line":4301},109,[1145,4303,4304],{"class":1312},"    ]\n",[1145,4306,4308],{"class":1147,"line":4307},110,[1145,4309,3300],{"class":1890},[1145,4311,4313],{"class":1147,"line":4312},111,[1145,4314,4315],{"class":1151},"    # Prepare the payload to send to other services\n",[1145,4317,4319,4322,4324],{"class":1147,"line":4318},112,[1145,4320,4321],{"class":1890},"    payload ",[1145,4323,2247],{"class":1312},[1145,4325,2068],{"class":1312},[1145,4327,4329,4331,4333,4335,4337,4339],{"class":1147,"line":4328},113,[1145,4330,4279],{"class":1316},[1145,4332,3410],{"class":1162},[1145,4334,1966],{"class":1316},[1145,4336,1313],{"class":1312},[1145,4338,3283],{"class":1890},[1145,4340,3446],{"class":1312},[1145,4342,4344,4346,4349,4351,4353,4355],{"class":1147,"line":4343},114,[1145,4345,4279],{"class":1316},[1145,4347,4348],{"class":1162},"profile_data",[1145,4350,1966],{"class":1316},[1145,4352,1313],{"class":1312},[1145,4354,3819],{"class":1890},[1145,4356,3446],{"class":1312},[1145,4358,4360,4362,4365,4367,4369,4372,4374,4377,4380,4383],{"class":1147,"line":4359},115,[1145,4361,4279],{"class":1316},[1145,4363,4364],{"class":1162},"timestamp",[1145,4366,1966],{"class":1316},[1145,4368,1313],{"class":1312},[1145,4370,4371],{"class":1890}," timezone",[1145,4373,2554],{"class":1312},[1145,4375,4376],{"class":2214},"now",[1145,4378,4379],{"class":1312},"().",[1145,4381,4382],{"class":2214},"isoformat",[1145,4384,4385],{"class":1312},"(),\n",[1145,4387,4389,4391,4394,4396,4398,4400,4403],{"class":1147,"line":4388},116,[1145,4390,4279],{"class":1316},[1145,4392,4393],{"class":1162},"event_type",[1145,4395,1966],{"class":1316},[1145,4397,1313],{"class":1312},[1145,4399,1317],{"class":1316},[1145,4401,4402],{"class":1162},"user_profile_updated",[1145,4404,1323],{"class":1316},[1145,4406,4408],{"class":1147,"line":4407},117,[1145,4409,4410],{"class":1312},"    }\n",[1145,4412,4414],{"class":1147,"line":4413},118,[1145,4415,3300],{"class":1890},[1145,4417,4419],{"class":1147,"line":4418},119,[1145,4420,4421],{"class":1151},"    # Notify each service\n",[1145,4423,4425,4428,4431,4433,4436],{"class":1147,"line":4424},120,[1145,4426,4427],{"class":1886},"    for",[1145,4429,4430],{"class":1890}," service_url ",[1145,4432,3927],{"class":1886},[1145,4434,4435],{"class":1890}," services",[1145,4437,1331],{"class":1312},[1145,4439,4441,4444],{"class":1147,"line":4440},121,[1145,4442,4443],{"class":1886},"        try",[1145,4445,1331],{"class":1312},[1145,4447,4449,4452,4454,4457,4459,4462],{"class":1147,"line":4448},122,[1145,4450,4451],{"class":1890},"            response ",[1145,4453,2247],{"class":1312},[1145,4455,4456],{"class":1890}," requests",[1145,4458,2554],{"class":1312},[1145,4460,4461],{"class":2214},"post",[1145,4463,3429],{"class":1312},[1145,4465,4467,4470],{"class":1147,"line":4466},123,[1145,4468,4469],{"class":2214},"                service_url",[1145,4471,3446],{"class":1312},[1145,4473,4475,4478,4480,4483],{"class":1147,"line":4474},124,[1145,4476,4477],{"class":2243},"                json",[1145,4479,2247],{"class":1312},[1145,4481,4482],{"class":2214},"payload",[1145,4484,3446],{"class":1312},[1145,4486,4488,4491,4493,4496,4498],{"class":1147,"line":4487},125,[1145,4489,4490],{"class":2243},"                timeout",[1145,4492,2247],{"class":1312},[1145,4494,4495],{"class":1169},"10",[1145,4497,1900],{"class":1312},[1145,4499,4500],{"class":1151},"  # Don't wait more than 10 seconds\n",[1145,4502,4504,4507,4510,4512,4515,4517,4519,4521,4524,4526],{"class":1147,"line":4503},126,[1145,4505,4506],{"class":2243},"                headers",[1145,4508,4509],{"class":1312},"={",[1145,4511,1966],{"class":1316},[1145,4513,4514],{"class":1162},"Content-Type",[1145,4516,1966],{"class":1316},[1145,4518,1313],{"class":1312},[1145,4520,1317],{"class":1316},[1145,4522,4523],{"class":1162},"application/json",[1145,4525,1966],{"class":1316},[1145,4527,2176],{"class":1312},[1145,4529,4531],{"class":1147,"line":4530},127,[1145,4532,4533],{"class":1312},"            )\n",[1145,4535,4537,4540,4542,4545,4548],{"class":1147,"line":4536},128,[1145,4538,4539],{"class":1890},"            response",[1145,4541,2554],{"class":1312},[1145,4543,4544],{"class":2214},"raise_for_status",[1145,4546,4547],{"class":1312},"()",[1145,4549,4550],{"class":1151},"  # Raise exception for HTTP errors\n",[1145,4552,4554],{"class":1147,"line":4553},129,[1145,4555,4556],{"class":1890},"            \n",[1145,4558,4560,4563,4565,4567,4569,4571,4574,4576,4579,4581,4584,4586,4588,4590,4593],{"class":1147,"line":4559},130,[1145,4561,4562],{"class":1890},"            logger",[1145,4564,2554],{"class":1312},[1145,4566,3551],{"class":2214},[1145,4568,2218],{"class":1312},[1145,4570,2798],{"class":2761},[1145,4572,4573],{"class":1162},"\"Notified ",[1145,4575,2805],{"class":2804},[1145,4577,4578],{"class":2214},"service_url",[1145,4580,2818],{"class":2804},[1145,4582,4583],{"class":1162}," about user ",[1145,4585,2805],{"class":2804},[1145,4587,3410],{"class":2214},[1145,4589,2818],{"class":2804},[1145,4591,4592],{"class":1162}," update\"",[1145,4594,2382],{"class":1312},[1145,4596,4598],{"class":1147,"line":4597},131,[1145,4599,4556],{"class":1890},[1145,4601,4603,4606,4608,4610,4613,4615,4617],{"class":1147,"line":4602},132,[1145,4604,4605],{"class":1886},"        except",[1145,4607,4456],{"class":1890},[1145,4609,2554],{"class":1312},[1145,4611,4612],{"class":2586},"RequestException",[1145,4614,3668],{"class":1886},[1145,4616,3671],{"class":1890},[1145,4618,1331],{"class":1312},[1145,4620,4622],{"class":1147,"line":4621},133,[1145,4623,4624],{"class":1151},"            # Log the error but don't fail the entire task\n",[1145,4626,4628],{"class":1147,"line":4627},134,[1145,4629,4630],{"class":1151},"            # In production, you might want to retry failed notifications\n",[1145,4632,4634,4636,4638,4640,4642,4644,4647,4649,4651,4653,4655,4657,4659,4661,4663],{"class":1147,"line":4633},135,[1145,4635,4562],{"class":1890},[1145,4637,2554],{"class":1312},[1145,4639,3627],{"class":2214},[1145,4641,2218],{"class":1312},[1145,4643,2798],{"class":2761},[1145,4645,4646],{"class":1162},"\"Failed to notify ",[1145,4648,2805],{"class":2804},[1145,4650,4578],{"class":2214},[1145,4652,2818],{"class":2804},[1145,4654,3704],{"class":1162},[1145,4656,2805],{"class":2804},[1145,4658,3709],{"class":2214},[1145,4660,2818],{"class":2804},[1145,4662,1382],{"class":1162},[1145,4664,2382],{"class":1312},[1026,4666,4667],{},[1050,4668,4669],{},"Key patterns demonstrated:",[1754,4671,4672,4678,4684,4689],{},[1047,4673,4674,4677],{},[1050,4675,4676],{},"Error Handling",": Different types of errors are handled differently. Permanent errors (like user not found) don't retry, while temporary errors (like network issues) do.",[1047,4679,4680,4683],{},[1050,4681,4682],{},"Task Chaining",": One task can trigger another task, allowing you to build complex workflows.",[1047,4685,4686,4688],{},[1050,4687,1058],{},": Tasks can make HTTP calls to other services, enabling loose coupling between services.",[1047,4690,4691,4694],{},[1050,4692,4693],{},"Logging",": Comprehensive logging helps with debugging and monitoring in production.",[1246,4696,4698],{"id":4697},"order-service-tasks","Order Service Tasks",[1026,4700,4701],{},"The order service demonstrates more complex orchestration patterns. Order processing typically involves multiple steps that must happen in sequence, and some steps can happen in parallel. Let's see how Celery handles these scenarios:",[1135,4703,4705],{"className":1872,"code":4704,"language":1874,"meta":1140,"style":1140},"# order_service/tasks.py\nfrom celery import shared_task, group, chain, chord\nfrom django.utils import timezone\nfrom .models import Order, OrderItem\nimport requests\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n@shared_task(bind=True, max_retries=3)\ndef process_order(self, order_id):\n    \"\"\"\n    Main order processing task that orchestrates the entire workflow\n    \n    This task demonstrates:\n    - Complex workflow orchestration\n    - Using Celery's chain primitive for sequential tasks\n    - Error handling for business processes\n    - Database state management\n    \"\"\"\n    try:\n        # Get the order from database\n        order = Order.objects.get(id=order_id)\n        \n        # Update order status to indicate processing has started\n        order.status = 'processing'\n        order.processing_started_at = timezone.now()\n        order.save()\n        \n        # Create a workflow chain - these tasks will execute in sequence\n        # Each task passes its result to the next task\n        workflow = chain(\n            validate_inventory.s(order_id),      # Step 1: Check if items are in stock\n            calculate_shipping.s(),              # Step 2: Calculate shipping costs\n            process_payment.s(),                 # Step 3: Process payment\n            send_confirmation.s()                # Step 4: Send confirmation email\n        )\n        \n        # Execute the workflow asynchronously\n        result = workflow.apply_async()\n        \n        logger.info(f\"Order {order_id} processing workflow initiated\")\n        return f\"Order {order_id} processing initiated\"\n        \n    except Order.DoesNotExist:\n        logger.error(f\"Order {order_id} not found\")\n        raise\n    except Exception as exc:\n        logger.error(f\"Failed to process order {order_id}: {exc}\")\n        # Update order status to failed\n        try:\n            order = Order.objects.get(id=order_id)\n            order.status = 'failed'\n            order.error_message = str(exc)\n            order.save()\n        except:\n            pass  # Don't fail if we can't update status\n        \n        raise self.retry(exc=exc, countdown=60)\n\n@shared_task\ndef validate_inventory(order_id):\n    \"\"\"\n    Validate that all items in the order are available in inventory\n    \n    This task demonstrates:\n    - External service communication\n    - Business logic validation\n    - Error handling for business rules\n    \"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    logger.info(f\"Validating inventory for order {order_id}\")\n    \n    # Check inventory for each item in the order\n    for item in order.items.all():\n        try:\n            # Call the inventory service to check stock\n            response = requests.post(\n                'http://inventory-service:8003/api/check-stock/',\n                json={\n                    'product_id': item.product_id,\n                    'quantity': item.quantity\n                },\n                timeout=10\n            )\n            response.raise_for_status()\n            \n            stock_data = response.json()\n            if not stock_data.get('available'):\n                # Not enough stock - this is a business rule violation\n                raise Exception(f\"Insufficient stock for product {item.product_id}\")\n                \n            logger.info(f\"Stock validated for product {item.product_id}\")\n            \n        except requests.RequestException as exc:\n            logger.error(f\"Failed to check stock for product {item.product_id}: {exc}\")\n            raise Exception(f\"Inventory service unavailable: {exc}\")\n    \n    logger.info(f\"All items validated for order {order_id}\")\n    return order_id  # Pass order_id to next task in chain\n\n@shared_task\ndef calculate_shipping(order_id):\n    \"\"\"\n    Calculate shipping costs for the order\n    \n    This task demonstrates:\n    - External service integration\n    - Data enrichment (adding calculated fields)\n    - Error handling for calculations\n    \"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    logger.info(f\"Calculating shipping for order {order_id}\")\n    \n    try:\n        # Call shipping service to calculate costs\n        response = requests.post(\n            'http://shipping-service:8004/api/calculate/',\n            json={\n                'order_id': order_id,\n                'destination': order.shipping_address,\n                'weight': order.total_weight,\n                'items': [\n                    {\n                        'product_id': item.product_id,\n                        'quantity': item.quantity,\n                        'weight': item.weight\n                    }\n                    for item in order.items.all()\n                ]\n            },\n            timeout=15\n        )\n        response.raise_for_status()\n        \n        shipping_data = response.json()\n        shipping_cost = shipping_data.get('cost', 0)\n        estimated_delivery = shipping_data.get('estimated_delivery')\n        \n        # Update order with shipping information\n        order.shipping_cost = shipping_cost\n        order.estimated_delivery = estimated_delivery\n        order.total_amount = order.subtotal + shipping_cost\n        order.save()\n        \n        logger.info(f\"Shipping calculated for order {order_id}: ${shipping_cost}\")\n        return order_id\n        \n    except requests.RequestException as exc:\n        logger.error(f\"Failed to calculate shipping for order {order_id}: {exc}\")\n        raise Exception(f\"Shipping service unavailable: {exc}\")\n\n@shared_task\ndef process_payment(order_id):\n    \"\"\"\n    Process payment for the order\n    \n    This task demonstrates:\n    - Critical business operations\n    - Transaction handling\n    - External payment processing\n    - Detailed error handling\n    \"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    logger.info(f\"Processing payment for order {order_id}\")\n    \n    try:\n        # Call payment service to charge the customer\n        response = requests.post(\n            'http://payment-service:8005/api/charge/',\n            json={\n                'order_id': order_id,\n                'amount': float(order.total_amount),\n                'currency': 'USD',\n                'payment_method': order.payment_method,\n                'customer_id': order.user_id,\n                'description': f'Order #{order_id}'\n            },\n            timeout=30  # Payment processing might take longer\n        )\n        response.raise_for_status()\n        \n        payment_data = response.json()\n        \n        if payment_data.get('success'):\n            # Payment successful - update order\n            order.status = 'paid'\n            order.payment_id = payment_data.get('payment_id')\n            order.paid_at = timezone.now()\n            order.save()\n            \n            logger.info(f\"Payment processed for order {order_id}: {payment_data.get('payment_id')}\")\n            return order_id\n        else:\n            # Payment failed\n            error_message = payment_data.get('error', 'Payment processing failed')\n            logger.error(f\"Payment failed for order {order_id}: {error_message}\")\n            raise Exception(f\"Payment failed: {error_message}\")\n            \n    except requests.RequestException as exc:\n        logger.error(f\"Payment service error for order {order_id}: {exc}\")\n        raise Exception(f\"Payment service unavailable: {exc}\")\n\n@shared_task\ndef send_confirmation(order_id):\n    \"\"\"\n    Send order confirmation to customer\n    \n    This task demonstrates:\n    - Final step in workflow\n    - Customer communication\n    - Order completion\n    \"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    logger.info(f\"Sending confirmation for order {order_id}\")\n    \n    # Send confirmation email to customer\n    send_order_email.delay(\n        order.user.email,\n        'Order Confirmation',\n        f'Your order #{order_id} has been confirmed and will be shipped soon!'\n    )\n    \n    # Update final order status\n    order.status = 'confirmed'\n    order.confirmed_at = timezone.now()\n    order.save()\n    \n    logger.info(f\"Order {order_id} confirmed and customer notified\")\n    return f\"Order {order_id} confirmed\"\n\n@shared_task\ndef send_order_email(email, subject, message):\n    \"\"\"\n    Send order-related emails\n    \n    This is a utility task that can be reused for different types of order emails\n    \"\"\"\n    try:\n        from django.core.mail import send_mail\n        \n        send_mail(\n            subject,\n            message,\n            'orders@example.com',\n            [email],\n            fail_silently=False,\n        )\n        \n        logger.info(f\"Order email sent to {email}\")\n        return f\"Email sent to {email}\"\n        \n    except Exception as exc:\n        logger.error(f\"Failed to send email to {email}: {exc}\")\n        raise\n",[1142,4706,4707,4712,4738,4752,4770,4776,4782,4786,4804,4808,4832,4850,4854,4859,4863,4867,4872,4877,4882,4887,4891,4897,4902,4930,4934,4939,4958,4977,4987,4991,4996,5001,5012,5031,5046,5060,5074,5078,5082,5087,5104,5108,5134,5151,5155,5167,5191,5195,5207,5240,5245,5251,5278,5296,5316,5326,5332,5340,5344,5372,5376,5382,5395,5399,5404,5408,5412,5417,5422,5427,5431,5458,5462,5488,5492,5497,5520,5526,5531,5545,5557,5564,5585,5603,5608,5617,5621,5631,5635,5651,5676,5681,5710,5715,5744,5748,5764,5801,5825,5829,5854,5864,5868,5874,5887,5891,5896,5900,5904,5909,5914,5919,5923,5949,5953,5978,5982,5988,5993,6008,6020,6027,6041,6061,6081,6093,6098,6117,6135,6152,6157,6178,6183,6188,6198,6202,6214,6219,6235,6266,6291,6296,6302,6317,6331,6355,6366,6371,6406,6414,6419,6436,6470,6494,6499,6506,6520,6525,6531,6536,6541,6547,6553,6559,6565,6570,6597,6602,6628,6633,6640,6646,6661,6673,6680,6695,6720,6741,6761,6781,6806,6811,6824,6829,6840,6845,6861,6866,6890,6896,6914,6942,6962,6973,6978,7027,7035,7043,7049,7082,7116,7140,7145,7162,7196,7220,7225,7232,7246,7251,7257,7262,7267,7273,7279,7285,7290,7317,7322,7348,7353,7359,7371,7386,7398,7416,7422,7427,7433,7452,7472,7483,7488,7514,7532,7537,7544,7568,7573,7579,7584,7590,7595,7602,7622,7627,7634,7641,7648,7660,7670,7681,7686,7691,7717,7734,7739,7752,7786],{"__ignoreMap":1140},[1145,4708,4709],{"class":1147,"line":1148},[1145,4710,4711],{"class":1151},"# order_service/tasks.py\n",[1145,4713,4714,4716,4718,4720,4723,4725,4728,4730,4733,4735],{"class":1147,"line":1155},[1145,4715,1887],{"class":1886},[1145,4717,2539],{"class":1890},[1145,4719,1894],{"class":1886},[1145,4721,4722],{"class":1890}," shared_task",[1145,4724,1900],{"class":1312},[1145,4726,4727],{"class":1890}," group",[1145,4729,1900],{"class":1312},[1145,4731,4732],{"class":1890}," chain",[1145,4734,1900],{"class":1312},[1145,4736,4737],{"class":1890}," chord\n",[1145,4739,4740,4742,4744,4746,4748,4750],{"class":1147,"line":1173},[1145,4741,1887],{"class":1886},[1145,4743,2551],{"class":1890},[1145,4745,2554],{"class":1312},[1145,4747,3185],{"class":1890},[1145,4749,1894],{"class":1886},[1145,4751,3190],{"class":1890},[1145,4753,4754,4756,4758,4760,4762,4765,4767],{"class":1147,"line":1186},[1145,4755,1887],{"class":1886},[1145,4757,2884],{"class":1312},[1145,4759,3169],{"class":1890},[1145,4761,1894],{"class":1886},[1145,4763,4764],{"class":1890}," Order",[1145,4766,1900],{"class":1312},[1145,4768,4769],{"class":1890}," OrderItem\n",[1145,4771,4772,4774],{"class":1147,"line":1199},[1145,4773,1894],{"class":1886},[1145,4775,3197],{"class":1890},[1145,4777,4778,4780],{"class":1147,"line":1351},[1145,4779,1894],{"class":1886},[1145,4781,3204],{"class":1890},[1145,4783,4784],{"class":1147,"line":1362},[1145,4785,1472],{"emptyLinePlaceholder":1471},[1145,4787,4788,4790,4792,4794,4796,4798,4800,4802],{"class":1147,"line":1370},[1145,4789,3218],{"class":1890},[1145,4791,2247],{"class":1312},[1145,4793,3223],{"class":1890},[1145,4795,2554],{"class":1312},[1145,4797,3228],{"class":2214},[1145,4799,2218],{"class":1312},[1145,4801,3233],{"class":2912},[1145,4803,2382],{"class":1312},[1145,4805,4806],{"class":1147,"line":1388},[1145,4807,1472],{"emptyLinePlaceholder":1471},[1145,4809,4810,4812,4814,4816,4818,4820,4822,4824,4826,4828,4830],{"class":1147,"line":1403},[1145,4811,2736],{"class":1312},[1145,4813,3246],{"class":2739},[1145,4815,2218],{"class":1312},[1145,4817,2749],{"class":2243},[1145,4819,2247],{"class":1312},[1145,4821,2754],{"class":2043},[1145,4823,1900],{"class":1312},[1145,4825,3259],{"class":2243},[1145,4827,2247],{"class":1312},[1145,4829,3264],{"class":1169},[1145,4831,2382],{"class":1312},[1145,4833,4834,4836,4839,4841,4843,4845,4848],{"class":1147,"line":1411},[1145,4835,2762],{"class":2761},[1145,4837,4838],{"class":2739}," process_order",[1145,4840,2218],{"class":1312},[1145,4842,2771],{"class":2770},[1145,4844,1900],{"class":1312},[1145,4846,4847],{"class":3282}," order_id",[1145,4849,2774],{"class":1312},[1145,4851,4852],{"class":1147,"line":1422},[1145,4853,3290],{"class":2779},[1145,4855,4856],{"class":1147,"line":1433},[1145,4857,4858],{"class":2783},"    Main order processing task that orchestrates the entire workflow\n",[1145,4860,4861],{"class":1147,"line":1441},[1145,4862,3300],{"class":2783},[1145,4864,4865],{"class":1147,"line":1452},[1145,4866,3334],{"class":2783},[1145,4868,4869],{"class":1147,"line":1460},[1145,4870,4871],{"class":2783},"    - Complex workflow orchestration\n",[1145,4873,4874],{"class":1147,"line":1468},[1145,4875,4876],{"class":2783},"    - Using Celery's chain primitive for sequential tasks\n",[1145,4878,4879],{"class":1147,"line":1475},[1145,4880,4881],{"class":2783},"    - Error handling for business processes\n",[1145,4883,4884],{"class":1147,"line":1483},[1145,4885,4886],{"class":2783},"    - Database state management\n",[1145,4888,4889],{"class":1147,"line":1493},[1145,4890,3290],{"class":2779},[1145,4892,4893,4895],{"class":1147,"line":1503},[1145,4894,3363],{"class":1886},[1145,4896,1331],{"class":1312},[1145,4898,4899],{"class":1147,"line":1510},[1145,4900,4901],{"class":1151},"        # Get the order from database\n",[1145,4903,4904,4907,4909,4911,4913,4915,4917,4919,4921,4923,4925,4928],{"class":1147,"line":1523},[1145,4905,4906],{"class":1890},"        order ",[1145,4908,2247],{"class":1312},[1145,4910,4764],{"class":1890},[1145,4912,2554],{"class":1312},[1145,4914,3395],{"class":2586},[1145,4916,2554],{"class":1312},[1145,4918,3400],{"class":2214},[1145,4920,2218],{"class":1312},[1145,4922,3405],{"class":2243},[1145,4924,2247],{"class":1312},[1145,4926,4927],{"class":2214},"order_id",[1145,4929,2382],{"class":1312},[1145,4931,4932],{"class":1147,"line":1530},[1145,4933,3315],{"class":1890},[1145,4935,4936],{"class":1147,"line":1537},[1145,4937,4938],{"class":1151},"        # Update order status to indicate processing has started\n",[1145,4940,4941,4944,4946,4949,4951,4953,4956],{"class":1147,"line":1542},[1145,4942,4943],{"class":1890},"        order",[1145,4945,2554],{"class":1312},[1145,4947,4948],{"class":2586},"status",[1145,4950,1921],{"class":1312},[1145,4952,1317],{"class":1316},[1145,4954,4955],{"class":1162},"processing",[1145,4957,1323],{"class":1316},[1145,4959,4960,4962,4964,4967,4969,4971,4973,4975],{"class":1147,"line":1550},[1145,4961,4943],{"class":1890},[1145,4963,2554],{"class":1312},[1145,4965,4966],{"class":2586},"processing_started_at",[1145,4968,1921],{"class":1312},[1145,4970,4371],{"class":1890},[1145,4972,2554],{"class":1312},[1145,4974,4376],{"class":2214},[1145,4976,2722],{"class":1312},[1145,4978,4979,4981,4983,4985],{"class":1147,"line":1561},[1145,4980,4943],{"class":1890},[1145,4982,2554],{"class":1312},[1145,4984,3993],{"class":2214},[1145,4986,2722],{"class":1312},[1145,4988,4989],{"class":1147,"line":1566},[1145,4990,3315],{"class":1890},[1145,4992,4993],{"class":1147,"line":1574},[1145,4994,4995],{"class":1151},"        # Create a workflow chain - these tasks will execute in sequence\n",[1145,4997,4998],{"class":1147,"line":1582},[1145,4999,5000],{"class":1151},"        # Each task passes its result to the next task\n",[1145,5002,5003,5006,5008,5010],{"class":1147,"line":2379},[1145,5004,5005],{"class":1890},"        workflow ",[1145,5007,2247],{"class":1312},[1145,5009,4732],{"class":2214},[1145,5011,3429],{"class":1312},[1145,5013,5014,5017,5019,5022,5024,5026,5028],{"class":1147,"line":2385},[1145,5015,5016],{"class":2214},"            validate_inventory",[1145,5018,2554],{"class":1312},[1145,5020,5021],{"class":2214},"s",[1145,5023,2218],{"class":1312},[1145,5025,4927],{"class":2214},[1145,5027,2240],{"class":1312},[1145,5029,5030],{"class":1151},"      # Step 1: Check if items are in stock\n",[1145,5032,5033,5036,5038,5040,5043],{"class":1147,"line":2390},[1145,5034,5035],{"class":2214},"            calculate_shipping",[1145,5037,2554],{"class":1312},[1145,5039,5021],{"class":2214},[1145,5041,5042],{"class":1312},"(),",[1145,5044,5045],{"class":1151},"              # Step 2: Calculate shipping costs\n",[1145,5047,5048,5051,5053,5055,5057],{"class":1147,"line":2396},[1145,5049,5050],{"class":2214},"            process_payment",[1145,5052,2554],{"class":1312},[1145,5054,5021],{"class":2214},[1145,5056,5042],{"class":1312},[1145,5058,5059],{"class":1151},"                 # Step 3: Process payment\n",[1145,5061,5062,5065,5067,5069,5071],{"class":1147,"line":2410},[1145,5063,5064],{"class":2214},"            send_confirmation",[1145,5066,2554],{"class":1312},[1145,5068,5021],{"class":2214},[1145,5070,4547],{"class":1312},[1145,5072,5073],{"class":1151},"                # Step 4: Send confirmation email\n",[1145,5075,5076],{"class":1147,"line":2424},[1145,5077,3529],{"class":1312},[1145,5079,5080],{"class":1147,"line":2438},[1145,5081,3315],{"class":1890},[1145,5083,5084],{"class":1147,"line":2443},[1145,5085,5086],{"class":1151},"        # Execute the workflow asynchronously\n",[1145,5088,5089,5092,5094,5097,5099,5102],{"class":1147,"line":2449},[1145,5090,5091],{"class":1890},"        result ",[1145,5093,2247],{"class":1312},[1145,5095,5096],{"class":1890}," workflow",[1145,5098,2554],{"class":1312},[1145,5100,5101],{"class":2214},"apply_async",[1145,5103,2722],{"class":1312},[1145,5105,5106],{"class":1147,"line":2463},[1145,5107,3315],{"class":1890},[1145,5109,5110,5112,5114,5116,5118,5120,5123,5125,5127,5129,5132],{"class":1147,"line":3526},[1145,5111,3546],{"class":1890},[1145,5113,2554],{"class":1312},[1145,5115,3551],{"class":2214},[1145,5117,2218],{"class":1312},[1145,5119,2798],{"class":2761},[1145,5121,5122],{"class":1162},"\"Order ",[1145,5124,2805],{"class":2804},[1145,5126,4927],{"class":2214},[1145,5128,2818],{"class":2804},[1145,5130,5131],{"class":1162}," processing workflow initiated\"",[1145,5133,2382],{"class":1312},[1145,5135,5136,5138,5140,5142,5144,5146,5148],{"class":1147,"line":3532},[1145,5137,3574],{"class":1886},[1145,5139,2830],{"class":2761},[1145,5141,5122],{"class":1162},[1145,5143,2805],{"class":2804},[1145,5145,4927],{"class":1890},[1145,5147,2818],{"class":2804},[1145,5149,5150],{"class":1162}," processing initiated\"\n",[1145,5152,5153],{"class":1147,"line":3537},[1145,5154,3315],{"class":1890},[1145,5156,5157,5159,5161,5163,5165],{"class":1147,"line":3543},[1145,5158,3602],{"class":1886},[1145,5160,4764],{"class":1890},[1145,5162,2554],{"class":1312},[1145,5164,3609],{"class":2586},[1145,5166,1331],{"class":1312},[1145,5168,5169,5171,5173,5175,5177,5179,5181,5183,5185,5187,5189],{"class":1147,"line":3571},[1145,5170,3546],{"class":1890},[1145,5172,2554],{"class":1312},[1145,5174,3627],{"class":2214},[1145,5176,2218],{"class":1312},[1145,5178,2798],{"class":2761},[1145,5180,5122],{"class":1162},[1145,5182,2805],{"class":2804},[1145,5184,4927],{"class":2214},[1145,5186,2818],{"class":2804},[1145,5188,3643],{"class":1162},[1145,5190,2382],{"class":1312},[1145,5192,5193],{"class":1147,"line":3594},[1145,5194,3651],{"class":1886},[1145,5196,5197,5199,5201,5203,5205],{"class":1147,"line":3599},[1145,5198,3602],{"class":1886},[1145,5200,3665],{"class":3664},[1145,5202,3668],{"class":1886},[1145,5204,3671],{"class":1890},[1145,5206,1331],{"class":1312},[1145,5208,5209,5211,5213,5215,5217,5219,5222,5224,5226,5228,5230,5232,5234,5236,5238],{"class":1147,"line":3614},[1145,5210,3546],{"class":1890},[1145,5212,2554],{"class":1312},[1145,5214,3627],{"class":2214},[1145,5216,2218],{"class":1312},[1145,5218,2798],{"class":2761},[1145,5220,5221],{"class":1162},"\"Failed to process order ",[1145,5223,2805],{"class":2804},[1145,5225,4927],{"class":2214},[1145,5227,2818],{"class":2804},[1145,5229,3704],{"class":1162},[1145,5231,2805],{"class":2804},[1145,5233,3709],{"class":2214},[1145,5235,2818],{"class":2804},[1145,5237,1382],{"class":1162},[1145,5239,2382],{"class":1312},[1145,5241,5242],{"class":1147,"line":3620},[1145,5243,5244],{"class":1151},"        # Update order status to failed\n",[1145,5246,5247,5249],{"class":1147,"line":3648},[1145,5248,4443],{"class":1886},[1145,5250,1331],{"class":1312},[1145,5252,5253,5256,5258,5260,5262,5264,5266,5268,5270,5272,5274,5276],{"class":1147,"line":3654},[1145,5254,5255],{"class":1890},"            order ",[1145,5257,2247],{"class":1312},[1145,5259,4764],{"class":1890},[1145,5261,2554],{"class":1312},[1145,5263,3395],{"class":2586},[1145,5265,2554],{"class":1312},[1145,5267,3400],{"class":2214},[1145,5269,2218],{"class":1312},[1145,5271,3405],{"class":2243},[1145,5273,2247],{"class":1312},[1145,5275,4927],{"class":2214},[1145,5277,2382],{"class":1312},[1145,5279,5280,5283,5285,5287,5289,5291,5294],{"class":1147,"line":3659},[1145,5281,5282],{"class":1890},"            order",[1145,5284,2554],{"class":1312},[1145,5286,4948],{"class":2586},[1145,5288,1921],{"class":1312},[1145,5290,1317],{"class":1316},[1145,5292,5293],{"class":1162},"failed",[1145,5295,1323],{"class":1316},[1145,5297,5298,5300,5302,5305,5307,5310,5312,5314],{"class":1147,"line":3676},[1145,5299,5282],{"class":1890},[1145,5301,2554],{"class":1312},[1145,5303,5304],{"class":2586},"error_message",[1145,5306,1921],{"class":1312},[1145,5308,5309],{"class":3664}," str",[1145,5311,2218],{"class":1312},[1145,5313,3709],{"class":2214},[1145,5315,2382],{"class":1312},[1145,5317,5318,5320,5322,5324],{"class":1147,"line":3682},[1145,5319,5282],{"class":1890},[1145,5321,2554],{"class":1312},[1145,5323,3993],{"class":2214},[1145,5325,2722],{"class":1312},[1145,5327,5328,5330],{"class":1147,"line":3718},[1145,5329,4605],{"class":1886},[1145,5331,1331],{"class":1312},[1145,5333,5334,5337],{"class":1147,"line":3723},[1145,5335,5336],{"class":1886},"            pass",[1145,5338,5339],{"class":1151},"  # Don't fail if we can't update status\n",[1145,5341,5342],{"class":1147,"line":3729},[1145,5343,3315],{"class":1890},[1145,5345,5346,5348,5350,5352,5354,5356,5358,5360,5362,5364,5366,5368,5370],{"class":1147,"line":3735},[1145,5347,3738],{"class":1886},[1145,5349,3741],{"class":1917},[1145,5351,2554],{"class":1312},[1145,5353,3746],{"class":2214},[1145,5355,2218],{"class":1312},[1145,5357,3709],{"class":2243},[1145,5359,2247],{"class":1312},[1145,5361,3709],{"class":2214},[1145,5363,1900],{"class":1312},[1145,5365,3759],{"class":2243},[1145,5367,2247],{"class":1312},[1145,5369,3764],{"class":1169},[1145,5371,2382],{"class":1312},[1145,5373,5374],{"class":1147,"line":3792},[1145,5375,1472],{"emptyLinePlaceholder":1471},[1145,5377,5378,5380],{"class":1147,"line":3797},[1145,5379,2736],{"class":1312},[1145,5381,3802],{"class":2739},[1145,5383,5384,5386,5389,5391,5393],{"class":1147,"line":3805},[1145,5385,2762],{"class":2761},[1145,5387,5388],{"class":2739}," validate_inventory",[1145,5390,2218],{"class":1312},[1145,5392,4927],{"class":3282},[1145,5394,2774],{"class":1312},[1145,5396,5397],{"class":1147,"line":3824},[1145,5398,3290],{"class":2779},[1145,5400,5401],{"class":1147,"line":3829},[1145,5402,5403],{"class":2783},"    Validate that all items in the order are available in inventory\n",[1145,5405,5406],{"class":1147,"line":3835},[1145,5407,3300],{"class":2783},[1145,5409,5410],{"class":1147,"line":3840},[1145,5411,3334],{"class":2783},[1145,5413,5414],{"class":1147,"line":3845},[1145,5415,5416],{"class":2783},"    - External service communication\n",[1145,5418,5419],{"class":1147,"line":3851},[1145,5420,5421],{"class":2783},"    - Business logic validation\n",[1145,5423,5424],{"class":1147,"line":3857},[1145,5425,5426],{"class":2783},"    - Error handling for business rules\n",[1145,5428,5429],{"class":1147,"line":3863},[1145,5430,3290],{"class":2779},[1145,5432,5433,5436,5438,5440,5442,5444,5446,5448,5450,5452,5454,5456],{"class":1147,"line":3868},[1145,5434,5435],{"class":1890},"    order ",[1145,5437,2247],{"class":1312},[1145,5439,4764],{"class":1890},[1145,5441,2554],{"class":1312},[1145,5443,3395],{"class":2586},[1145,5445,2554],{"class":1312},[1145,5447,3400],{"class":2214},[1145,5449,2218],{"class":1312},[1145,5451,3405],{"class":2243},[1145,5453,2247],{"class":1312},[1145,5455,4927],{"class":2214},[1145,5457,2382],{"class":1312},[1145,5459,5460],{"class":1147,"line":3875},[1145,5461,3300],{"class":1890},[1145,5463,5464,5467,5469,5471,5473,5475,5478,5480,5482,5484,5486],{"class":1147,"line":3902},[1145,5465,5466],{"class":1890},"    logger",[1145,5468,2554],{"class":1312},[1145,5470,3551],{"class":2214},[1145,5472,2218],{"class":1312},[1145,5474,2798],{"class":2761},[1145,5476,5477],{"class":1162},"\"Validating inventory for order ",[1145,5479,2805],{"class":2804},[1145,5481,4927],{"class":2214},[1145,5483,2818],{"class":2804},[1145,5485,1382],{"class":1162},[1145,5487,2382],{"class":1312},[1145,5489,5490],{"class":1147,"line":3907},[1145,5491,3300],{"class":1890},[1145,5493,5494],{"class":1147,"line":3913},[1145,5495,5496],{"class":1151},"    # Check inventory for each item in the order\n",[1145,5498,5499,5501,5504,5506,5509,5511,5513,5515,5518],{"class":1147,"line":3940},[1145,5500,4427],{"class":1886},[1145,5502,5503],{"class":1890}," item ",[1145,5505,3927],{"class":1886},[1145,5507,5508],{"class":1890}," order",[1145,5510,2554],{"class":1312},[1145,5512,3934],{"class":2586},[1145,5514,2554],{"class":1312},[1145,5516,5517],{"class":2214},"all",[1145,5519,3937],{"class":1312},[1145,5521,5522,5524],{"class":1147,"line":3959},[1145,5523,4443],{"class":1886},[1145,5525,1331],{"class":1312},[1145,5527,5528],{"class":1147,"line":3980},[1145,5529,5530],{"class":1151},"            # Call the inventory service to check stock\n",[1145,5532,5533,5535,5537,5539,5541,5543],{"class":1147,"line":3985},[1145,5534,4451],{"class":1890},[1145,5536,2247],{"class":1312},[1145,5538,4456],{"class":1890},[1145,5540,2554],{"class":1312},[1145,5542,4461],{"class":2214},[1145,5544,3429],{"class":1312},[1145,5546,5547,5550,5553,5555],{"class":1147,"line":3998},[1145,5548,5549],{"class":1316},"                '",[1145,5551,5552],{"class":1162},"http://inventory-service:8003/api/check-stock/",[1145,5554,1966],{"class":1316},[1145,5556,3446],{"class":1312},[1145,5558,5559,5561],{"class":1147,"line":4003},[1145,5560,4477],{"class":2243},[1145,5562,5563],{"class":1312},"={\n",[1145,5565,5566,5569,5572,5574,5576,5579,5581,5583],{"class":1147,"line":4009},[1145,5567,5568],{"class":1316},"                    '",[1145,5570,5571],{"class":1162},"product_id",[1145,5573,1966],{"class":1316},[1145,5575,1313],{"class":1312},[1145,5577,5578],{"class":2214}," item",[1145,5580,2554],{"class":1312},[1145,5582,5571],{"class":2586},[1145,5584,3446],{"class":1312},[1145,5586,5587,5589,5592,5594,5596,5598,5600],{"class":1147,"line":4015},[1145,5588,5568],{"class":1316},[1145,5590,5591],{"class":1162},"quantity",[1145,5593,1966],{"class":1316},[1145,5595,1313],{"class":1312},[1145,5597,5578],{"class":2214},[1145,5599,2554],{"class":1312},[1145,5601,5602],{"class":2586},"quantity\n",[1145,5604,5605],{"class":1147,"line":4036},[1145,5606,5607],{"class":1312},"                },\n",[1145,5609,5610,5612,5614],{"class":1147,"line":4041},[1145,5611,4490],{"class":2243},[1145,5613,2247],{"class":1312},[1145,5615,5616],{"class":1169},"10\n",[1145,5618,5619],{"class":1147,"line":4067},[1145,5620,4533],{"class":1312},[1145,5622,5623,5625,5627,5629],{"class":1147,"line":4084},[1145,5624,4539],{"class":1890},[1145,5626,2554],{"class":1312},[1145,5628,4544],{"class":2214},[1145,5630,2722],{"class":1312},[1145,5632,5633],{"class":1147,"line":4089},[1145,5634,4556],{"class":1890},[1145,5636,5637,5640,5642,5645,5647,5649],{"class":1147,"line":4102},[1145,5638,5639],{"class":1890},"            stock_data ",[1145,5641,2247],{"class":1312},[1145,5643,5644],{"class":1890}," response",[1145,5646,2554],{"class":1312},[1145,5648,1963],{"class":2214},[1145,5650,2722],{"class":1312},[1145,5652,5653,5655,5658,5661,5663,5665,5667,5669,5672,5674],{"class":1147,"line":4128},[1145,5654,3943],{"class":1886},[1145,5656,5657],{"class":1814}," not",[1145,5659,5660],{"class":1890}," stock_data",[1145,5662,2554],{"class":1312},[1145,5664,3400],{"class":2214},[1145,5666,2218],{"class":1312},[1145,5668,1966],{"class":1316},[1145,5670,5671],{"class":1162},"available",[1145,5673,1966],{"class":1316},[1145,5675,2774],{"class":1312},[1145,5677,5678],{"class":1147,"line":4133},[1145,5679,5680],{"class":1151},"                # Not enough stock - this is a business rule violation\n",[1145,5682,5683,5686,5688,5690,5692,5695,5697,5700,5702,5704,5706,5708],{"class":1147,"line":4146},[1145,5684,5685],{"class":1886},"                raise",[1145,5687,3665],{"class":3664},[1145,5689,2218],{"class":1312},[1145,5691,2798],{"class":2761},[1145,5693,5694],{"class":1162},"\"Insufficient stock for product ",[1145,5696,2805],{"class":2804},[1145,5698,5699],{"class":2214},"item",[1145,5701,2554],{"class":1312},[1145,5703,5571],{"class":2586},[1145,5705,2818],{"class":2804},[1145,5707,1382],{"class":1162},[1145,5709,2382],{"class":1312},[1145,5711,5712],{"class":1147,"line":4180},[1145,5713,5714],{"class":1890},"                \n",[1145,5716,5717,5719,5721,5723,5725,5727,5730,5732,5734,5736,5738,5740,5742],{"class":1147,"line":4185},[1145,5718,4562],{"class":1890},[1145,5720,2554],{"class":1312},[1145,5722,3551],{"class":2214},[1145,5724,2218],{"class":1312},[1145,5726,2798],{"class":2761},[1145,5728,5729],{"class":1162},"\"Stock validated for product ",[1145,5731,2805],{"class":2804},[1145,5733,5699],{"class":2214},[1145,5735,2554],{"class":1312},[1145,5737,5571],{"class":2586},[1145,5739,2818],{"class":2804},[1145,5741,1382],{"class":1162},[1145,5743,2382],{"class":1312},[1145,5745,5746],{"class":1147,"line":4190},[1145,5747,4556],{"class":1890},[1145,5749,5750,5752,5754,5756,5758,5760,5762],{"class":1147,"line":4197},[1145,5751,4605],{"class":1886},[1145,5753,4456],{"class":1890},[1145,5755,2554],{"class":1312},[1145,5757,4612],{"class":2586},[1145,5759,3668],{"class":1886},[1145,5761,3671],{"class":1890},[1145,5763,1331],{"class":1312},[1145,5765,5766,5768,5770,5772,5774,5776,5779,5781,5783,5785,5787,5789,5791,5793,5795,5797,5799],{"class":1147,"line":4215},[1145,5767,4562],{"class":1890},[1145,5769,2554],{"class":1312},[1145,5771,3627],{"class":2214},[1145,5773,2218],{"class":1312},[1145,5775,2798],{"class":2761},[1145,5777,5778],{"class":1162},"\"Failed to check stock for product ",[1145,5780,2805],{"class":2804},[1145,5782,5699],{"class":2214},[1145,5784,2554],{"class":1312},[1145,5786,5571],{"class":2586},[1145,5788,2818],{"class":2804},[1145,5790,3704],{"class":1162},[1145,5792,2805],{"class":2804},[1145,5794,3709],{"class":2214},[1145,5796,2818],{"class":2804},[1145,5798,1382],{"class":1162},[1145,5800,2382],{"class":1312},[1145,5802,5803,5806,5808,5810,5812,5815,5817,5819,5821,5823],{"class":1147,"line":4220},[1145,5804,5805],{"class":1886},"            raise",[1145,5807,3665],{"class":3664},[1145,5809,2218],{"class":1312},[1145,5811,2798],{"class":2761},[1145,5813,5814],{"class":1162},"\"Inventory service unavailable: ",[1145,5816,2805],{"class":2804},[1145,5818,3709],{"class":2214},[1145,5820,2818],{"class":2804},[1145,5822,1382],{"class":1162},[1145,5824,2382],{"class":1312},[1145,5826,5827],{"class":1147,"line":4226},[1145,5828,3300],{"class":1890},[1145,5830,5831,5833,5835,5837,5839,5841,5844,5846,5848,5850,5852],{"class":1147,"line":4231},[1145,5832,5466],{"class":1890},[1145,5834,2554],{"class":1312},[1145,5836,3551],{"class":2214},[1145,5838,2218],{"class":1312},[1145,5840,2798],{"class":2761},[1145,5842,5843],{"class":1162},"\"All items validated for order ",[1145,5845,2805],{"class":2804},[1145,5847,4927],{"class":2214},[1145,5849,2818],{"class":2804},[1145,5851,1382],{"class":1162},[1145,5853,2382],{"class":1312},[1145,5855,5856,5858,5861],{"class":1147,"line":4236},[1145,5857,2827],{"class":1886},[1145,5859,5860],{"class":1890}," order_id  ",[1145,5862,5863],{"class":1151},"# Pass order_id to next task in chain\n",[1145,5865,5866],{"class":1147,"line":4242},[1145,5867,1472],{"emptyLinePlaceholder":1471},[1145,5869,5870,5872],{"class":1147,"line":4248},[1145,5871,2736],{"class":1312},[1145,5873,3802],{"class":2739},[1145,5875,5876,5878,5881,5883,5885],{"class":1147,"line":4254},[1145,5877,2762],{"class":2761},[1145,5879,5880],{"class":2739}," calculate_shipping",[1145,5882,2218],{"class":1312},[1145,5884,4927],{"class":3282},[1145,5886,2774],{"class":1312},[1145,5888,5889],{"class":1147,"line":4259},[1145,5890,3290],{"class":2779},[1145,5892,5893],{"class":1147,"line":4265},[1145,5894,5895],{"class":2783},"    Calculate shipping costs for the order\n",[1145,5897,5898],{"class":1147,"line":4276},[1145,5899,3300],{"class":2783},[1145,5901,5902],{"class":1147,"line":4289},[1145,5903,3334],{"class":2783},[1145,5905,5906],{"class":1147,"line":4301},[1145,5907,5908],{"class":2783},"    - External service integration\n",[1145,5910,5911],{"class":1147,"line":4307},[1145,5912,5913],{"class":2783},"    - Data enrichment (adding calculated fields)\n",[1145,5915,5916],{"class":1147,"line":4312},[1145,5917,5918],{"class":2783},"    - Error handling for calculations\n",[1145,5920,5921],{"class":1147,"line":4318},[1145,5922,3290],{"class":2779},[1145,5924,5925,5927,5929,5931,5933,5935,5937,5939,5941,5943,5945,5947],{"class":1147,"line":4328},[1145,5926,5435],{"class":1890},[1145,5928,2247],{"class":1312},[1145,5930,4764],{"class":1890},[1145,5932,2554],{"class":1312},[1145,5934,3395],{"class":2586},[1145,5936,2554],{"class":1312},[1145,5938,3400],{"class":2214},[1145,5940,2218],{"class":1312},[1145,5942,3405],{"class":2243},[1145,5944,2247],{"class":1312},[1145,5946,4927],{"class":2214},[1145,5948,2382],{"class":1312},[1145,5950,5951],{"class":1147,"line":4343},[1145,5952,3300],{"class":1890},[1145,5954,5955,5957,5959,5961,5963,5965,5968,5970,5972,5974,5976],{"class":1147,"line":4359},[1145,5956,5466],{"class":1890},[1145,5958,2554],{"class":1312},[1145,5960,3551],{"class":2214},[1145,5962,2218],{"class":1312},[1145,5964,2798],{"class":2761},[1145,5966,5967],{"class":1162},"\"Calculating shipping for order ",[1145,5969,2805],{"class":2804},[1145,5971,4927],{"class":2214},[1145,5973,2818],{"class":2804},[1145,5975,1382],{"class":1162},[1145,5977,2382],{"class":1312},[1145,5979,5980],{"class":1147,"line":4388},[1145,5981,3300],{"class":1890},[1145,5983,5984,5986],{"class":1147,"line":4407},[1145,5985,3363],{"class":1886},[1145,5987,1331],{"class":1312},[1145,5989,5990],{"class":1147,"line":4413},[1145,5991,5992],{"class":1151},"        # Call shipping service to calculate costs\n",[1145,5994,5995,5998,6000,6002,6004,6006],{"class":1147,"line":4418},[1145,5996,5997],{"class":1890},"        response ",[1145,5999,2247],{"class":1312},[1145,6001,4456],{"class":1890},[1145,6003,2554],{"class":1312},[1145,6005,4461],{"class":2214},[1145,6007,3429],{"class":1312},[1145,6009,6010,6013,6016,6018],{"class":1147,"line":4424},[1145,6011,6012],{"class":1316},"            '",[1145,6014,6015],{"class":1162},"http://shipping-service:8004/api/calculate/",[1145,6017,1966],{"class":1316},[1145,6019,3446],{"class":1312},[1145,6021,6022,6025],{"class":1147,"line":4440},[1145,6023,6024],{"class":2243},"            json",[1145,6026,5563],{"class":1312},[1145,6028,6029,6031,6033,6035,6037,6039],{"class":1147,"line":4448},[1145,6030,5549],{"class":1316},[1145,6032,4927],{"class":1162},[1145,6034,1966],{"class":1316},[1145,6036,1313],{"class":1312},[1145,6038,4847],{"class":2214},[1145,6040,3446],{"class":1312},[1145,6042,6043,6045,6048,6050,6052,6054,6056,6059],{"class":1147,"line":4466},[1145,6044,5549],{"class":1316},[1145,6046,6047],{"class":1162},"destination",[1145,6049,1966],{"class":1316},[1145,6051,1313],{"class":1312},[1145,6053,5508],{"class":2214},[1145,6055,2554],{"class":1312},[1145,6057,6058],{"class":2586},"shipping_address",[1145,6060,3446],{"class":1312},[1145,6062,6063,6065,6068,6070,6072,6074,6076,6079],{"class":1147,"line":4474},[1145,6064,5549],{"class":1316},[1145,6066,6067],{"class":1162},"weight",[1145,6069,1966],{"class":1316},[1145,6071,1313],{"class":1312},[1145,6073,5508],{"class":2214},[1145,6075,2554],{"class":1312},[1145,6077,6078],{"class":2586},"total_weight",[1145,6080,3446],{"class":1312},[1145,6082,6083,6085,6087,6089,6091],{"class":1147,"line":4487},[1145,6084,5549],{"class":1316},[1145,6086,3934],{"class":1162},[1145,6088,1966],{"class":1316},[1145,6090,1313],{"class":1312},[1145,6092,4273],{"class":1312},[1145,6094,6095],{"class":1147,"line":4503},[1145,6096,6097],{"class":1312},"                    {\n",[1145,6099,6100,6103,6105,6107,6109,6111,6113,6115],{"class":1147,"line":4530},[1145,6101,6102],{"class":1316},"                        '",[1145,6104,5571],{"class":1162},[1145,6106,1966],{"class":1316},[1145,6108,1313],{"class":1312},[1145,6110,5578],{"class":2214},[1145,6112,2554],{"class":1312},[1145,6114,5571],{"class":2586},[1145,6116,3446],{"class":1312},[1145,6118,6119,6121,6123,6125,6127,6129,6131,6133],{"class":1147,"line":4536},[1145,6120,6102],{"class":1316},[1145,6122,5591],{"class":1162},[1145,6124,1966],{"class":1316},[1145,6126,1313],{"class":1312},[1145,6128,5578],{"class":2214},[1145,6130,2554],{"class":1312},[1145,6132,5591],{"class":2586},[1145,6134,3446],{"class":1312},[1145,6136,6137,6139,6141,6143,6145,6147,6149],{"class":1147,"line":4553},[1145,6138,6102],{"class":1316},[1145,6140,6067],{"class":1162},[1145,6142,1966],{"class":1316},[1145,6144,1313],{"class":1312},[1145,6146,5578],{"class":2214},[1145,6148,2554],{"class":1312},[1145,6150,6151],{"class":2586},"weight\n",[1145,6153,6154],{"class":1147,"line":4559},[1145,6155,6156],{"class":1312},"                    }\n",[1145,6158,6159,6162,6164,6166,6168,6170,6172,6174,6176],{"class":1147,"line":4597},[1145,6160,6161],{"class":1886},"                    for",[1145,6163,5503],{"class":2214},[1145,6165,3927],{"class":1886},[1145,6167,5508],{"class":2214},[1145,6169,2554],{"class":1312},[1145,6171,3934],{"class":2586},[1145,6173,2554],{"class":1312},[1145,6175,5517],{"class":2214},[1145,6177,2722],{"class":1312},[1145,6179,6180],{"class":1147,"line":4602},[1145,6181,6182],{"class":1312},"                ]\n",[1145,6184,6185],{"class":1147,"line":4621},[1145,6186,6187],{"class":1312},"            },\n",[1145,6189,6190,6193,6195],{"class":1147,"line":4627},[1145,6191,6192],{"class":2243},"            timeout",[1145,6194,2247],{"class":1312},[1145,6196,6197],{"class":1169},"15\n",[1145,6199,6200],{"class":1147,"line":4633},[1145,6201,3529],{"class":1312},[1145,6203,6205,6208,6210,6212],{"class":1147,"line":6204},136,[1145,6206,6207],{"class":1890},"        response",[1145,6209,2554],{"class":1312},[1145,6211,4544],{"class":2214},[1145,6213,2722],{"class":1312},[1145,6215,6217],{"class":1147,"line":6216},137,[1145,6218,3315],{"class":1890},[1145,6220,6222,6225,6227,6229,6231,6233],{"class":1147,"line":6221},138,[1145,6223,6224],{"class":1890},"        shipping_data ",[1145,6226,2247],{"class":1312},[1145,6228,5644],{"class":1890},[1145,6230,2554],{"class":1312},[1145,6232,1963],{"class":2214},[1145,6234,2722],{"class":1312},[1145,6236,6238,6241,6243,6246,6248,6250,6252,6254,6257,6259,6261,6264],{"class":1147,"line":6237},139,[1145,6239,6240],{"class":1890},"        shipping_cost ",[1145,6242,2247],{"class":1312},[1145,6244,6245],{"class":1890}," shipping_data",[1145,6247,2554],{"class":1312},[1145,6249,3400],{"class":2214},[1145,6251,2218],{"class":1312},[1145,6253,1966],{"class":1316},[1145,6255,6256],{"class":1162},"cost",[1145,6258,1966],{"class":1316},[1145,6260,1900],{"class":1312},[1145,6262,6263],{"class":1169}," 0",[1145,6265,2382],{"class":1312},[1145,6267,6269,6272,6274,6276,6278,6280,6282,6284,6287,6289],{"class":1147,"line":6268},140,[1145,6270,6271],{"class":1890},"        estimated_delivery ",[1145,6273,2247],{"class":1312},[1145,6275,6245],{"class":1890},[1145,6277,2554],{"class":1312},[1145,6279,3400],{"class":2214},[1145,6281,2218],{"class":1312},[1145,6283,1966],{"class":1316},[1145,6285,6286],{"class":1162},"estimated_delivery",[1145,6288,1966],{"class":1316},[1145,6290,2382],{"class":1312},[1145,6292,6294],{"class":1147,"line":6293},141,[1145,6295,3315],{"class":1890},[1145,6297,6299],{"class":1147,"line":6298},142,[1145,6300,6301],{"class":1151},"        # Update order with shipping information\n",[1145,6303,6305,6307,6309,6312,6314],{"class":1147,"line":6304},143,[1145,6306,4943],{"class":1890},[1145,6308,2554],{"class":1312},[1145,6310,6311],{"class":2586},"shipping_cost",[1145,6313,1921],{"class":1312},[1145,6315,6316],{"class":1890}," shipping_cost\n",[1145,6318,6320,6322,6324,6326,6328],{"class":1147,"line":6319},144,[1145,6321,4943],{"class":1890},[1145,6323,2554],{"class":1312},[1145,6325,6286],{"class":2586},[1145,6327,1921],{"class":1312},[1145,6329,6330],{"class":1890}," estimated_delivery\n",[1145,6332,6334,6336,6338,6341,6343,6345,6347,6350,6353],{"class":1147,"line":6333},145,[1145,6335,4943],{"class":1890},[1145,6337,2554],{"class":1312},[1145,6339,6340],{"class":2586},"total_amount",[1145,6342,1921],{"class":1312},[1145,6344,5508],{"class":1890},[1145,6346,2554],{"class":1312},[1145,6348,6349],{"class":2586},"subtotal",[1145,6351,6352],{"class":1814}," +",[1145,6354,6316],{"class":1890},[1145,6356,6358,6360,6362,6364],{"class":1147,"line":6357},146,[1145,6359,4943],{"class":1890},[1145,6361,2554],{"class":1312},[1145,6363,3993],{"class":2214},[1145,6365,2722],{"class":1312},[1145,6367,6369],{"class":1147,"line":6368},147,[1145,6370,3315],{"class":1890},[1145,6372,6374,6376,6378,6380,6382,6384,6387,6389,6391,6393,6396,6398,6400,6402,6404],{"class":1147,"line":6373},148,[1145,6375,3546],{"class":1890},[1145,6377,2554],{"class":1312},[1145,6379,3551],{"class":2214},[1145,6381,2218],{"class":1312},[1145,6383,2798],{"class":2761},[1145,6385,6386],{"class":1162},"\"Shipping calculated for order ",[1145,6388,2805],{"class":2804},[1145,6390,4927],{"class":2214},[1145,6392,2818],{"class":2804},[1145,6394,6395],{"class":1162},": $",[1145,6397,2805],{"class":2804},[1145,6399,6311],{"class":2214},[1145,6401,2818],{"class":2804},[1145,6403,1382],{"class":1162},[1145,6405,2382],{"class":1312},[1145,6407,6409,6411],{"class":1147,"line":6408},149,[1145,6410,3574],{"class":1886},[1145,6412,6413],{"class":1890}," order_id\n",[1145,6415,6417],{"class":1147,"line":6416},150,[1145,6418,3315],{"class":1890},[1145,6420,6422,6424,6426,6428,6430,6432,6434],{"class":1147,"line":6421},151,[1145,6423,3602],{"class":1886},[1145,6425,4456],{"class":1890},[1145,6427,2554],{"class":1312},[1145,6429,4612],{"class":2586},[1145,6431,3668],{"class":1886},[1145,6433,3671],{"class":1890},[1145,6435,1331],{"class":1312},[1145,6437,6439,6441,6443,6445,6447,6449,6452,6454,6456,6458,6460,6462,6464,6466,6468],{"class":1147,"line":6438},152,[1145,6440,3546],{"class":1890},[1145,6442,2554],{"class":1312},[1145,6444,3627],{"class":2214},[1145,6446,2218],{"class":1312},[1145,6448,2798],{"class":2761},[1145,6450,6451],{"class":1162},"\"Failed to calculate shipping for order ",[1145,6453,2805],{"class":2804},[1145,6455,4927],{"class":2214},[1145,6457,2818],{"class":2804},[1145,6459,3704],{"class":1162},[1145,6461,2805],{"class":2804},[1145,6463,3709],{"class":2214},[1145,6465,2818],{"class":2804},[1145,6467,1382],{"class":1162},[1145,6469,2382],{"class":1312},[1145,6471,6473,6475,6477,6479,6481,6484,6486,6488,6490,6492],{"class":1147,"line":6472},153,[1145,6474,3738],{"class":1886},[1145,6476,3665],{"class":3664},[1145,6478,2218],{"class":1312},[1145,6480,2798],{"class":2761},[1145,6482,6483],{"class":1162},"\"Shipping service unavailable: ",[1145,6485,2805],{"class":2804},[1145,6487,3709],{"class":2214},[1145,6489,2818],{"class":2804},[1145,6491,1382],{"class":1162},[1145,6493,2382],{"class":1312},[1145,6495,6497],{"class":1147,"line":6496},154,[1145,6498,1472],{"emptyLinePlaceholder":1471},[1145,6500,6502,6504],{"class":1147,"line":6501},155,[1145,6503,2736],{"class":1312},[1145,6505,3802],{"class":2739},[1145,6507,6509,6511,6514,6516,6518],{"class":1147,"line":6508},156,[1145,6510,2762],{"class":2761},[1145,6512,6513],{"class":2739}," process_payment",[1145,6515,2218],{"class":1312},[1145,6517,4927],{"class":3282},[1145,6519,2774],{"class":1312},[1145,6521,6523],{"class":1147,"line":6522},157,[1145,6524,3290],{"class":2779},[1145,6526,6528],{"class":1147,"line":6527},158,[1145,6529,6530],{"class":2783},"    Process payment for the order\n",[1145,6532,6534],{"class":1147,"line":6533},159,[1145,6535,3300],{"class":2783},[1145,6537,6539],{"class":1147,"line":6538},160,[1145,6540,3334],{"class":2783},[1145,6542,6544],{"class":1147,"line":6543},161,[1145,6545,6546],{"class":2783},"    - Critical business operations\n",[1145,6548,6550],{"class":1147,"line":6549},162,[1145,6551,6552],{"class":2783},"    - Transaction handling\n",[1145,6554,6556],{"class":1147,"line":6555},163,[1145,6557,6558],{"class":2783},"    - External payment processing\n",[1145,6560,6562],{"class":1147,"line":6561},164,[1145,6563,6564],{"class":2783},"    - Detailed error handling\n",[1145,6566,6568],{"class":1147,"line":6567},165,[1145,6569,3290],{"class":2779},[1145,6571,6573,6575,6577,6579,6581,6583,6585,6587,6589,6591,6593,6595],{"class":1147,"line":6572},166,[1145,6574,5435],{"class":1890},[1145,6576,2247],{"class":1312},[1145,6578,4764],{"class":1890},[1145,6580,2554],{"class":1312},[1145,6582,3395],{"class":2586},[1145,6584,2554],{"class":1312},[1145,6586,3400],{"class":2214},[1145,6588,2218],{"class":1312},[1145,6590,3405],{"class":2243},[1145,6592,2247],{"class":1312},[1145,6594,4927],{"class":2214},[1145,6596,2382],{"class":1312},[1145,6598,6600],{"class":1147,"line":6599},167,[1145,6601,3300],{"class":1890},[1145,6603,6605,6607,6609,6611,6613,6615,6618,6620,6622,6624,6626],{"class":1147,"line":6604},168,[1145,6606,5466],{"class":1890},[1145,6608,2554],{"class":1312},[1145,6610,3551],{"class":2214},[1145,6612,2218],{"class":1312},[1145,6614,2798],{"class":2761},[1145,6616,6617],{"class":1162},"\"Processing payment for order ",[1145,6619,2805],{"class":2804},[1145,6621,4927],{"class":2214},[1145,6623,2818],{"class":2804},[1145,6625,1382],{"class":1162},[1145,6627,2382],{"class":1312},[1145,6629,6631],{"class":1147,"line":6630},169,[1145,6632,3300],{"class":1890},[1145,6634,6636,6638],{"class":1147,"line":6635},170,[1145,6637,3363],{"class":1886},[1145,6639,1331],{"class":1312},[1145,6641,6643],{"class":1147,"line":6642},171,[1145,6644,6645],{"class":1151},"        # Call payment service to charge the customer\n",[1145,6647,6649,6651,6653,6655,6657,6659],{"class":1147,"line":6648},172,[1145,6650,5997],{"class":1890},[1145,6652,2247],{"class":1312},[1145,6654,4456],{"class":1890},[1145,6656,2554],{"class":1312},[1145,6658,4461],{"class":2214},[1145,6660,3429],{"class":1312},[1145,6662,6664,6666,6669,6671],{"class":1147,"line":6663},173,[1145,6665,6012],{"class":1316},[1145,6667,6668],{"class":1162},"http://payment-service:8005/api/charge/",[1145,6670,1966],{"class":1316},[1145,6672,3446],{"class":1312},[1145,6674,6676,6678],{"class":1147,"line":6675},174,[1145,6677,6024],{"class":2243},[1145,6679,5563],{"class":1312},[1145,6681,6683,6685,6687,6689,6691,6693],{"class":1147,"line":6682},175,[1145,6684,5549],{"class":1316},[1145,6686,4927],{"class":1162},[1145,6688,1966],{"class":1316},[1145,6690,1313],{"class":1312},[1145,6692,4847],{"class":2214},[1145,6694,3446],{"class":1312},[1145,6696,6698,6700,6703,6705,6707,6710,6712,6714,6716,6718],{"class":1147,"line":6697},176,[1145,6699,5549],{"class":1316},[1145,6701,6702],{"class":1162},"amount",[1145,6704,1966],{"class":1316},[1145,6706,1313],{"class":1312},[1145,6708,6709],{"class":3664}," float",[1145,6711,2218],{"class":1312},[1145,6713,2319],{"class":2214},[1145,6715,2554],{"class":1312},[1145,6717,6340],{"class":2586},[1145,6719,2256],{"class":1312},[1145,6721,6723,6725,6728,6730,6732,6734,6737,6739],{"class":1147,"line":6722},177,[1145,6724,5549],{"class":1316},[1145,6726,6727],{"class":1162},"currency",[1145,6729,1966],{"class":1316},[1145,6731,1313],{"class":1312},[1145,6733,1317],{"class":1316},[1145,6735,6736],{"class":1162},"USD",[1145,6738,1966],{"class":1316},[1145,6740,3446],{"class":1312},[1145,6742,6744,6746,6749,6751,6753,6755,6757,6759],{"class":1147,"line":6743},178,[1145,6745,5549],{"class":1316},[1145,6747,6748],{"class":1162},"payment_method",[1145,6750,1966],{"class":1316},[1145,6752,1313],{"class":1312},[1145,6754,5508],{"class":2214},[1145,6756,2554],{"class":1312},[1145,6758,6748],{"class":2586},[1145,6760,3446],{"class":1312},[1145,6762,6764,6766,6769,6771,6773,6775,6777,6779],{"class":1147,"line":6763},179,[1145,6765,5549],{"class":1316},[1145,6767,6768],{"class":1162},"customer_id",[1145,6770,1966],{"class":1316},[1145,6772,1313],{"class":1312},[1145,6774,5508],{"class":2214},[1145,6776,2554],{"class":1312},[1145,6778,3410],{"class":2586},[1145,6780,3446],{"class":1312},[1145,6782,6784,6786,6789,6791,6793,6795,6798,6800,6802,6804],{"class":1147,"line":6783},180,[1145,6785,5549],{"class":1316},[1145,6787,6788],{"class":1162},"description",[1145,6790,1966],{"class":1316},[1145,6792,1313],{"class":1312},[1145,6794,2830],{"class":2761},[1145,6796,6797],{"class":1162},"'Order #",[1145,6799,2805],{"class":2804},[1145,6801,4927],{"class":2214},[1145,6803,2818],{"class":2804},[1145,6805,1323],{"class":1162},[1145,6807,6809],{"class":1147,"line":6808},181,[1145,6810,6187],{"class":1312},[1145,6812,6814,6816,6818,6821],{"class":1147,"line":6813},182,[1145,6815,6192],{"class":2243},[1145,6817,2247],{"class":1312},[1145,6819,6820],{"class":1169},"30",[1145,6822,6823],{"class":1151},"  # Payment processing might take longer\n",[1145,6825,6827],{"class":1147,"line":6826},183,[1145,6828,3529],{"class":1312},[1145,6830,6832,6834,6836,6838],{"class":1147,"line":6831},184,[1145,6833,6207],{"class":1890},[1145,6835,2554],{"class":1312},[1145,6837,4544],{"class":2214},[1145,6839,2722],{"class":1312},[1145,6841,6843],{"class":1147,"line":6842},185,[1145,6844,3315],{"class":1890},[1145,6846,6848,6851,6853,6855,6857,6859],{"class":1147,"line":6847},186,[1145,6849,6850],{"class":1890},"        payment_data ",[1145,6852,2247],{"class":1312},[1145,6854,5644],{"class":1890},[1145,6856,2554],{"class":1312},[1145,6858,1963],{"class":2214},[1145,6860,2722],{"class":1312},[1145,6862,6864],{"class":1147,"line":6863},187,[1145,6865,3315],{"class":1890},[1145,6867,6869,6872,6875,6877,6879,6881,6883,6886,6888],{"class":1147,"line":6868},188,[1145,6870,6871],{"class":1886},"        if",[1145,6873,6874],{"class":1890}," payment_data",[1145,6876,2554],{"class":1312},[1145,6878,3400],{"class":2214},[1145,6880,2218],{"class":1312},[1145,6882,1966],{"class":1316},[1145,6884,6885],{"class":1162},"success",[1145,6887,1966],{"class":1316},[1145,6889,2774],{"class":1312},[1145,6891,6893],{"class":1147,"line":6892},189,[1145,6894,6895],{"class":1151},"            # Payment successful - update order\n",[1145,6897,6899,6901,6903,6905,6907,6909,6912],{"class":1147,"line":6898},190,[1145,6900,5282],{"class":1890},[1145,6902,2554],{"class":1312},[1145,6904,4948],{"class":2586},[1145,6906,1921],{"class":1312},[1145,6908,1317],{"class":1316},[1145,6910,6911],{"class":1162},"paid",[1145,6913,1323],{"class":1316},[1145,6915,6917,6919,6921,6924,6926,6928,6930,6932,6934,6936,6938,6940],{"class":1147,"line":6916},191,[1145,6918,5282],{"class":1890},[1145,6920,2554],{"class":1312},[1145,6922,6923],{"class":2586},"payment_id",[1145,6925,1921],{"class":1312},[1145,6927,6874],{"class":1890},[1145,6929,2554],{"class":1312},[1145,6931,3400],{"class":2214},[1145,6933,2218],{"class":1312},[1145,6935,1966],{"class":1316},[1145,6937,6923],{"class":1162},[1145,6939,1966],{"class":1316},[1145,6941,2382],{"class":1312},[1145,6943,6945,6947,6949,6952,6954,6956,6958,6960],{"class":1147,"line":6944},192,[1145,6946,5282],{"class":1890},[1145,6948,2554],{"class":1312},[1145,6950,6951],{"class":2586},"paid_at",[1145,6953,1921],{"class":1312},[1145,6955,4371],{"class":1890},[1145,6957,2554],{"class":1312},[1145,6959,4376],{"class":2214},[1145,6961,2722],{"class":1312},[1145,6963,6965,6967,6969,6971],{"class":1147,"line":6964},193,[1145,6966,5282],{"class":1890},[1145,6968,2554],{"class":1312},[1145,6970,3993],{"class":2214},[1145,6972,2722],{"class":1312},[1145,6974,6976],{"class":1147,"line":6975},194,[1145,6977,4556],{"class":1890},[1145,6979,6981,6983,6985,6987,6989,6991,6994,6996,6998,7000,7002,7004,7007,7009,7011,7013,7015,7017,7019,7021,7023,7025],{"class":1147,"line":6980},195,[1145,6982,4562],{"class":1890},[1145,6984,2554],{"class":1312},[1145,6986,3551],{"class":2214},[1145,6988,2218],{"class":1312},[1145,6990,2798],{"class":2761},[1145,6992,6993],{"class":1162},"\"Payment processed for order ",[1145,6995,2805],{"class":2804},[1145,6997,4927],{"class":2214},[1145,6999,2818],{"class":2804},[1145,7001,3704],{"class":1162},[1145,7003,2805],{"class":2804},[1145,7005,7006],{"class":2214},"payment_data",[1145,7008,2554],{"class":1312},[1145,7010,3400],{"class":2214},[1145,7012,2218],{"class":1312},[1145,7014,1966],{"class":1316},[1145,7016,6923],{"class":1162},[1145,7018,1966],{"class":1316},[1145,7020,1623],{"class":1312},[1145,7022,2818],{"class":2804},[1145,7024,1382],{"class":1162},[1145,7026,2382],{"class":1312},[1145,7028,7030,7033],{"class":1147,"line":7029},196,[1145,7031,7032],{"class":1886},"            return",[1145,7034,6413],{"class":1890},[1145,7036,7038,7041],{"class":1147,"line":7037},197,[1145,7039,7040],{"class":1886},"        else",[1145,7042,1331],{"class":1312},[1145,7044,7046],{"class":1147,"line":7045},198,[1145,7047,7048],{"class":1151},"            # Payment failed\n",[1145,7050,7052,7055,7057,7059,7061,7063,7065,7067,7069,7071,7073,7075,7078,7080],{"class":1147,"line":7051},199,[1145,7053,7054],{"class":1890},"            error_message ",[1145,7056,2247],{"class":1312},[1145,7058,6874],{"class":1890},[1145,7060,2554],{"class":1312},[1145,7062,3400],{"class":2214},[1145,7064,2218],{"class":1312},[1145,7066,1966],{"class":1316},[1145,7068,3627],{"class":1162},[1145,7070,1966],{"class":1316},[1145,7072,1900],{"class":1312},[1145,7074,1317],{"class":1316},[1145,7076,7077],{"class":1162},"Payment processing failed",[1145,7079,1966],{"class":1316},[1145,7081,2382],{"class":1312},[1145,7083,7085,7087,7089,7091,7093,7095,7098,7100,7102,7104,7106,7108,7110,7112,7114],{"class":1147,"line":7084},200,[1145,7086,4562],{"class":1890},[1145,7088,2554],{"class":1312},[1145,7090,3627],{"class":2214},[1145,7092,2218],{"class":1312},[1145,7094,2798],{"class":2761},[1145,7096,7097],{"class":1162},"\"Payment failed for order ",[1145,7099,2805],{"class":2804},[1145,7101,4927],{"class":2214},[1145,7103,2818],{"class":2804},[1145,7105,3704],{"class":1162},[1145,7107,2805],{"class":2804},[1145,7109,5304],{"class":2214},[1145,7111,2818],{"class":2804},[1145,7113,1382],{"class":1162},[1145,7115,2382],{"class":1312},[1145,7117,7119,7121,7123,7125,7127,7130,7132,7134,7136,7138],{"class":1147,"line":7118},201,[1145,7120,5805],{"class":1886},[1145,7122,3665],{"class":3664},[1145,7124,2218],{"class":1312},[1145,7126,2798],{"class":2761},[1145,7128,7129],{"class":1162},"\"Payment failed: ",[1145,7131,2805],{"class":2804},[1145,7133,5304],{"class":2214},[1145,7135,2818],{"class":2804},[1145,7137,1382],{"class":1162},[1145,7139,2382],{"class":1312},[1145,7141,7143],{"class":1147,"line":7142},202,[1145,7144,4556],{"class":1890},[1145,7146,7148,7150,7152,7154,7156,7158,7160],{"class":1147,"line":7147},203,[1145,7149,3602],{"class":1886},[1145,7151,4456],{"class":1890},[1145,7153,2554],{"class":1312},[1145,7155,4612],{"class":2586},[1145,7157,3668],{"class":1886},[1145,7159,3671],{"class":1890},[1145,7161,1331],{"class":1312},[1145,7163,7165,7167,7169,7171,7173,7175,7178,7180,7182,7184,7186,7188,7190,7192,7194],{"class":1147,"line":7164},204,[1145,7166,3546],{"class":1890},[1145,7168,2554],{"class":1312},[1145,7170,3627],{"class":2214},[1145,7172,2218],{"class":1312},[1145,7174,2798],{"class":2761},[1145,7176,7177],{"class":1162},"\"Payment service error for order ",[1145,7179,2805],{"class":2804},[1145,7181,4927],{"class":2214},[1145,7183,2818],{"class":2804},[1145,7185,3704],{"class":1162},[1145,7187,2805],{"class":2804},[1145,7189,3709],{"class":2214},[1145,7191,2818],{"class":2804},[1145,7193,1382],{"class":1162},[1145,7195,2382],{"class":1312},[1145,7197,7199,7201,7203,7205,7207,7210,7212,7214,7216,7218],{"class":1147,"line":7198},205,[1145,7200,3738],{"class":1886},[1145,7202,3665],{"class":3664},[1145,7204,2218],{"class":1312},[1145,7206,2798],{"class":2761},[1145,7208,7209],{"class":1162},"\"Payment service unavailable: ",[1145,7211,2805],{"class":2804},[1145,7213,3709],{"class":2214},[1145,7215,2818],{"class":2804},[1145,7217,1382],{"class":1162},[1145,7219,2382],{"class":1312},[1145,7221,7223],{"class":1147,"line":7222},206,[1145,7224,1472],{"emptyLinePlaceholder":1471},[1145,7226,7228,7230],{"class":1147,"line":7227},207,[1145,7229,2736],{"class":1312},[1145,7231,3802],{"class":2739},[1145,7233,7235,7237,7240,7242,7244],{"class":1147,"line":7234},208,[1145,7236,2762],{"class":2761},[1145,7238,7239],{"class":2739}," send_confirmation",[1145,7241,2218],{"class":1312},[1145,7243,4927],{"class":3282},[1145,7245,2774],{"class":1312},[1145,7247,7249],{"class":1147,"line":7248},209,[1145,7250,3290],{"class":2779},[1145,7252,7254],{"class":1147,"line":7253},210,[1145,7255,7256],{"class":2783},"    Send order confirmation to customer\n",[1145,7258,7260],{"class":1147,"line":7259},211,[1145,7261,3300],{"class":2783},[1145,7263,7265],{"class":1147,"line":7264},212,[1145,7266,3334],{"class":2783},[1145,7268,7270],{"class":1147,"line":7269},213,[1145,7271,7272],{"class":2783},"    - Final step in workflow\n",[1145,7274,7276],{"class":1147,"line":7275},214,[1145,7277,7278],{"class":2783},"    - Customer communication\n",[1145,7280,7282],{"class":1147,"line":7281},215,[1145,7283,7284],{"class":2783},"    - Order completion\n",[1145,7286,7288],{"class":1147,"line":7287},216,[1145,7289,3290],{"class":2779},[1145,7291,7293,7295,7297,7299,7301,7303,7305,7307,7309,7311,7313,7315],{"class":1147,"line":7292},217,[1145,7294,5435],{"class":1890},[1145,7296,2247],{"class":1312},[1145,7298,4764],{"class":1890},[1145,7300,2554],{"class":1312},[1145,7302,3395],{"class":2586},[1145,7304,2554],{"class":1312},[1145,7306,3400],{"class":2214},[1145,7308,2218],{"class":1312},[1145,7310,3405],{"class":2243},[1145,7312,2247],{"class":1312},[1145,7314,4927],{"class":2214},[1145,7316,2382],{"class":1312},[1145,7318,7320],{"class":1147,"line":7319},218,[1145,7321,3300],{"class":1890},[1145,7323,7325,7327,7329,7331,7333,7335,7338,7340,7342,7344,7346],{"class":1147,"line":7324},219,[1145,7326,5466],{"class":1890},[1145,7328,2554],{"class":1312},[1145,7330,3551],{"class":2214},[1145,7332,2218],{"class":1312},[1145,7334,2798],{"class":2761},[1145,7336,7337],{"class":1162},"\"Sending confirmation for order ",[1145,7339,2805],{"class":2804},[1145,7341,4927],{"class":2214},[1145,7343,2818],{"class":2804},[1145,7345,1382],{"class":1162},[1145,7347,2382],{"class":1312},[1145,7349,7351],{"class":1147,"line":7350},220,[1145,7352,3300],{"class":1890},[1145,7354,7356],{"class":1147,"line":7355},221,[1145,7357,7358],{"class":1151},"    # Send confirmation email to customer\n",[1145,7360,7362,7365,7367,7369],{"class":1147,"line":7361},222,[1145,7363,7364],{"class":1890},"    send_order_email",[1145,7366,2554],{"class":1312},[1145,7368,4023],{"class":2214},[1145,7370,3429],{"class":1312},[1145,7372,7374,7376,7378,7380,7382,7384],{"class":1147,"line":7373},223,[1145,7375,4943],{"class":2214},[1145,7377,2554],{"class":1312},[1145,7379,2279],{"class":2586},[1145,7381,2554],{"class":1312},[1145,7383,3505],{"class":2586},[1145,7385,3446],{"class":1312},[1145,7387,7389,7391,7394,7396],{"class":1147,"line":7388},224,[1145,7390,4279],{"class":1316},[1145,7392,7393],{"class":1162},"Order Confirmation",[1145,7395,1966],{"class":1316},[1145,7397,3446],{"class":1312},[1145,7399,7401,7404,7407,7409,7411,7413],{"class":1147,"line":7400},225,[1145,7402,7403],{"class":2761},"        f",[1145,7405,7406],{"class":1162},"'Your order #",[1145,7408,2805],{"class":2804},[1145,7410,4927],{"class":2214},[1145,7412,2818],{"class":2804},[1145,7414,7415],{"class":1162}," has been confirmed and will be shipped soon!'\n",[1145,7417,7419],{"class":1147,"line":7418},226,[1145,7420,7421],{"class":1312},"    )\n",[1145,7423,7425],{"class":1147,"line":7424},227,[1145,7426,3300],{"class":1890},[1145,7428,7430],{"class":1147,"line":7429},228,[1145,7431,7432],{"class":1151},"    # Update final order status\n",[1145,7434,7436,7439,7441,7443,7445,7447,7450],{"class":1147,"line":7435},229,[1145,7437,7438],{"class":1890},"    order",[1145,7440,2554],{"class":1312},[1145,7442,4948],{"class":2586},[1145,7444,1921],{"class":1312},[1145,7446,1317],{"class":1316},[1145,7448,7449],{"class":1162},"confirmed",[1145,7451,1323],{"class":1316},[1145,7453,7455,7457,7459,7462,7464,7466,7468,7470],{"class":1147,"line":7454},230,[1145,7456,7438],{"class":1890},[1145,7458,2554],{"class":1312},[1145,7460,7461],{"class":2586},"confirmed_at",[1145,7463,1921],{"class":1312},[1145,7465,4371],{"class":1890},[1145,7467,2554],{"class":1312},[1145,7469,4376],{"class":2214},[1145,7471,2722],{"class":1312},[1145,7473,7475,7477,7479,7481],{"class":1147,"line":7474},231,[1145,7476,7438],{"class":1890},[1145,7478,2554],{"class":1312},[1145,7480,3993],{"class":2214},[1145,7482,2722],{"class":1312},[1145,7484,7486],{"class":1147,"line":7485},232,[1145,7487,3300],{"class":1890},[1145,7489,7491,7493,7495,7497,7499,7501,7503,7505,7507,7509,7512],{"class":1147,"line":7490},233,[1145,7492,5466],{"class":1890},[1145,7494,2554],{"class":1312},[1145,7496,3551],{"class":2214},[1145,7498,2218],{"class":1312},[1145,7500,2798],{"class":2761},[1145,7502,5122],{"class":1162},[1145,7504,2805],{"class":2804},[1145,7506,4927],{"class":2214},[1145,7508,2818],{"class":2804},[1145,7510,7511],{"class":1162}," confirmed and customer notified\"",[1145,7513,2382],{"class":1312},[1145,7515,7517,7519,7521,7523,7525,7527,7529],{"class":1147,"line":7516},234,[1145,7518,2827],{"class":1886},[1145,7520,2830],{"class":2761},[1145,7522,5122],{"class":1162},[1145,7524,2805],{"class":2804},[1145,7526,4927],{"class":1890},[1145,7528,2818],{"class":2804},[1145,7530,7531],{"class":1162}," confirmed\"\n",[1145,7533,7535],{"class":1147,"line":7534},235,[1145,7536,1472],{"emptyLinePlaceholder":1471},[1145,7538,7540,7542],{"class":1147,"line":7539},236,[1145,7541,2736],{"class":1312},[1145,7543,3802],{"class":2739},[1145,7545,7547,7549,7552,7554,7556,7558,7561,7563,7566],{"class":1147,"line":7546},237,[1145,7548,2762],{"class":2761},[1145,7550,7551],{"class":2739}," send_order_email",[1145,7553,2218],{"class":1312},[1145,7555,3505],{"class":3282},[1145,7557,1900],{"class":1312},[1145,7559,7560],{"class":3282}," subject",[1145,7562,1900],{"class":1312},[1145,7564,7565],{"class":3282}," message",[1145,7567,2774],{"class":1312},[1145,7569,7571],{"class":1147,"line":7570},238,[1145,7572,3290],{"class":2779},[1145,7574,7576],{"class":1147,"line":7575},239,[1145,7577,7578],{"class":2783},"    Send order-related emails\n",[1145,7580,7582],{"class":1147,"line":7581},240,[1145,7583,3300],{"class":2783},[1145,7585,7587],{"class":1147,"line":7586},241,[1145,7588,7589],{"class":2783},"    This is a utility task that can be reused for different types of order emails\n",[1145,7591,7593],{"class":1147,"line":7592},242,[1145,7594,3290],{"class":2779},[1145,7596,7598,7600],{"class":1147,"line":7597},243,[1145,7599,3363],{"class":1886},[1145,7601,1331],{"class":1312},[1145,7603,7605,7608,7610,7612,7614,7616,7618,7620],{"class":1147,"line":7604},244,[1145,7606,7607],{"class":1886},"        from",[1145,7609,2551],{"class":1890},[1145,7611,2554],{"class":1312},[1145,7613,3138],{"class":1890},[1145,7615,2554],{"class":1312},[1145,7617,3143],{"class":1890},[1145,7619,1894],{"class":1886},[1145,7621,3148],{"class":1890},[1145,7623,7625],{"class":1147,"line":7624},245,[1145,7626,3315],{"class":1890},[1145,7628,7630,7632],{"class":1147,"line":7629},246,[1145,7631,3426],{"class":2214},[1145,7633,3429],{"class":1312},[1145,7635,7637,7639],{"class":1147,"line":7636},247,[1145,7638,3434],{"class":2214},[1145,7640,3446],{"class":1312},[1145,7642,7644,7646],{"class":1147,"line":7643},248,[1145,7645,3451],{"class":2214},[1145,7647,3446],{"class":1312},[1145,7649,7651,7653,7656,7658],{"class":1147,"line":7650},249,[1145,7652,6012],{"class":1316},[1145,7654,7655],{"class":1162},"orders@example.com",[1145,7657,1966],{"class":1316},[1145,7659,3446],{"class":1312},[1145,7661,7663,7666,7668],{"class":1147,"line":7662},250,[1145,7664,7665],{"class":1312},"            [",[1145,7667,3505],{"class":2214},[1145,7669,3508],{"class":1312},[1145,7671,7673,7675,7677,7679],{"class":1147,"line":7672},251,[1145,7674,3513],{"class":2243},[1145,7676,2247],{"class":1312},[1145,7678,3518],{"class":2043},[1145,7680,3446],{"class":1312},[1145,7682,7684],{"class":1147,"line":7683},252,[1145,7685,3529],{"class":1312},[1145,7687,7689],{"class":1147,"line":7688},253,[1145,7690,3315],{"class":1890},[1145,7692,7694,7696,7698,7700,7702,7704,7707,7709,7711,7713,7715],{"class":1147,"line":7693},254,[1145,7695,3546],{"class":1890},[1145,7697,2554],{"class":1312},[1145,7699,3551],{"class":2214},[1145,7701,2218],{"class":1312},[1145,7703,2798],{"class":2761},[1145,7705,7706],{"class":1162},"\"Order email sent to ",[1145,7708,2805],{"class":2804},[1145,7710,3505],{"class":2214},[1145,7712,2818],{"class":2804},[1145,7714,1382],{"class":1162},[1145,7716,2382],{"class":1312},[1145,7718,7720,7722,7724,7726,7728,7730,7732],{"class":1147,"line":7719},255,[1145,7721,3574],{"class":1886},[1145,7723,2830],{"class":2761},[1145,7725,3579],{"class":1162},[1145,7727,2805],{"class":2804},[1145,7729,3505],{"class":1890},[1145,7731,2818],{"class":2804},[1145,7733,1520],{"class":1162},[1145,7735,7737],{"class":1147,"line":7736},256,[1145,7738,3315],{"class":1890},[1145,7740,7742,7744,7746,7748,7750],{"class":1147,"line":7741},257,[1145,7743,3602],{"class":1886},[1145,7745,3665],{"class":3664},[1145,7747,3668],{"class":1886},[1145,7749,3671],{"class":1890},[1145,7751,1331],{"class":1312},[1145,7753,7755,7757,7759,7761,7763,7765,7768,7770,7772,7774,7776,7778,7780,7782,7784],{"class":1147,"line":7754},258,[1145,7756,3546],{"class":1890},[1145,7758,2554],{"class":1312},[1145,7760,3627],{"class":2214},[1145,7762,2218],{"class":1312},[1145,7764,2798],{"class":2761},[1145,7766,7767],{"class":1162},"\"Failed to send email to ",[1145,7769,2805],{"class":2804},[1145,7771,3505],{"class":2214},[1145,7773,2818],{"class":2804},[1145,7775,3704],{"class":1162},[1145,7777,2805],{"class":2804},[1145,7779,3709],{"class":2214},[1145,7781,2818],{"class":2804},[1145,7783,1382],{"class":1162},[1145,7785,2382],{"class":1312},[1145,7787,7789],{"class":1147,"line":7788},259,[1145,7790,3651],{"class":1886},[1026,7792,7793],{},[1050,7794,7795],{},"Key concepts in order processing:",[1754,7797,7798,7808,7814,7820,7826],{},[1047,7799,7800,7803,7804,7807],{},[1050,7801,7802],{},"Sequential Workflows",": Using ",[1142,7805,7806],{},"chain()"," ensures tasks execute in the correct order. Each task receives the result of the previous task.",[1047,7809,7810,7813],{},[1050,7811,7812],{},"Business Logic",": Each task handles a specific business concern (inventory, shipping, payment), making the code modular and testable.",[1047,7815,7816,7819],{},[1050,7817,7818],{},"Error Propagation",": If any task in the chain fails, the entire workflow stops, preventing inconsistent states.",[1047,7821,7822,7825],{},[1050,7823,7824],{},"State Management",": The order status is updated at each step, providing visibility into the process.",[1047,7827,7828,7831],{},[1050,7829,7830],{},"External Service Integration",": Each task handles communication with external services, including proper error handling and timeouts.",[1030,7833,7835],{"id":7834},"advanced-orchestration-patterns","Advanced Orchestration Patterns",[1026,7837,7838],{},"Celery provides several powerful primitives for orchestrating complex workflows. Understanding these patterns is crucial for building robust microservices that can handle real-world business processes.",[1246,7840,7842],{"id":7841},"understanding-celery-primitives","Understanding Celery Primitives",[1026,7844,7845],{},"Before diving into examples, let's understand the key orchestration primitives:",[1754,7847,7848,7854,7860,7866,7872],{},[1047,7849,7850,7853],{},[1050,7851,7852],{},"Chain",": Execute tasks sequentially, where each task receives the result of the previous task",[1047,7855,7856,7859],{},[1050,7857,7858],{},"Group",": Execute tasks in parallel, all tasks run simultaneously",[1047,7861,7862,7865],{},[1050,7863,7864],{},"Chord",": Execute tasks in parallel, then execute a callback task with all results",[1047,7867,7868,7871],{},[1050,7869,7870],{},"Map",": Execute the same task with different arguments in parallel",[1047,7873,7874,7877],{},[1050,7875,7876],{},"Starmap",": Like map, but unpacks arguments",[1246,7879,7881],{"id":7880},"workflow-orchestration-with-chains-and-groups","Workflow Orchestration with Chains and Groups",[1026,7883,7884],{},"Let's see how to combine these primitives for complex business processes:",[1135,7886,7888],{"className":1872,"code":7887,"language":1874,"meta":1140,"style":1140},"# Complex workflow orchestration\nfrom celery import chain, group, chord\n\n@shared_task\ndef orchestrate_user_onboarding(user_id):\n    \"\"\"\n    Orchestrate complete user onboarding process\n    \n    This demonstrates a real-world scenario where some tasks must happen\n    in sequence (user validation) while others can happen in parallel\n    (sending emails, setting up preferences).\n    \"\"\"\n    \n    # Step 1: Sequential tasks that must happen in order\n    # These tasks depend on each other's results\n    sequential_tasks = chain(\n        validate_user_data.s(user_id),      # First: validate the user data\n        create_user_profile.s(),            # Then: create profile (needs validated data)\n        assign_user_role.s(),               # Finally: assign role (needs profile)\n    )\n    \n    # Step 2: Parallel tasks that can run simultaneously\n    # These tasks are independent and can run at the same time\n    parallel_tasks = group(\n        send_welcome_email.s(user_id),      # Send welcome email\n        create_user_preferences.s(user_id), # Set up default preferences\n        setup_default_settings.s(user_id),  # Configure default settings\n        notify_admin_new_user.s(user_id),   # Notify administrators\n    )\n    \n    # Step 3: Combine sequential and parallel execution\n    # First run sequential tasks, then run parallel tasks\n    workflow = chain(\n        sequential_tasks,                    # Must complete first\n        parallel_tasks,                      # Then run in parallel\n        finalize_onboarding.s(user_id)       # Finally, complete onboarding\n    )\n    \n    # Execute the entire workflow\n    result = workflow.apply_async()\n    \n    return {\n        'workflow_id': result.id,\n        'status': 'initiated',\n        'user_id': user_id\n    }\n\n@shared_task\ndef validate_user_data(user_id):\n    \"\"\"Validate user data and return validation results\"\"\"\n    user = User.objects.get(id=user_id)\n    \n    # Perform various validations\n    validations = {\n        'email_valid': '@' in user.email,\n        'name_provided': bool(user.first_name and user.last_name),\n        'age_appropriate': True,  # Add age validation logic\n    }\n    \n    if not all(validations.values()):\n        raise Exception(f\"User validation failed: {validations}\")\n    \n    logger.info(f\"User {user_id} validation passed\")\n    return {'user_id': user_id, 'validations': validations}\n\n@shared_task\ndef create_user_profile(validation_result):\n    \"\"\"Create user profile based on validation results\"\"\"\n    user_id = validation_result['user_id']\n    user = User.objects.get(id=user_id)\n    \n    # Create profile with validated data\n    profile = UserProfile.objects.create(\n        user=user,\n        status='active',\n        created_via='onboarding_workflow'\n    )\n    \n    logger.info(f\"Profile created for user {user_id}\")\n    return {'user_id': user_id, 'profile_id': profile.id}\n\n@shared_task\ndef orchestrate_order_fulfillment(order_id):\n    \"\"\"\n    Orchestrate order fulfillment across multiple services\n    \n    This demonstrates the chord pattern - multiple tasks run in parallel,\n    and when they all complete, a callback task runs with all the results.\n    \"\"\"\n    \n    # Preparation tasks that can run in parallel\n    # All of these need to complete before we can fulfill the order\n    preparation_tasks = group(\n        reserve_inventory.s(order_id),           # Reserve items in warehouse\n        calculate_taxes.s(order_id),             # Calculate tax amounts\n        validate_shipping_address.s(order_id),   # Verify shipping address\n        check_fraud_score.s(order_id),          # Run fraud detection\n    )\n    \n    # Use chord to run preparation tasks in parallel, then run callback\n    # The callback receives a list of all the results\n    fulfillment_workflow = chord(\n        preparation_tasks,                       # Run these in parallel\n        finalize_order_preparation.s(order_id)  # Then run this with all results\n    )\n    \n    result = fulfillment_workflow.apply_async()\n    \n    return {\n        'workflow_id': result.id,\n        'order_id': order_id,\n        'status': 'preparation_started'\n    }\n\n@shared_task\ndef reserve_inventory(order_id):\n    \"\"\"Reserve inventory items for the order\"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    reservations = []\n    for item in order.items.all():\n        # Call inventory service to reserve items\n        response = requests.post(\n            'http://inventory-service:8003/api/reserve/',\n            json={\n                'product_id': item.product_id,\n                'quantity': item.quantity,\n                'order_id': order_id\n            }\n        )\n        \n        if response.status_code == 200:\n            reservation_id = response.json().get('reservation_id')\n            reservations.append({\n                'product_id': item.product_id,\n                'reservation_id': reservation_id\n            })\n        else:\n            raise Exception(f\"Failed to reserve {item.product_id}\")\n    \n    return {'order_id': order_id, 'reservations': reservations}\n\n@shared_task\ndef calculate_taxes(order_id):\n    \"\"\"Calculate tax amounts for the order\"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    # Call tax service\n    response = requests.post(\n        'http://tax-service:8006/api/calculate/',\n        json={\n            'order_id': order_id,\n            'shipping_address': order.shipping_address,\n            'items': [\n                {\n                    'product_id': item.product_id,\n                    'price': float(item.price),\n                    'quantity': item.quantity\n                }\n                for item in order.items.all()\n            ]\n        }\n    )\n    \n    tax_data = response.json()\n    return {'order_id': order_id, 'tax_amount': tax_data.get('total_tax', 0)}\n\n@shared_task\ndef finalize_order_preparation(preparation_results, order_id):\n    \"\"\"\n    Finalize order preparation using results from all preparation tasks\n    \n    This callback task receives the results from all the parallel tasks\n    and uses them to complete the order preparation.\n    \"\"\"\n    order = Order.objects.get(id=order_id)\n    \n    # Process results from all preparation tasks\n    total_tax = 0\n    reservations = []\n    \n    for result in preparation_results:\n        if 'tax_amount' in result:\n            total_tax += result['tax_amount']\n        elif 'reservations' in result:\n            reservations.extend(result['reservations'])\n    \n    # Update order with calculated values\n    order.tax_amount = total_tax\n    order.total_amount = order.subtotal + order.shipping_cost + total_tax\n    order.status = 'ready_to_ship'\n    order.save()\n    \n    # Store reservation information\n    for reservation in reservations:\n        OrderReservation.objects.create(\n            order=order,\n            product_id=reservation['product_id'],\n            reservation_id=reservation['reservation_id']\n        )\n    \n    logger.info(f\"Order {order_id} preparation finalized\")\n    return f\"Order {order_id} ready for fulfillment\"\n",[1142,7889,7890,7895,7913,7917,7923,7936,7940,7945,7949,7954,7959,7964,7968,7972,7977,7982,7993,8011,8025,8039,8043,8047,8052,8057,8068,8086,8104,8122,8140,8144,8148,8153,8158,8169,8179,8189,8207,8211,8215,8220,8235,8239,8245,8265,8284,8297,8301,8305,8311,8324,8333,8360,8364,8369,8378,8407,8441,8459,8463,8467,8490,8513,8517,8542,8573,8577,8583,8597,8606,8628,8654,8658,8663,8684,8694,8710,8724,8728,8732,8757,8793,8797,8803,8816,8820,8825,8829,8834,8839,8843,8847,8852,8857,8868,8886,8904,8922,8940,8944,8948,8953,8958,8970,8980,8998,9002,9006,9021,9025,9031,9049,9063,9080,9084,9088,9094,9107,9116,9142,9146,9156,9176,9181,9195,9206,9212,9230,9248,9260,9265,9269,9273,9292,9320,9333,9351,9364,9369,9375,9402,9406,9438,9442,9448,9461,9470,9496,9500,9505,9520,9531,9538,9552,9570,9582,9587,9605,9628,9644,9649,9670,9675,9680,9684,9688,9703,9753,9757,9763,9781,9785,9790,9794,9799,9804,9808,9834,9838,9843,9853,9861,9865,9879,9895,9915,9932,9956,9960,9965,9978,10006,10023,10033,10037,10042,10055,10070,10080,10100,10119,10123,10127,10152],{"__ignoreMap":1140},[1145,7891,7892],{"class":1147,"line":1148},[1145,7893,7894],{"class":1151},"# Complex workflow orchestration\n",[1145,7896,7897,7899,7901,7903,7905,7907,7909,7911],{"class":1147,"line":1155},[1145,7898,1887],{"class":1886},[1145,7900,2539],{"class":1890},[1145,7902,1894],{"class":1886},[1145,7904,4732],{"class":1890},[1145,7906,1900],{"class":1312},[1145,7908,4727],{"class":1890},[1145,7910,1900],{"class":1312},[1145,7912,4737],{"class":1890},[1145,7914,7915],{"class":1147,"line":1173},[1145,7916,1472],{"emptyLinePlaceholder":1471},[1145,7918,7919,7921],{"class":1147,"line":1186},[1145,7920,2736],{"class":1312},[1145,7922,3802],{"class":2739},[1145,7924,7925,7927,7930,7932,7934],{"class":1147,"line":1199},[1145,7926,2762],{"class":2761},[1145,7928,7929],{"class":2739}," orchestrate_user_onboarding",[1145,7931,2218],{"class":1312},[1145,7933,3410],{"class":3282},[1145,7935,2774],{"class":1312},[1145,7937,7938],{"class":1147,"line":1351},[1145,7939,3290],{"class":2779},[1145,7941,7942],{"class":1147,"line":1362},[1145,7943,7944],{"class":2783},"    Orchestrate complete user onboarding process\n",[1145,7946,7947],{"class":1147,"line":1370},[1145,7948,3300],{"class":2783},[1145,7950,7951],{"class":1147,"line":1388},[1145,7952,7953],{"class":2783},"    This demonstrates a real-world scenario where some tasks must happen\n",[1145,7955,7956],{"class":1147,"line":1403},[1145,7957,7958],{"class":2783},"    in sequence (user validation) while others can happen in parallel\n",[1145,7960,7961],{"class":1147,"line":1411},[1145,7962,7963],{"class":2783},"    (sending emails, setting up preferences).\n",[1145,7965,7966],{"class":1147,"line":1422},[1145,7967,3290],{"class":2779},[1145,7969,7970],{"class":1147,"line":1433},[1145,7971,3300],{"class":1890},[1145,7973,7974],{"class":1147,"line":1441},[1145,7975,7976],{"class":1151},"    # Step 1: Sequential tasks that must happen in order\n",[1145,7978,7979],{"class":1147,"line":1452},[1145,7980,7981],{"class":1151},"    # These tasks depend on each other's results\n",[1145,7983,7984,7987,7989,7991],{"class":1147,"line":1460},[1145,7985,7986],{"class":1890},"    sequential_tasks ",[1145,7988,2247],{"class":1312},[1145,7990,4732],{"class":2214},[1145,7992,3429],{"class":1312},[1145,7994,7995,7998,8000,8002,8004,8006,8008],{"class":1147,"line":1468},[1145,7996,7997],{"class":2214},"        validate_user_data",[1145,7999,2554],{"class":1312},[1145,8001,5021],{"class":2214},[1145,8003,2218],{"class":1312},[1145,8005,3410],{"class":2214},[1145,8007,2240],{"class":1312},[1145,8009,8010],{"class":1151},"      # First: validate the user data\n",[1145,8012,8013,8016,8018,8020,8022],{"class":1147,"line":1475},[1145,8014,8015],{"class":2214},"        create_user_profile",[1145,8017,2554],{"class":1312},[1145,8019,5021],{"class":2214},[1145,8021,5042],{"class":1312},[1145,8023,8024],{"class":1151},"            # Then: create profile (needs validated data)\n",[1145,8026,8027,8030,8032,8034,8036],{"class":1147,"line":1483},[1145,8028,8029],{"class":2214},"        assign_user_role",[1145,8031,2554],{"class":1312},[1145,8033,5021],{"class":2214},[1145,8035,5042],{"class":1312},[1145,8037,8038],{"class":1151},"               # Finally: assign role (needs profile)\n",[1145,8040,8041],{"class":1147,"line":1493},[1145,8042,7421],{"class":1312},[1145,8044,8045],{"class":1147,"line":1503},[1145,8046,3300],{"class":1890},[1145,8048,8049],{"class":1147,"line":1510},[1145,8050,8051],{"class":1151},"    # Step 2: Parallel tasks that can run simultaneously\n",[1145,8053,8054],{"class":1147,"line":1523},[1145,8055,8056],{"class":1151},"    # These tasks are independent and can run at the same time\n",[1145,8058,8059,8062,8064,8066],{"class":1147,"line":1530},[1145,8060,8061],{"class":1890},"    parallel_tasks ",[1145,8063,2247],{"class":1312},[1145,8065,4727],{"class":2214},[1145,8067,3429],{"class":1312},[1145,8069,8070,8073,8075,8077,8079,8081,8083],{"class":1147,"line":1537},[1145,8071,8072],{"class":2214},"        send_welcome_email",[1145,8074,2554],{"class":1312},[1145,8076,5021],{"class":2214},[1145,8078,2218],{"class":1312},[1145,8080,3410],{"class":2214},[1145,8082,2240],{"class":1312},[1145,8084,8085],{"class":1151},"      # Send welcome email\n",[1145,8087,8088,8091,8093,8095,8097,8099,8101],{"class":1147,"line":1542},[1145,8089,8090],{"class":2214},"        create_user_preferences",[1145,8092,2554],{"class":1312},[1145,8094,5021],{"class":2214},[1145,8096,2218],{"class":1312},[1145,8098,3410],{"class":2214},[1145,8100,2240],{"class":1312},[1145,8102,8103],{"class":1151}," # Set up default preferences\n",[1145,8105,8106,8109,8111,8113,8115,8117,8119],{"class":1147,"line":1550},[1145,8107,8108],{"class":2214},"        setup_default_settings",[1145,8110,2554],{"class":1312},[1145,8112,5021],{"class":2214},[1145,8114,2218],{"class":1312},[1145,8116,3410],{"class":2214},[1145,8118,2240],{"class":1312},[1145,8120,8121],{"class":1151},"  # Configure default settings\n",[1145,8123,8124,8127,8129,8131,8133,8135,8137],{"class":1147,"line":1561},[1145,8125,8126],{"class":2214},"        notify_admin_new_user",[1145,8128,2554],{"class":1312},[1145,8130,5021],{"class":2214},[1145,8132,2218],{"class":1312},[1145,8134,3410],{"class":2214},[1145,8136,2240],{"class":1312},[1145,8138,8139],{"class":1151},"   # Notify administrators\n",[1145,8141,8142],{"class":1147,"line":1566},[1145,8143,7421],{"class":1312},[1145,8145,8146],{"class":1147,"line":1574},[1145,8147,3300],{"class":1890},[1145,8149,8150],{"class":1147,"line":1582},[1145,8151,8152],{"class":1151},"    # Step 3: Combine sequential and parallel execution\n",[1145,8154,8155],{"class":1147,"line":2379},[1145,8156,8157],{"class":1151},"    # First run sequential tasks, then run parallel tasks\n",[1145,8159,8160,8163,8165,8167],{"class":1147,"line":2385},[1145,8161,8162],{"class":1890},"    workflow ",[1145,8164,2247],{"class":1312},[1145,8166,4732],{"class":2214},[1145,8168,3429],{"class":1312},[1145,8170,8171,8174,8176],{"class":1147,"line":2390},[1145,8172,8173],{"class":2214},"        sequential_tasks",[1145,8175,1900],{"class":1312},[1145,8177,8178],{"class":1151},"                    # Must complete first\n",[1145,8180,8181,8184,8186],{"class":1147,"line":2396},[1145,8182,8183],{"class":2214},"        parallel_tasks",[1145,8185,1900],{"class":1312},[1145,8187,8188],{"class":1151},"                      # Then run in parallel\n",[1145,8190,8191,8194,8196,8198,8200,8202,8204],{"class":1147,"line":2410},[1145,8192,8193],{"class":2214},"        finalize_onboarding",[1145,8195,2554],{"class":1312},[1145,8197,5021],{"class":2214},[1145,8199,2218],{"class":1312},[1145,8201,3410],{"class":2214},[1145,8203,1623],{"class":1312},[1145,8205,8206],{"class":1151},"       # Finally, complete onboarding\n",[1145,8208,8209],{"class":1147,"line":2424},[1145,8210,7421],{"class":1312},[1145,8212,8213],{"class":1147,"line":2438},[1145,8214,3300],{"class":1890},[1145,8216,8217],{"class":1147,"line":2443},[1145,8218,8219],{"class":1151},"    # Execute the entire workflow\n",[1145,8221,8222,8225,8227,8229,8231,8233],{"class":1147,"line":2449},[1145,8223,8224],{"class":1890},"    result ",[1145,8226,2247],{"class":1312},[1145,8228,5096],{"class":1890},[1145,8230,2554],{"class":1312},[1145,8232,5101],{"class":2214},[1145,8234,2722],{"class":1312},[1145,8236,8237],{"class":1147,"line":2463},[1145,8238,3300],{"class":1890},[1145,8240,8241,8243],{"class":1147,"line":3526},[1145,8242,2827],{"class":1886},[1145,8244,2068],{"class":1312},[1145,8246,8247,8249,8252,8254,8256,8259,8261,8263],{"class":1147,"line":3532},[1145,8248,4279],{"class":1316},[1145,8250,8251],{"class":1162},"workflow_id",[1145,8253,1966],{"class":1316},[1145,8255,1313],{"class":1312},[1145,8257,8258],{"class":1890}," result",[1145,8260,2554],{"class":1312},[1145,8262,3405],{"class":2586},[1145,8264,3446],{"class":1312},[1145,8266,8267,8269,8271,8273,8275,8277,8280,8282],{"class":1147,"line":3537},[1145,8268,4279],{"class":1316},[1145,8270,4948],{"class":1162},[1145,8272,1966],{"class":1316},[1145,8274,1313],{"class":1312},[1145,8276,1317],{"class":1316},[1145,8278,8279],{"class":1162},"initiated",[1145,8281,1966],{"class":1316},[1145,8283,3446],{"class":1312},[1145,8285,8286,8288,8290,8292,8294],{"class":1147,"line":3543},[1145,8287,4279],{"class":1316},[1145,8289,3410],{"class":1162},[1145,8291,1966],{"class":1316},[1145,8293,1313],{"class":1312},[1145,8295,8296],{"class":1890}," user_id\n",[1145,8298,8299],{"class":1147,"line":3571},[1145,8300,4410],{"class":1312},[1145,8302,8303],{"class":1147,"line":3594},[1145,8304,1472],{"emptyLinePlaceholder":1471},[1145,8306,8307,8309],{"class":1147,"line":3599},[1145,8308,2736],{"class":1312},[1145,8310,3802],{"class":2739},[1145,8312,8313,8315,8318,8320,8322],{"class":1147,"line":3614},[1145,8314,2762],{"class":2761},[1145,8316,8317],{"class":2739}," validate_user_data",[1145,8319,2218],{"class":1312},[1145,8321,3410],{"class":3282},[1145,8323,2774],{"class":1312},[1145,8325,8326,8328,8331],{"class":1147,"line":3620},[1145,8327,2780],{"class":2779},[1145,8329,8330],{"class":2783},"Validate user data and return validation results",[1145,8332,2787],{"class":2779},[1145,8334,8335,8338,8340,8342,8344,8346,8348,8350,8352,8354,8356,8358],{"class":1147,"line":3648},[1145,8336,8337],{"class":1890},"    user ",[1145,8339,2247],{"class":1312},[1145,8341,3390],{"class":1890},[1145,8343,2554],{"class":1312},[1145,8345,3395],{"class":2586},[1145,8347,2554],{"class":1312},[1145,8349,3400],{"class":2214},[1145,8351,2218],{"class":1312},[1145,8353,3405],{"class":2243},[1145,8355,2247],{"class":1312},[1145,8357,3410],{"class":2214},[1145,8359,2382],{"class":1312},[1145,8361,8362],{"class":1147,"line":3654},[1145,8363,3300],{"class":1890},[1145,8365,8366],{"class":1147,"line":3659},[1145,8367,8368],{"class":1151},"    # Perform various validations\n",[1145,8370,8371,8374,8376],{"class":1147,"line":3676},[1145,8372,8373],{"class":1890},"    validations ",[1145,8375,2247],{"class":1312},[1145,8377,2068],{"class":1312},[1145,8379,8380,8382,8385,8387,8389,8391,8393,8395,8398,8401,8403,8405],{"class":1147,"line":3682},[1145,8381,4279],{"class":1316},[1145,8383,8384],{"class":1162},"email_valid",[1145,8386,1966],{"class":1316},[1145,8388,1313],{"class":1312},[1145,8390,1317],{"class":1316},[1145,8392,2736],{"class":1162},[1145,8394,1966],{"class":1316},[1145,8396,8397],{"class":1814}," in",[1145,8399,8400],{"class":1890}," user",[1145,8402,2554],{"class":1312},[1145,8404,3505],{"class":2586},[1145,8406,3446],{"class":1312},[1145,8408,8409,8411,8414,8416,8418,8421,8423,8425,8427,8429,8432,8434,8436,8439],{"class":1147,"line":3718},[1145,8410,4279],{"class":1316},[1145,8412,8413],{"class":1162},"name_provided",[1145,8415,1966],{"class":1316},[1145,8417,1313],{"class":1312},[1145,8419,8420],{"class":3664}," bool",[1145,8422,2218],{"class":1312},[1145,8424,2279],{"class":2214},[1145,8426,2554],{"class":1312},[1145,8428,3467],{"class":2586},[1145,8430,8431],{"class":1886}," and",[1145,8433,8400],{"class":2214},[1145,8435,2554],{"class":1312},[1145,8437,8438],{"class":2586},"last_name",[1145,8440,2256],{"class":1312},[1145,8442,8443,8445,8448,8450,8452,8454,8456],{"class":1147,"line":3723},[1145,8444,4279],{"class":1316},[1145,8446,8447],{"class":1162},"age_appropriate",[1145,8449,1966],{"class":1316},[1145,8451,1313],{"class":1312},[1145,8453,2418],{"class":2043},[1145,8455,1900],{"class":1312},[1145,8457,8458],{"class":1151},"  # Add age validation logic\n",[1145,8460,8461],{"class":1147,"line":3729},[1145,8462,4410],{"class":1312},[1145,8464,8465],{"class":1147,"line":3735},[1145,8466,3300],{"class":1890},[1145,8468,8469,8472,8474,8477,8479,8482,8484,8487],{"class":1147,"line":3792},[1145,8470,8471],{"class":1886},"    if",[1145,8473,5657],{"class":1814},[1145,8475,8476],{"class":2792}," all",[1145,8478,2218],{"class":1312},[1145,8480,8481],{"class":2214},"validations",[1145,8483,2554],{"class":1312},[1145,8485,8486],{"class":2214},"values",[1145,8488,8489],{"class":1312},"()):\n",[1145,8491,8492,8494,8496,8498,8500,8503,8505,8507,8509,8511],{"class":1147,"line":3797},[1145,8493,3738],{"class":1886},[1145,8495,3665],{"class":3664},[1145,8497,2218],{"class":1312},[1145,8499,2798],{"class":2761},[1145,8501,8502],{"class":1162},"\"User validation failed: ",[1145,8504,2805],{"class":2804},[1145,8506,8481],{"class":2214},[1145,8508,2818],{"class":2804},[1145,8510,1382],{"class":1162},[1145,8512,2382],{"class":1312},[1145,8514,8515],{"class":1147,"line":3805},[1145,8516,3300],{"class":1890},[1145,8518,8519,8521,8523,8525,8527,8529,8531,8533,8535,8537,8540],{"class":1147,"line":3824},[1145,8520,5466],{"class":1890},[1145,8522,2554],{"class":1312},[1145,8524,3551],{"class":2214},[1145,8526,2218],{"class":1312},[1145,8528,2798],{"class":2761},[1145,8530,3634],{"class":1162},[1145,8532,2805],{"class":2804},[1145,8534,3410],{"class":2214},[1145,8536,2818],{"class":2804},[1145,8538,8539],{"class":1162}," validation passed\"",[1145,8541,2382],{"class":1312},[1145,8543,8544,8546,8548,8550,8552,8554,8556,8558,8560,8562,8564,8566,8568,8571],{"class":1147,"line":3829},[1145,8545,2827],{"class":1886},[1145,8547,2083],{"class":1312},[1145,8549,1966],{"class":1316},[1145,8551,3410],{"class":1162},[1145,8553,1966],{"class":1316},[1145,8555,1313],{"class":1312},[1145,8557,3283],{"class":1890},[1145,8559,1900],{"class":1312},[1145,8561,1317],{"class":1316},[1145,8563,8481],{"class":1162},[1145,8565,1966],{"class":1316},[1145,8567,1313],{"class":1312},[1145,8569,8570],{"class":1890}," validations",[1145,8572,2176],{"class":1312},[1145,8574,8575],{"class":1147,"line":3835},[1145,8576,1472],{"emptyLinePlaceholder":1471},[1145,8578,8579,8581],{"class":1147,"line":3840},[1145,8580,2736],{"class":1312},[1145,8582,3802],{"class":2739},[1145,8584,8585,8587,8590,8592,8595],{"class":1147,"line":3845},[1145,8586,2762],{"class":2761},[1145,8588,8589],{"class":2739}," create_user_profile",[1145,8591,2218],{"class":1312},[1145,8593,8594],{"class":3282},"validation_result",[1145,8596,2774],{"class":1312},[1145,8598,8599,8601,8604],{"class":1147,"line":3851},[1145,8600,2780],{"class":2779},[1145,8602,8603],{"class":2783},"Create user profile based on validation results",[1145,8605,2787],{"class":2779},[1145,8607,8608,8611,8613,8616,8619,8621,8623,8625],{"class":1147,"line":3857},[1145,8609,8610],{"class":1890},"    user_id ",[1145,8612,2247],{"class":1312},[1145,8614,8615],{"class":1890}," validation_result",[1145,8617,8618],{"class":1312},"[",[1145,8620,1966],{"class":1316},[1145,8622,3410],{"class":1162},[1145,8624,1966],{"class":1316},[1145,8626,8627],{"class":1312},"]\n",[1145,8629,8630,8632,8634,8636,8638,8640,8642,8644,8646,8648,8650,8652],{"class":1147,"line":3863},[1145,8631,8337],{"class":1890},[1145,8633,2247],{"class":1312},[1145,8635,3390],{"class":1890},[1145,8637,2554],{"class":1312},[1145,8639,3395],{"class":2586},[1145,8641,2554],{"class":1312},[1145,8643,3400],{"class":2214},[1145,8645,2218],{"class":1312},[1145,8647,3405],{"class":2243},[1145,8649,2247],{"class":1312},[1145,8651,3410],{"class":2214},[1145,8653,2382],{"class":1312},[1145,8655,8656],{"class":1147,"line":3868},[1145,8657,3300],{"class":1890},[1145,8659,8660],{"class":1147,"line":3875},[1145,8661,8662],{"class":1151},"    # Create profile with validated data\n",[1145,8664,8665,8668,8670,8673,8675,8677,8679,8682],{"class":1147,"line":3902},[1145,8666,8667],{"class":1890},"    profile ",[1145,8669,2247],{"class":1312},[1145,8671,8672],{"class":1890}," UserProfile",[1145,8674,2554],{"class":1312},[1145,8676,3395],{"class":2586},[1145,8678,2554],{"class":1312},[1145,8680,8681],{"class":2214},"create",[1145,8683,3429],{"class":1312},[1145,8685,8686,8688,8690,8692],{"class":1147,"line":3907},[1145,8687,3988],{"class":2243},[1145,8689,2247],{"class":1312},[1145,8691,2279],{"class":2214},[1145,8693,3446],{"class":1312},[1145,8695,8696,8699,8701,8703,8706,8708],{"class":1147,"line":3913},[1145,8697,8698],{"class":2243},"        status",[1145,8700,2247],{"class":1312},[1145,8702,1966],{"class":1316},[1145,8704,8705],{"class":1162},"active",[1145,8707,1966],{"class":1316},[1145,8709,3446],{"class":1312},[1145,8711,8712,8715,8717,8719,8722],{"class":1147,"line":3940},[1145,8713,8714],{"class":2243},"        created_via",[1145,8716,2247],{"class":1312},[1145,8718,1966],{"class":1316},[1145,8720,8721],{"class":1162},"onboarding_workflow",[1145,8723,1323],{"class":1316},[1145,8725,8726],{"class":1147,"line":3959},[1145,8727,7421],{"class":1312},[1145,8729,8730],{"class":1147,"line":3980},[1145,8731,3300],{"class":1890},[1145,8733,8734,8736,8738,8740,8742,8744,8747,8749,8751,8753,8755],{"class":1147,"line":3985},[1145,8735,5466],{"class":1890},[1145,8737,2554],{"class":1312},[1145,8739,3551],{"class":2214},[1145,8741,2218],{"class":1312},[1145,8743,2798],{"class":2761},[1145,8745,8746],{"class":1162},"\"Profile created for user ",[1145,8748,2805],{"class":2804},[1145,8750,3410],{"class":2214},[1145,8752,2818],{"class":2804},[1145,8754,1382],{"class":1162},[1145,8756,2382],{"class":1312},[1145,8758,8759,8761,8763,8765,8767,8769,8771,8773,8775,8777,8780,8782,8784,8787,8789,8791],{"class":1147,"line":3998},[1145,8760,2827],{"class":1886},[1145,8762,2083],{"class":1312},[1145,8764,1966],{"class":1316},[1145,8766,3410],{"class":1162},[1145,8768,1966],{"class":1316},[1145,8770,1313],{"class":1312},[1145,8772,3283],{"class":1890},[1145,8774,1900],{"class":1312},[1145,8776,1317],{"class":1316},[1145,8778,8779],{"class":1162},"profile_id",[1145,8781,1966],{"class":1316},[1145,8783,1313],{"class":1312},[1145,8785,8786],{"class":1890}," profile",[1145,8788,2554],{"class":1312},[1145,8790,3405],{"class":2586},[1145,8792,2176],{"class":1312},[1145,8794,8795],{"class":1147,"line":4003},[1145,8796,1472],{"emptyLinePlaceholder":1471},[1145,8798,8799,8801],{"class":1147,"line":4009},[1145,8800,2736],{"class":1312},[1145,8802,3802],{"class":2739},[1145,8804,8805,8807,8810,8812,8814],{"class":1147,"line":4015},[1145,8806,2762],{"class":2761},[1145,8808,8809],{"class":2739}," orchestrate_order_fulfillment",[1145,8811,2218],{"class":1312},[1145,8813,4927],{"class":3282},[1145,8815,2774],{"class":1312},[1145,8817,8818],{"class":1147,"line":4036},[1145,8819,3290],{"class":2779},[1145,8821,8822],{"class":1147,"line":4041},[1145,8823,8824],{"class":2783},"    Orchestrate order fulfillment across multiple services\n",[1145,8826,8827],{"class":1147,"line":4067},[1145,8828,3300],{"class":2783},[1145,8830,8831],{"class":1147,"line":4084},[1145,8832,8833],{"class":2783},"    This demonstrates the chord pattern - multiple tasks run in parallel,\n",[1145,8835,8836],{"class":1147,"line":4089},[1145,8837,8838],{"class":2783},"    and when they all complete, a callback task runs with all the results.\n",[1145,8840,8841],{"class":1147,"line":4102},[1145,8842,3290],{"class":2779},[1145,8844,8845],{"class":1147,"line":4128},[1145,8846,3300],{"class":1890},[1145,8848,8849],{"class":1147,"line":4133},[1145,8850,8851],{"class":1151},"    # Preparation tasks that can run in parallel\n",[1145,8853,8854],{"class":1147,"line":4146},[1145,8855,8856],{"class":1151},"    # All of these need to complete before we can fulfill the order\n",[1145,8858,8859,8862,8864,8866],{"class":1147,"line":4180},[1145,8860,8861],{"class":1890},"    preparation_tasks ",[1145,8863,2247],{"class":1312},[1145,8865,4727],{"class":2214},[1145,8867,3429],{"class":1312},[1145,8869,8870,8873,8875,8877,8879,8881,8883],{"class":1147,"line":4185},[1145,8871,8872],{"class":2214},"        reserve_inventory",[1145,8874,2554],{"class":1312},[1145,8876,5021],{"class":2214},[1145,8878,2218],{"class":1312},[1145,8880,4927],{"class":2214},[1145,8882,2240],{"class":1312},[1145,8884,8885],{"class":1151},"           # Reserve items in warehouse\n",[1145,8887,8888,8891,8893,8895,8897,8899,8901],{"class":1147,"line":4190},[1145,8889,8890],{"class":2214},"        calculate_taxes",[1145,8892,2554],{"class":1312},[1145,8894,5021],{"class":2214},[1145,8896,2218],{"class":1312},[1145,8898,4927],{"class":2214},[1145,8900,2240],{"class":1312},[1145,8902,8903],{"class":1151},"             # Calculate tax amounts\n",[1145,8905,8906,8909,8911,8913,8915,8917,8919],{"class":1147,"line":4197},[1145,8907,8908],{"class":2214},"        validate_shipping_address",[1145,8910,2554],{"class":1312},[1145,8912,5021],{"class":2214},[1145,8914,2218],{"class":1312},[1145,8916,4927],{"class":2214},[1145,8918,2240],{"class":1312},[1145,8920,8921],{"class":1151},"   # Verify shipping address\n",[1145,8923,8924,8927,8929,8931,8933,8935,8937],{"class":1147,"line":4215},[1145,8925,8926],{"class":2214},"        check_fraud_score",[1145,8928,2554],{"class":1312},[1145,8930,5021],{"class":2214},[1145,8932,2218],{"class":1312},[1145,8934,4927],{"class":2214},[1145,8936,2240],{"class":1312},[1145,8938,8939],{"class":1151},"          # Run fraud detection\n",[1145,8941,8942],{"class":1147,"line":4220},[1145,8943,7421],{"class":1312},[1145,8945,8946],{"class":1147,"line":4226},[1145,8947,3300],{"class":1890},[1145,8949,8950],{"class":1147,"line":4231},[1145,8951,8952],{"class":1151},"    # Use chord to run preparation tasks in parallel, then run callback\n",[1145,8954,8955],{"class":1147,"line":4236},[1145,8956,8957],{"class":1151},"    # The callback receives a list of all the results\n",[1145,8959,8960,8963,8965,8968],{"class":1147,"line":4242},[1145,8961,8962],{"class":1890},"    fulfillment_workflow ",[1145,8964,2247],{"class":1312},[1145,8966,8967],{"class":2214}," chord",[1145,8969,3429],{"class":1312},[1145,8971,8972,8975,8977],{"class":1147,"line":4248},[1145,8973,8974],{"class":2214},"        preparation_tasks",[1145,8976,1900],{"class":1312},[1145,8978,8979],{"class":1151},"                       # Run these in parallel\n",[1145,8981,8982,8985,8987,8989,8991,8993,8995],{"class":1147,"line":4254},[1145,8983,8984],{"class":2214},"        finalize_order_preparation",[1145,8986,2554],{"class":1312},[1145,8988,5021],{"class":2214},[1145,8990,2218],{"class":1312},[1145,8992,4927],{"class":2214},[1145,8994,1623],{"class":1312},[1145,8996,8997],{"class":1151},"  # Then run this with all results\n",[1145,8999,9000],{"class":1147,"line":4259},[1145,9001,7421],{"class":1312},[1145,9003,9004],{"class":1147,"line":4265},[1145,9005,3300],{"class":1890},[1145,9007,9008,9010,9012,9015,9017,9019],{"class":1147,"line":4276},[1145,9009,8224],{"class":1890},[1145,9011,2247],{"class":1312},[1145,9013,9014],{"class":1890}," fulfillment_workflow",[1145,9016,2554],{"class":1312},[1145,9018,5101],{"class":2214},[1145,9020,2722],{"class":1312},[1145,9022,9023],{"class":1147,"line":4289},[1145,9024,3300],{"class":1890},[1145,9026,9027,9029],{"class":1147,"line":4301},[1145,9028,2827],{"class":1886},[1145,9030,2068],{"class":1312},[1145,9032,9033,9035,9037,9039,9041,9043,9045,9047],{"class":1147,"line":4307},[1145,9034,4279],{"class":1316},[1145,9036,8251],{"class":1162},[1145,9038,1966],{"class":1316},[1145,9040,1313],{"class":1312},[1145,9042,8258],{"class":1890},[1145,9044,2554],{"class":1312},[1145,9046,3405],{"class":2586},[1145,9048,3446],{"class":1312},[1145,9050,9051,9053,9055,9057,9059,9061],{"class":1147,"line":4312},[1145,9052,4279],{"class":1316},[1145,9054,4927],{"class":1162},[1145,9056,1966],{"class":1316},[1145,9058,1313],{"class":1312},[1145,9060,4847],{"class":1890},[1145,9062,3446],{"class":1312},[1145,9064,9065,9067,9069,9071,9073,9075,9078],{"class":1147,"line":4318},[1145,9066,4279],{"class":1316},[1145,9068,4948],{"class":1162},[1145,9070,1966],{"class":1316},[1145,9072,1313],{"class":1312},[1145,9074,1317],{"class":1316},[1145,9076,9077],{"class":1162},"preparation_started",[1145,9079,1323],{"class":1316},[1145,9081,9082],{"class":1147,"line":4328},[1145,9083,4410],{"class":1312},[1145,9085,9086],{"class":1147,"line":4343},[1145,9087,1472],{"emptyLinePlaceholder":1471},[1145,9089,9090,9092],{"class":1147,"line":4359},[1145,9091,2736],{"class":1312},[1145,9093,3802],{"class":2739},[1145,9095,9096,9098,9101,9103,9105],{"class":1147,"line":4388},[1145,9097,2762],{"class":2761},[1145,9099,9100],{"class":2739}," reserve_inventory",[1145,9102,2218],{"class":1312},[1145,9104,4927],{"class":3282},[1145,9106,2774],{"class":1312},[1145,9108,9109,9111,9114],{"class":1147,"line":4407},[1145,9110,2780],{"class":2779},[1145,9112,9113],{"class":2783},"Reserve inventory items for the order",[1145,9115,2787],{"class":2779},[1145,9117,9118,9120,9122,9124,9126,9128,9130,9132,9134,9136,9138,9140],{"class":1147,"line":4413},[1145,9119,5435],{"class":1890},[1145,9121,2247],{"class":1312},[1145,9123,4764],{"class":1890},[1145,9125,2554],{"class":1312},[1145,9127,3395],{"class":2586},[1145,9129,2554],{"class":1312},[1145,9131,3400],{"class":2214},[1145,9133,2218],{"class":1312},[1145,9135,3405],{"class":2243},[1145,9137,2247],{"class":1312},[1145,9139,4927],{"class":2214},[1145,9141,2382],{"class":1312},[1145,9143,9144],{"class":1147,"line":4418},[1145,9145,3300],{"class":1890},[1145,9147,9148,9151,9153],{"class":1147,"line":4424},[1145,9149,9150],{"class":1890},"    reservations ",[1145,9152,2247],{"class":1312},[1145,9154,9155],{"class":1312}," []\n",[1145,9157,9158,9160,9162,9164,9166,9168,9170,9172,9174],{"class":1147,"line":4440},[1145,9159,4427],{"class":1886},[1145,9161,5503],{"class":1890},[1145,9163,3927],{"class":1886},[1145,9165,5508],{"class":1890},[1145,9167,2554],{"class":1312},[1145,9169,3934],{"class":2586},[1145,9171,2554],{"class":1312},[1145,9173,5517],{"class":2214},[1145,9175,3937],{"class":1312},[1145,9177,9178],{"class":1147,"line":4448},[1145,9179,9180],{"class":1151},"        # Call inventory service to reserve items\n",[1145,9182,9183,9185,9187,9189,9191,9193],{"class":1147,"line":4466},[1145,9184,5997],{"class":1890},[1145,9186,2247],{"class":1312},[1145,9188,4456],{"class":1890},[1145,9190,2554],{"class":1312},[1145,9192,4461],{"class":2214},[1145,9194,3429],{"class":1312},[1145,9196,9197,9199,9202,9204],{"class":1147,"line":4474},[1145,9198,6012],{"class":1316},[1145,9200,9201],{"class":1162},"http://inventory-service:8003/api/reserve/",[1145,9203,1966],{"class":1316},[1145,9205,3446],{"class":1312},[1145,9207,9208,9210],{"class":1147,"line":4487},[1145,9209,6024],{"class":2243},[1145,9211,5563],{"class":1312},[1145,9213,9214,9216,9218,9220,9222,9224,9226,9228],{"class":1147,"line":4503},[1145,9215,5549],{"class":1316},[1145,9217,5571],{"class":1162},[1145,9219,1966],{"class":1316},[1145,9221,1313],{"class":1312},[1145,9223,5578],{"class":2214},[1145,9225,2554],{"class":1312},[1145,9227,5571],{"class":2586},[1145,9229,3446],{"class":1312},[1145,9231,9232,9234,9236,9238,9240,9242,9244,9246],{"class":1147,"line":4530},[1145,9233,5549],{"class":1316},[1145,9235,5591],{"class":1162},[1145,9237,1966],{"class":1316},[1145,9239,1313],{"class":1312},[1145,9241,5578],{"class":2214},[1145,9243,2554],{"class":1312},[1145,9245,5591],{"class":2586},[1145,9247,3446],{"class":1312},[1145,9249,9250,9252,9254,9256,9258],{"class":1147,"line":4536},[1145,9251,5549],{"class":1316},[1145,9253,4927],{"class":1162},[1145,9255,1966],{"class":1316},[1145,9257,1313],{"class":1312},[1145,9259,6413],{"class":2214},[1145,9261,9262],{"class":1147,"line":4553},[1145,9263,9264],{"class":1312},"            }\n",[1145,9266,9267],{"class":1147,"line":4559},[1145,9268,3529],{"class":1312},[1145,9270,9271],{"class":1147,"line":4597},[1145,9272,3315],{"class":1890},[1145,9274,9275,9277,9279,9281,9284,9287,9290],{"class":1147,"line":4602},[1145,9276,6871],{"class":1886},[1145,9278,5644],{"class":1890},[1145,9280,2554],{"class":1312},[1145,9282,9283],{"class":2586},"status_code",[1145,9285,9286],{"class":1814}," ==",[1145,9288,9289],{"class":1169}," 200",[1145,9291,1331],{"class":1312},[1145,9293,9294,9297,9299,9301,9303,9305,9307,9309,9311,9313,9316,9318],{"class":1147,"line":4621},[1145,9295,9296],{"class":1890},"            reservation_id ",[1145,9298,2247],{"class":1312},[1145,9300,5644],{"class":1890},[1145,9302,2554],{"class":1312},[1145,9304,1963],{"class":2214},[1145,9306,4379],{"class":1312},[1145,9308,3400],{"class":2214},[1145,9310,2218],{"class":1312},[1145,9312,1966],{"class":1316},[1145,9314,9315],{"class":1162},"reservation_id",[1145,9317,1966],{"class":1316},[1145,9319,2382],{"class":1312},[1145,9321,9322,9325,9327,9330],{"class":1147,"line":4627},[1145,9323,9324],{"class":1890},"            reservations",[1145,9326,2554],{"class":1312},[1145,9328,9329],{"class":2214},"append",[1145,9331,9332],{"class":1312},"({\n",[1145,9334,9335,9337,9339,9341,9343,9345,9347,9349],{"class":1147,"line":4633},[1145,9336,5549],{"class":1316},[1145,9338,5571],{"class":1162},[1145,9340,1966],{"class":1316},[1145,9342,1313],{"class":1312},[1145,9344,5578],{"class":2214},[1145,9346,2554],{"class":1312},[1145,9348,5571],{"class":2586},[1145,9350,3446],{"class":1312},[1145,9352,9353,9355,9357,9359,9361],{"class":1147,"line":6204},[1145,9354,5549],{"class":1316},[1145,9356,9315],{"class":1162},[1145,9358,1966],{"class":1316},[1145,9360,1313],{"class":1312},[1145,9362,9363],{"class":2214}," reservation_id\n",[1145,9365,9366],{"class":1147,"line":6216},[1145,9367,9368],{"class":1312},"            })\n",[1145,9370,9371,9373],{"class":1147,"line":6221},[1145,9372,7040],{"class":1886},[1145,9374,1331],{"class":1312},[1145,9376,9377,9379,9381,9383,9385,9388,9390,9392,9394,9396,9398,9400],{"class":1147,"line":6237},[1145,9378,5805],{"class":1886},[1145,9380,3665],{"class":3664},[1145,9382,2218],{"class":1312},[1145,9384,2798],{"class":2761},[1145,9386,9387],{"class":1162},"\"Failed to reserve ",[1145,9389,2805],{"class":2804},[1145,9391,5699],{"class":2214},[1145,9393,2554],{"class":1312},[1145,9395,5571],{"class":2586},[1145,9397,2818],{"class":2804},[1145,9399,1382],{"class":1162},[1145,9401,2382],{"class":1312},[1145,9403,9404],{"class":1147,"line":6268},[1145,9405,3300],{"class":1890},[1145,9407,9408,9410,9412,9414,9416,9418,9420,9422,9424,9426,9429,9431,9433,9436],{"class":1147,"line":6293},[1145,9409,2827],{"class":1886},[1145,9411,2083],{"class":1312},[1145,9413,1966],{"class":1316},[1145,9415,4927],{"class":1162},[1145,9417,1966],{"class":1316},[1145,9419,1313],{"class":1312},[1145,9421,4847],{"class":1890},[1145,9423,1900],{"class":1312},[1145,9425,1317],{"class":1316},[1145,9427,9428],{"class":1162},"reservations",[1145,9430,1966],{"class":1316},[1145,9432,1313],{"class":1312},[1145,9434,9435],{"class":1890}," reservations",[1145,9437,2176],{"class":1312},[1145,9439,9440],{"class":1147,"line":6298},[1145,9441,1472],{"emptyLinePlaceholder":1471},[1145,9443,9444,9446],{"class":1147,"line":6304},[1145,9445,2736],{"class":1312},[1145,9447,3802],{"class":2739},[1145,9449,9450,9452,9455,9457,9459],{"class":1147,"line":6319},[1145,9451,2762],{"class":2761},[1145,9453,9454],{"class":2739}," calculate_taxes",[1145,9456,2218],{"class":1312},[1145,9458,4927],{"class":3282},[1145,9460,2774],{"class":1312},[1145,9462,9463,9465,9468],{"class":1147,"line":6333},[1145,9464,2780],{"class":2779},[1145,9466,9467],{"class":2783},"Calculate tax amounts for the order",[1145,9469,2787],{"class":2779},[1145,9471,9472,9474,9476,9478,9480,9482,9484,9486,9488,9490,9492,9494],{"class":1147,"line":6357},[1145,9473,5435],{"class":1890},[1145,9475,2247],{"class":1312},[1145,9477,4764],{"class":1890},[1145,9479,2554],{"class":1312},[1145,9481,3395],{"class":2586},[1145,9483,2554],{"class":1312},[1145,9485,3400],{"class":2214},[1145,9487,2218],{"class":1312},[1145,9489,3405],{"class":2243},[1145,9491,2247],{"class":1312},[1145,9493,4927],{"class":2214},[1145,9495,2382],{"class":1312},[1145,9497,9498],{"class":1147,"line":6368},[1145,9499,3300],{"class":1890},[1145,9501,9502],{"class":1147,"line":6373},[1145,9503,9504],{"class":1151},"    # Call tax service\n",[1145,9506,9507,9510,9512,9514,9516,9518],{"class":1147,"line":6408},[1145,9508,9509],{"class":1890},"    response ",[1145,9511,2247],{"class":1312},[1145,9513,4456],{"class":1890},[1145,9515,2554],{"class":1312},[1145,9517,4461],{"class":2214},[1145,9519,3429],{"class":1312},[1145,9521,9522,9524,9527,9529],{"class":1147,"line":6416},[1145,9523,4279],{"class":1316},[1145,9525,9526],{"class":1162},"http://tax-service:8006/api/calculate/",[1145,9528,1966],{"class":1316},[1145,9530,3446],{"class":1312},[1145,9532,9533,9536],{"class":1147,"line":6421},[1145,9534,9535],{"class":2243},"        json",[1145,9537,5563],{"class":1312},[1145,9539,9540,9542,9544,9546,9548,9550],{"class":1147,"line":6438},[1145,9541,6012],{"class":1316},[1145,9543,4927],{"class":1162},[1145,9545,1966],{"class":1316},[1145,9547,1313],{"class":1312},[1145,9549,4847],{"class":2214},[1145,9551,3446],{"class":1312},[1145,9553,9554,9556,9558,9560,9562,9564,9566,9568],{"class":1147,"line":6472},[1145,9555,6012],{"class":1316},[1145,9557,6058],{"class":1162},[1145,9559,1966],{"class":1316},[1145,9561,1313],{"class":1312},[1145,9563,5508],{"class":2214},[1145,9565,2554],{"class":1312},[1145,9567,6058],{"class":2586},[1145,9569,3446],{"class":1312},[1145,9571,9572,9574,9576,9578,9580],{"class":1147,"line":6496},[1145,9573,6012],{"class":1316},[1145,9575,3934],{"class":1162},[1145,9577,1966],{"class":1316},[1145,9579,1313],{"class":1312},[1145,9581,4273],{"class":1312},[1145,9583,9584],{"class":1147,"line":6501},[1145,9585,9586],{"class":1312},"                {\n",[1145,9588,9589,9591,9593,9595,9597,9599,9601,9603],{"class":1147,"line":6508},[1145,9590,5568],{"class":1316},[1145,9592,5571],{"class":1162},[1145,9594,1966],{"class":1316},[1145,9596,1313],{"class":1312},[1145,9598,5578],{"class":2214},[1145,9600,2554],{"class":1312},[1145,9602,5571],{"class":2586},[1145,9604,3446],{"class":1312},[1145,9606,9607,9609,9612,9614,9616,9618,9620,9622,9624,9626],{"class":1147,"line":6522},[1145,9608,5568],{"class":1316},[1145,9610,9611],{"class":1162},"price",[1145,9613,1966],{"class":1316},[1145,9615,1313],{"class":1312},[1145,9617,6709],{"class":3664},[1145,9619,2218],{"class":1312},[1145,9621,5699],{"class":2214},[1145,9623,2554],{"class":1312},[1145,9625,9611],{"class":2586},[1145,9627,2256],{"class":1312},[1145,9629,9630,9632,9634,9636,9638,9640,9642],{"class":1147,"line":6527},[1145,9631,5568],{"class":1316},[1145,9633,5591],{"class":1162},[1145,9635,1966],{"class":1316},[1145,9637,1313],{"class":1312},[1145,9639,5578],{"class":2214},[1145,9641,2554],{"class":1312},[1145,9643,5602],{"class":2586},[1145,9645,9646],{"class":1147,"line":6533},[1145,9647,9648],{"class":1312},"                }\n",[1145,9650,9651,9654,9656,9658,9660,9662,9664,9666,9668],{"class":1147,"line":6538},[1145,9652,9653],{"class":1886},"                for",[1145,9655,5503],{"class":2214},[1145,9657,3927],{"class":1886},[1145,9659,5508],{"class":2214},[1145,9661,2554],{"class":1312},[1145,9663,3934],{"class":2586},[1145,9665,2554],{"class":1312},[1145,9667,5517],{"class":2214},[1145,9669,2722],{"class":1312},[1145,9671,9672],{"class":1147,"line":6543},[1145,9673,9674],{"class":1312},"            ]\n",[1145,9676,9677],{"class":1147,"line":6549},[1145,9678,9679],{"class":1312},"        }\n",[1145,9681,9682],{"class":1147,"line":6555},[1145,9683,7421],{"class":1312},[1145,9685,9686],{"class":1147,"line":6561},[1145,9687,3300],{"class":1890},[1145,9689,9690,9693,9695,9697,9699,9701],{"class":1147,"line":6567},[1145,9691,9692],{"class":1890},"    tax_data ",[1145,9694,2247],{"class":1312},[1145,9696,5644],{"class":1890},[1145,9698,2554],{"class":1312},[1145,9700,1963],{"class":2214},[1145,9702,2722],{"class":1312},[1145,9704,9705,9707,9709,9711,9713,9715,9717,9719,9721,9723,9726,9728,9730,9733,9735,9737,9739,9741,9744,9746,9748,9750],{"class":1147,"line":6572},[1145,9706,2827],{"class":1886},[1145,9708,2083],{"class":1312},[1145,9710,1966],{"class":1316},[1145,9712,4927],{"class":1162},[1145,9714,1966],{"class":1316},[1145,9716,1313],{"class":1312},[1145,9718,4847],{"class":1890},[1145,9720,1900],{"class":1312},[1145,9722,1317],{"class":1316},[1145,9724,9725],{"class":1162},"tax_amount",[1145,9727,1966],{"class":1316},[1145,9729,1313],{"class":1312},[1145,9731,9732],{"class":1890}," tax_data",[1145,9734,2554],{"class":1312},[1145,9736,3400],{"class":2214},[1145,9738,2218],{"class":1312},[1145,9740,1966],{"class":1316},[1145,9742,9743],{"class":1162},"total_tax",[1145,9745,1966],{"class":1316},[1145,9747,1900],{"class":1312},[1145,9749,6263],{"class":1169},[1145,9751,9752],{"class":1312},")}\n",[1145,9754,9755],{"class":1147,"line":6599},[1145,9756,1472],{"emptyLinePlaceholder":1471},[1145,9758,9759,9761],{"class":1147,"line":6604},[1145,9760,2736],{"class":1312},[1145,9762,3802],{"class":2739},[1145,9764,9765,9767,9770,9772,9775,9777,9779],{"class":1147,"line":6630},[1145,9766,2762],{"class":2761},[1145,9768,9769],{"class":2739}," finalize_order_preparation",[1145,9771,2218],{"class":1312},[1145,9773,9774],{"class":3282},"preparation_results",[1145,9776,1900],{"class":1312},[1145,9778,4847],{"class":3282},[1145,9780,2774],{"class":1312},[1145,9782,9783],{"class":1147,"line":6635},[1145,9784,3290],{"class":2779},[1145,9786,9787],{"class":1147,"line":6642},[1145,9788,9789],{"class":2783},"    Finalize order preparation using results from all preparation tasks\n",[1145,9791,9792],{"class":1147,"line":6648},[1145,9793,3300],{"class":2783},[1145,9795,9796],{"class":1147,"line":6663},[1145,9797,9798],{"class":2783},"    This callback task receives the results from all the parallel tasks\n",[1145,9800,9801],{"class":1147,"line":6675},[1145,9802,9803],{"class":2783},"    and uses them to complete the order preparation.\n",[1145,9805,9806],{"class":1147,"line":6682},[1145,9807,3290],{"class":2779},[1145,9809,9810,9812,9814,9816,9818,9820,9822,9824,9826,9828,9830,9832],{"class":1147,"line":6697},[1145,9811,5435],{"class":1890},[1145,9813,2247],{"class":1312},[1145,9815,4764],{"class":1890},[1145,9817,2554],{"class":1312},[1145,9819,3395],{"class":2586},[1145,9821,2554],{"class":1312},[1145,9823,3400],{"class":2214},[1145,9825,2218],{"class":1312},[1145,9827,3405],{"class":2243},[1145,9829,2247],{"class":1312},[1145,9831,4927],{"class":2214},[1145,9833,2382],{"class":1312},[1145,9835,9836],{"class":1147,"line":6722},[1145,9837,3300],{"class":1890},[1145,9839,9840],{"class":1147,"line":6743},[1145,9841,9842],{"class":1151},"    # Process results from all preparation tasks\n",[1145,9844,9845,9848,9850],{"class":1147,"line":6763},[1145,9846,9847],{"class":1890},"    total_tax ",[1145,9849,2247],{"class":1312},[1145,9851,9852],{"class":1169}," 0\n",[1145,9854,9855,9857,9859],{"class":1147,"line":6783},[1145,9856,9150],{"class":1890},[1145,9858,2247],{"class":1312},[1145,9860,9155],{"class":1312},[1145,9862,9863],{"class":1147,"line":6808},[1145,9864,3300],{"class":1890},[1145,9866,9867,9869,9872,9874,9877],{"class":1147,"line":6813},[1145,9868,4427],{"class":1886},[1145,9870,9871],{"class":1890}," result ",[1145,9873,3927],{"class":1886},[1145,9875,9876],{"class":1890}," preparation_results",[1145,9878,1331],{"class":1312},[1145,9880,9881,9883,9885,9887,9889,9891,9893],{"class":1147,"line":6826},[1145,9882,6871],{"class":1886},[1145,9884,1317],{"class":1316},[1145,9886,9725],{"class":1162},[1145,9888,1966],{"class":1316},[1145,9890,8397],{"class":1814},[1145,9892,8258],{"class":1890},[1145,9894,1331],{"class":1312},[1145,9896,9897,9900,9903,9905,9907,9909,9911,9913],{"class":1147,"line":6831},[1145,9898,9899],{"class":1890},"            total_tax ",[1145,9901,9902],{"class":1312},"+=",[1145,9904,8258],{"class":1890},[1145,9906,8618],{"class":1312},[1145,9908,1966],{"class":1316},[1145,9910,9725],{"class":1162},[1145,9912,1966],{"class":1316},[1145,9914,8627],{"class":1312},[1145,9916,9917,9920,9922,9924,9926,9928,9930],{"class":1147,"line":6842},[1145,9918,9919],{"class":1886},"        elif",[1145,9921,1317],{"class":1316},[1145,9923,9428],{"class":1162},[1145,9925,1966],{"class":1316},[1145,9927,8397],{"class":1814},[1145,9929,8258],{"class":1890},[1145,9931,1331],{"class":1312},[1145,9933,9934,9936,9938,9941,9943,9945,9947,9949,9951,9953],{"class":1147,"line":6847},[1145,9935,9324],{"class":1890},[1145,9937,2554],{"class":1312},[1145,9939,9940],{"class":2214},"extend",[1145,9942,2218],{"class":1312},[1145,9944,3024],{"class":2214},[1145,9946,8618],{"class":1312},[1145,9948,1966],{"class":1316},[1145,9950,9428],{"class":1162},[1145,9952,1966],{"class":1316},[1145,9954,9955],{"class":1312},"])\n",[1145,9957,9958],{"class":1147,"line":6863},[1145,9959,3300],{"class":1890},[1145,9961,9962],{"class":1147,"line":6868},[1145,9963,9964],{"class":1151},"    # Update order with calculated values\n",[1145,9966,9967,9969,9971,9973,9975],{"class":1147,"line":6892},[1145,9968,7438],{"class":1890},[1145,9970,2554],{"class":1312},[1145,9972,9725],{"class":2586},[1145,9974,1921],{"class":1312},[1145,9976,9977],{"class":1890}," total_tax\n",[1145,9979,9980,9982,9984,9986,9988,9990,9992,9994,9996,9998,10000,10002,10004],{"class":1147,"line":6898},[1145,9981,7438],{"class":1890},[1145,9983,2554],{"class":1312},[1145,9985,6340],{"class":2586},[1145,9987,1921],{"class":1312},[1145,9989,5508],{"class":1890},[1145,9991,2554],{"class":1312},[1145,9993,6349],{"class":2586},[1145,9995,6352],{"class":1814},[1145,9997,5508],{"class":1890},[1145,9999,2554],{"class":1312},[1145,10001,6311],{"class":2586},[1145,10003,6352],{"class":1814},[1145,10005,9977],{"class":1890},[1145,10007,10008,10010,10012,10014,10016,10018,10021],{"class":1147,"line":6916},[1145,10009,7438],{"class":1890},[1145,10011,2554],{"class":1312},[1145,10013,4948],{"class":2586},[1145,10015,1921],{"class":1312},[1145,10017,1317],{"class":1316},[1145,10019,10020],{"class":1162},"ready_to_ship",[1145,10022,1323],{"class":1316},[1145,10024,10025,10027,10029,10031],{"class":1147,"line":6944},[1145,10026,7438],{"class":1890},[1145,10028,2554],{"class":1312},[1145,10030,3993],{"class":2214},[1145,10032,2722],{"class":1312},[1145,10034,10035],{"class":1147,"line":6964},[1145,10036,3300],{"class":1890},[1145,10038,10039],{"class":1147,"line":6975},[1145,10040,10041],{"class":1151},"    # Store reservation information\n",[1145,10043,10044,10046,10049,10051,10053],{"class":1147,"line":6980},[1145,10045,4427],{"class":1886},[1145,10047,10048],{"class":1890}," reservation ",[1145,10050,3927],{"class":1886},[1145,10052,9435],{"class":1890},[1145,10054,1331],{"class":1312},[1145,10056,10057,10060,10062,10064,10066,10068],{"class":1147,"line":7029},[1145,10058,10059],{"class":1890},"        OrderReservation",[1145,10061,2554],{"class":1312},[1145,10063,3395],{"class":2586},[1145,10065,2554],{"class":1312},[1145,10067,8681],{"class":2214},[1145,10069,3429],{"class":1312},[1145,10071,10072,10074,10076,10078],{"class":1147,"line":7037},[1145,10073,5282],{"class":2243},[1145,10075,2247],{"class":1312},[1145,10077,2319],{"class":2214},[1145,10079,3446],{"class":1312},[1145,10081,10082,10085,10087,10090,10092,10094,10096,10098],{"class":1147,"line":7045},[1145,10083,10084],{"class":2243},"            product_id",[1145,10086,2247],{"class":1312},[1145,10088,10089],{"class":2214},"reservation",[1145,10091,8618],{"class":1312},[1145,10093,1966],{"class":1316},[1145,10095,5571],{"class":1162},[1145,10097,1966],{"class":1316},[1145,10099,3508],{"class":1312},[1145,10101,10102,10105,10107,10109,10111,10113,10115,10117],{"class":1147,"line":7051},[1145,10103,10104],{"class":2243},"            reservation_id",[1145,10106,2247],{"class":1312},[1145,10108,10089],{"class":2214},[1145,10110,8618],{"class":1312},[1145,10112,1966],{"class":1316},[1145,10114,9315],{"class":1162},[1145,10116,1966],{"class":1316},[1145,10118,8627],{"class":1312},[1145,10120,10121],{"class":1147,"line":7084},[1145,10122,3529],{"class":1312},[1145,10124,10125],{"class":1147,"line":7118},[1145,10126,3300],{"class":1890},[1145,10128,10129,10131,10133,10135,10137,10139,10141,10143,10145,10147,10150],{"class":1147,"line":7142},[1145,10130,5466],{"class":1890},[1145,10132,2554],{"class":1312},[1145,10134,3551],{"class":2214},[1145,10136,2218],{"class":1312},[1145,10138,2798],{"class":2761},[1145,10140,5122],{"class":1162},[1145,10142,2805],{"class":2804},[1145,10144,4927],{"class":2214},[1145,10146,2818],{"class":2804},[1145,10148,10149],{"class":1162}," preparation finalized\"",[1145,10151,2382],{"class":1312},[1145,10153,10154,10156,10158,10160,10162,10164,10166],{"class":1147,"line":7147},[1145,10155,2827],{"class":1886},[1145,10157,2830],{"class":2761},[1145,10159,5122],{"class":1162},[1145,10161,2805],{"class":2804},[1145,10163,4927],{"class":1890},[1145,10165,2818],{"class":2804},[1145,10167,10168],{"class":1162}," ready for fulfillment\"\n",[1026,10170,10171],{},[1050,10172,10173],{},"Key benefits of these patterns:",[1754,10175,10176,10182,10188,10194],{},[1047,10177,10178,10181],{},[1050,10179,10180],{},"Parallel Execution",": Tasks that don't depend on each other can run simultaneously, reducing total processing time.",[1047,10183,10184,10187],{},[1050,10185,10186],{},"Result Aggregation",": Chord pattern allows you to collect results from multiple parallel tasks and process them together.",[1047,10189,10190,10193],{},[1050,10191,10192],{},"Fault Isolation",": If one task in a group fails, others can still complete successfully.",[1047,10195,10196,10198],{},[1050,10197,3092],{},": Parallel tasks can run on different workers, distributing load across your infrastructure.",[1246,10200,10202],{"id":10201},"event-driven-communication","Event-Driven Communication",[1026,10204,10205],{},"Event-driven architecture is a powerful pattern for microservices where services communicate by publishing and consuming events. Instead of direct service-to-service calls, services publish events when something interesting happens, and other services can subscribe to these events.",[1026,10207,10208],{},[1050,10209,10210],{},"Benefits of event-driven communication:",[1044,10212,10213,10219,10224,10230],{},[1047,10214,10215,10218],{},[1050,10216,10217],{},"Loose coupling",": Services don't need to know about each other directly",[1047,10220,10221,10223],{},[1050,10222,3092],{},": Events can be processed asynchronously",[1047,10225,10226,10229],{},[1050,10227,10228],{},"Resilience",": If a service is down, events can be processed later",[1047,10231,10232,10235],{},[1050,10233,10234],{},"Extensibility",": New services can easily subscribe to existing events",[1135,10237,10239],{"className":1872,"code":10238,"language":1874,"meta":1140,"style":1140},"# Event publishing and handling\n@shared_task\ndef publish_user_event(event_type, user_id, data=None):\n    \"\"\"\n    Publish user-related events to interested services\n    \n    This is the publisher side of event-driven communication.\n    When something happens to a user (created, updated, deleted),\n    this task publishes an event that other services can react to.\n    \n    Args:\n        event_type: Type of event (e.g., 'user.created', 'user.updated')\n        user_id: ID of the user the event relates to\n        data: Additional event data\n    \"\"\"\n    \n    # Create a standardized event payload\n    event_payload = {\n        'event_type': event_type,\n        'user_id': user_id,\n        'data': data or {},\n        'timestamp': timezone.now().isoformat(),\n        'service': 'user_service',\n        'event_id': str(uuid.uuid4()),  # Unique identifier for this event\n        'version': '1.0'  # Event schema version for compatibility\n    }\n    \n    # Define which services are interested in which events\n    # This routing map determines where each event type gets sent\n    routing_map = {\n        'user.created': ['notification_queue', 'analytics_queue', 'recommendation_queue'],\n        'user.updated': ['order_queue', 'recommendation_queue', 'cache_invalidation_queue'],\n        'user.deleted': ['cleanup_queue', 'analytics_queue', 'gdpr_compliance_queue'],\n        'user.login': ['analytics_queue', 'security_queue'],\n        'user.password_changed': ['security_queue', 'notification_queue'],\n    }\n    \n    # Get the queues that should receive this event type\n    target_queues = routing_map.get(event_type, [])\n    \n    if not target_queues:\n        logger.warning(f\"No routing defined for event type: {event_type}\")\n        return\n    \n    # Send the event to all interested queues\n    for queue in target_queues:\n        try:\n            handle_user_event.apply_async(\n                args=[event_payload],\n                queue=queue,\n                retry=True,\n                retry_policy={\n                    'max_retries': 3,\n                    'interval_start': 0,\n                    'interval_step': 0.2,\n                    'interval_max': 0.2,\n                }\n            )\n            logger.info(f\"Event {event_type} sent to queue {queue}\")\n            \n        except Exception as exc:\n            logger.error(f\"Failed to send event {event_type} to queue {queue}: {exc}\")\n\n@shared_task\ndef handle_user_event(event_payload):\n    \"\"\"\n    Handle incoming user events\n    \n    This is the consumer side of event-driven communication.\n    Different services can implement this task to react to user events\n    in their own specific way.\n    \n    Args:\n        event_payload: The event data published by another service\n    \"\"\"\n    event_type = event_payload['event_type']\n    user_id = event_payload['user_id']\n    event_data = event_payload.get('data', {})\n    \n    logger.info(f\"Handling event {event_type} for user {user_id}\")\n    \n    # Define handlers for different event types\n    # Each handler implements the business logic for reacting to that event\n    handlers = {\n        'user.created': handle_user_created,\n        'user.updated': handle_user_updated,\n        'user.deleted': handle_user_deleted,\n        'user.login': handle_user_login,\n        'user.password_changed': handle_password_changed,\n    }\n    \n    # Get the appropriate handler for this event type\n    handler = handlers.get(event_type)\n    if handler:\n        try:\n            result = handler(event_payload)\n            logger.info(f\"Successfully handled event {event_type} for user {user_id}\")\n            return result\n        except Exception as exc:\n            logger.error(f\"Error handling event {event_type} for user {user_id}: {exc}\")\n            raise\n    else:\n        logger.warning(f\"No handler for event type: {event_type}\")\n\ndef handle_user_created(event_payload):\n    \"\"\"\n    Handle user creation events\n    \n    This might be implemented differently in different services:\n    - Analytics service: Track new user registration\n    - Notification service: Send welcome email\n    - Recommendation service: Initialize user preferences\n    \"\"\"\n    user_id = event_payload['user_id']\n    user_data = event_payload.get('data', {})\n    \n    # Example: Analytics service implementation\n    if get_current_service() == 'analytics_service':\n        # Track user registration in analytics\n        track_user_registration.delay(user_id, user_data)\n        \n        # Update user statistics\n        update_registration_stats.delay()\n    \n    # Example: Notification service implementation\n    elif get_current_service() == 'notification_service':\n        # Send welcome email\n        send_welcome_email.delay(user_id)\n        \n        # Create notification preferences\n        create_notification_preferences.delay(user_id)\n    \n    return f\"User creation event handled for user {user_id}\"\n\ndef handle_user_updated(event_payload):\n    \"\"\"Handle user update events\"\"\"\n    user_id = event_payload['user_id']\n    updated_fields = event_payload.get('data', {}).get('updated_fields', [])\n    \n    # Different services react to different field updates\n    if 'email' in updated_fields:\n        # Email changed - update email verification status\n        verify_new_email.delay(user_id)\n    \n    if 'preferences' in updated_fields:\n        # Preferences changed - update recommendation engine\n        update_user_recommendations.delay(user_id)\n    \n    # Invalidate caches that might contain user data\n    invalidate_user_caches.delay(user_id)\n    \n    return f\"User update event handled for user {user_id}\"\n\ndef handle_user_deleted(event_payload):\n    \"\"\"Handle user deletion events\"\"\"\n    user_id = event_payload['user_id']\n    \n    # GDPR compliance - remove user data from all systems\n    cleanup_user_data.delay(user_id)\n    \n    # Update analytics\n    track_user_deletion.delay(user_id)\n    \n    # Cancel any pending tasks for this user\n    cancel_user_tasks.delay(user_id)\n    \n    return f\"User deletion event handled for user {user_id}\"\n\n# Example of how to publish events from your Django views or services\ndef create_user_with_events(user_data):\n    \"\"\"\n    Create a user and publish appropriate events\n    \n    This shows how to integrate event publishing into your business logic\n    \"\"\"\n    # Create the user\n    user = User.objects.create(**user_data)\n    \n    # Publish user creation event\n    publish_user_event.delay(\n        event_type='user.created',\n        user_id=user.id,\n        data={\n            'username': user.username,\n            'email': user.email,\n            'registration_source': 'web',\n            'user_agent': request.META.get('HTTP_USER_AGENT', ''),\n        }\n    )\n    \n    return user\n\n# Example of event-driven cache invalidation\n@shared_task\ndef invalidate_user_caches(user_id):\n    \"\"\"\n    Invalidate all caches related to a user\n    \n    This task can be triggered by user update events to ensure\n    cached data stays consistent across services\n    \"\"\"\n    cache_keys = [\n        f'user:{user_id}',\n        f'user_profile:{user_id}',\n        f'user_preferences:{user_id}',\n        f'user_orders:{user_id}',\n    ]\n    \n    for key in cache_keys:\n        cache.delete(key)\n        logger.debug(f\"Invalidated cache key: {key}\")\n    \n    # Also invalidate pattern-based caches\n    cache_patterns = [\n        f'user_list:*',\n        f'user_stats:*',\n    ]\n    \n    for pattern in cache_patterns:\n        invalidate_cache_pattern.delay(pattern)\n",[1142,10240,10241,10246,10252,10279,10283,10288,10292,10297,10302,10307,10311,10315,10320,10325,10330,10334,10338,10343,10352,10367,10381,10401,10423,10442,10471,10491,10495,10499,10504,10509,10518,10557,10595,10634,10664,10693,10697,10701,10706,10729,10733,10744,10770,10775,10779,10784,10797,10803,10814,10826,10837,10848,10855,10871,10886,10902,10917,10921,10925,10959,10963,10975,11017,11021,11027,11040,11044,11049,11053,11058,11063,11068,11072,11076,11081,11085,11105,11123,11149,11153,11187,11191,11196,11201,11210,11225,11240,11255,11270,11285,11289,11293,11298,11318,11327,11333,11348,11381,11388,11400,11441,11446,11453,11478,11482,11494,11498,11503,11507,11512,11517,11522,11527,11531,11549,11574,11578,11583,11603,11608,11628,11632,11637,11648,11652,11657,11677,11682,11696,11700,11705,11720,11724,11741,11745,11757,11766,11784,11825,11829,11834,11851,11856,11871,11875,11892,11897,11912,11916,11921,11936,11940,11957,11961,11973,11982,12000,12004,12009,12024,12028,12033,12048,12052,12057,12072,12076,12093,12097,12102,12116,12120,12125,12129,12134,12138,12143,12168,12172,12177,12188,12203,12218,12225,12244,12262,12282,12322,12326,12330,12334,12341,12345,12350,12356,12369,12373,12378,12382,12387,12392,12396,12405,12422,12439,12456,12473,12477,12481,12495,12512,12538,12542,12547,12556,12565,12574,12578,12582,12596],{"__ignoreMap":1140},[1145,10242,10243],{"class":1147,"line":1148},[1145,10244,10245],{"class":1151},"# Event publishing and handling\n",[1145,10247,10248,10250],{"class":1147,"line":1155},[1145,10249,2736],{"class":1312},[1145,10251,3802],{"class":2739},[1145,10253,10254,10256,10259,10261,10263,10265,10267,10269,10272,10274,10277],{"class":1147,"line":1173},[1145,10255,2762],{"class":2761},[1145,10257,10258],{"class":2739}," publish_user_event",[1145,10260,2218],{"class":1312},[1145,10262,4393],{"class":3282},[1145,10264,1900],{"class":1312},[1145,10266,3283],{"class":3282},[1145,10268,1900],{"class":1312},[1145,10270,10271],{"class":3282}," data",[1145,10273,2247],{"class":1814},[1145,10275,10276],{"class":2043},"None",[1145,10278,2774],{"class":1312},[1145,10280,10281],{"class":1147,"line":1186},[1145,10282,3290],{"class":2779},[1145,10284,10285],{"class":1147,"line":1199},[1145,10286,10287],{"class":2783},"    Publish user-related events to interested services\n",[1145,10289,10290],{"class":1147,"line":1351},[1145,10291,3300],{"class":2783},[1145,10293,10294],{"class":1147,"line":1362},[1145,10295,10296],{"class":2783},"    This is the publisher side of event-driven communication.\n",[1145,10298,10299],{"class":1147,"line":1370},[1145,10300,10301],{"class":2783},"    When something happens to a user (created, updated, deleted),\n",[1145,10303,10304],{"class":1147,"line":1388},[1145,10305,10306],{"class":2783},"    this task publishes an event that other services can react to.\n",[1145,10308,10309],{"class":1147,"line":1403},[1145,10310,3300],{"class":2783},[1145,10312,10313],{"class":1147,"line":1411},[1145,10314,3305],{"class":2783},[1145,10316,10317],{"class":1147,"line":1422},[1145,10318,10319],{"class":2783},"        event_type: Type of event (e.g., 'user.created', 'user.updated')\n",[1145,10321,10322],{"class":1147,"line":1433},[1145,10323,10324],{"class":2783},"        user_id: ID of the user the event relates to\n",[1145,10326,10327],{"class":1147,"line":1441},[1145,10328,10329],{"class":2783},"        data: Additional event data\n",[1145,10331,10332],{"class":1147,"line":1452},[1145,10333,3290],{"class":2779},[1145,10335,10336],{"class":1147,"line":1460},[1145,10337,3300],{"class":1890},[1145,10339,10340],{"class":1147,"line":1468},[1145,10341,10342],{"class":1151},"    # Create a standardized event payload\n",[1145,10344,10345,10348,10350],{"class":1147,"line":1475},[1145,10346,10347],{"class":1890},"    event_payload ",[1145,10349,2247],{"class":1312},[1145,10351,2068],{"class":1312},[1145,10353,10354,10356,10358,10360,10362,10365],{"class":1147,"line":1483},[1145,10355,4279],{"class":1316},[1145,10357,4393],{"class":1162},[1145,10359,1966],{"class":1316},[1145,10361,1313],{"class":1312},[1145,10363,10364],{"class":1890}," event_type",[1145,10366,3446],{"class":1312},[1145,10368,10369,10371,10373,10375,10377,10379],{"class":1147,"line":1493},[1145,10370,4279],{"class":1316},[1145,10372,3410],{"class":1162},[1145,10374,1966],{"class":1316},[1145,10376,1313],{"class":1312},[1145,10378,3283],{"class":1890},[1145,10380,3446],{"class":1312},[1145,10382,10383,10385,10388,10390,10392,10395,10398],{"class":1147,"line":1503},[1145,10384,4279],{"class":1316},[1145,10386,10387],{"class":1162},"data",[1145,10389,1966],{"class":1316},[1145,10391,1313],{"class":1312},[1145,10393,10394],{"class":1890}," data ",[1145,10396,10397],{"class":1814},"or",[1145,10399,10400],{"class":1312}," {},\n",[1145,10402,10403,10405,10407,10409,10411,10413,10415,10417,10419,10421],{"class":1147,"line":1510},[1145,10404,4279],{"class":1316},[1145,10406,4364],{"class":1162},[1145,10408,1966],{"class":1316},[1145,10410,1313],{"class":1312},[1145,10412,4371],{"class":1890},[1145,10414,2554],{"class":1312},[1145,10416,4376],{"class":2214},[1145,10418,4379],{"class":1312},[1145,10420,4382],{"class":2214},[1145,10422,4385],{"class":1312},[1145,10424,10425,10427,10430,10432,10434,10436,10438,10440],{"class":1147,"line":1523},[1145,10426,4279],{"class":1316},[1145,10428,10429],{"class":1162},"service",[1145,10431,1966],{"class":1316},[1145,10433,1313],{"class":1312},[1145,10435,1317],{"class":1316},[1145,10437,2643],{"class":1162},[1145,10439,1966],{"class":1316},[1145,10441,3446],{"class":1312},[1145,10443,10444,10446,10449,10451,10453,10455,10457,10460,10462,10465,10468],{"class":1147,"line":1530},[1145,10445,4279],{"class":1316},[1145,10447,10448],{"class":1162},"event_id",[1145,10450,1966],{"class":1316},[1145,10452,1313],{"class":1312},[1145,10454,5309],{"class":3664},[1145,10456,2218],{"class":1312},[1145,10458,10459],{"class":2214},"uuid",[1145,10461,2554],{"class":1312},[1145,10463,10464],{"class":2214},"uuid4",[1145,10466,10467],{"class":1312},"()),",[1145,10469,10470],{"class":1151},"  # Unique identifier for this event\n",[1145,10472,10473,10475,10477,10479,10481,10483,10486,10488],{"class":1147,"line":1537},[1145,10474,4279],{"class":1316},[1145,10476,1309],{"class":1162},[1145,10478,1966],{"class":1316},[1145,10480,1313],{"class":1312},[1145,10482,1317],{"class":1316},[1145,10484,10485],{"class":1162},"1.0",[1145,10487,1966],{"class":1316},[1145,10489,10490],{"class":1151},"  # Event schema version for compatibility\n",[1145,10492,10493],{"class":1147,"line":1542},[1145,10494,4410],{"class":1312},[1145,10496,10497],{"class":1147,"line":1550},[1145,10498,3300],{"class":1890},[1145,10500,10501],{"class":1147,"line":1561},[1145,10502,10503],{"class":1151},"    # Define which services are interested in which events\n",[1145,10505,10506],{"class":1147,"line":1566},[1145,10507,10508],{"class":1151},"    # This routing map determines where each event type gets sent\n",[1145,10510,10511,10514,10516],{"class":1147,"line":1574},[1145,10512,10513],{"class":1890},"    routing_map ",[1145,10515,2247],{"class":1312},[1145,10517,2068],{"class":1312},[1145,10519,10520,10522,10525,10527,10529,10531,10533,10535,10537,10539,10541,10544,10546,10548,10550,10553,10555],{"class":1147,"line":1582},[1145,10521,4279],{"class":1316},[1145,10523,10524],{"class":1162},"user.created",[1145,10526,1966],{"class":1316},[1145,10528,1313],{"class":1312},[1145,10530,1995],{"class":1312},[1145,10532,1966],{"class":1316},[1145,10534,2164],{"class":1162},[1145,10536,1966],{"class":1316},[1145,10538,1900],{"class":1312},[1145,10540,1317],{"class":1316},[1145,10542,10543],{"class":1162},"analytics_queue",[1145,10545,1966],{"class":1316},[1145,10547,1900],{"class":1312},[1145,10549,1317],{"class":1316},[1145,10551,10552],{"class":1162},"recommendation_queue",[1145,10554,1966],{"class":1316},[1145,10556,3508],{"class":1312},[1145,10558,10559,10561,10564,10566,10568,10570,10572,10574,10576,10578,10580,10582,10584,10586,10588,10591,10593],{"class":1147,"line":2379},[1145,10560,4279],{"class":1316},[1145,10562,10563],{"class":1162},"user.updated",[1145,10565,1966],{"class":1316},[1145,10567,1313],{"class":1312},[1145,10569,1995],{"class":1312},[1145,10571,1966],{"class":1316},[1145,10573,2131],{"class":1162},[1145,10575,1966],{"class":1316},[1145,10577,1900],{"class":1312},[1145,10579,1317],{"class":1316},[1145,10581,10552],{"class":1162},[1145,10583,1966],{"class":1316},[1145,10585,1900],{"class":1312},[1145,10587,1317],{"class":1316},[1145,10589,10590],{"class":1162},"cache_invalidation_queue",[1145,10592,1966],{"class":1316},[1145,10594,3508],{"class":1312},[1145,10596,10597,10599,10602,10604,10606,10608,10610,10613,10615,10617,10619,10621,10623,10625,10627,10630,10632],{"class":1147,"line":2385},[1145,10598,4279],{"class":1316},[1145,10600,10601],{"class":1162},"user.deleted",[1145,10603,1966],{"class":1316},[1145,10605,1313],{"class":1312},[1145,10607,1995],{"class":1312},[1145,10609,1966],{"class":1316},[1145,10611,10612],{"class":1162},"cleanup_queue",[1145,10614,1966],{"class":1316},[1145,10616,1900],{"class":1312},[1145,10618,1317],{"class":1316},[1145,10620,10543],{"class":1162},[1145,10622,1966],{"class":1316},[1145,10624,1900],{"class":1312},[1145,10626,1317],{"class":1316},[1145,10628,10629],{"class":1162},"gdpr_compliance_queue",[1145,10631,1966],{"class":1316},[1145,10633,3508],{"class":1312},[1145,10635,10636,10638,10641,10643,10645,10647,10649,10651,10653,10655,10657,10660,10662],{"class":1147,"line":2390},[1145,10637,4279],{"class":1316},[1145,10639,10640],{"class":1162},"user.login",[1145,10642,1966],{"class":1316},[1145,10644,1313],{"class":1312},[1145,10646,1995],{"class":1312},[1145,10648,1966],{"class":1316},[1145,10650,10543],{"class":1162},[1145,10652,1966],{"class":1316},[1145,10654,1900],{"class":1312},[1145,10656,1317],{"class":1316},[1145,10658,10659],{"class":1162},"security_queue",[1145,10661,1966],{"class":1316},[1145,10663,3508],{"class":1312},[1145,10665,10666,10668,10671,10673,10675,10677,10679,10681,10683,10685,10687,10689,10691],{"class":1147,"line":2396},[1145,10667,4279],{"class":1316},[1145,10669,10670],{"class":1162},"user.password_changed",[1145,10672,1966],{"class":1316},[1145,10674,1313],{"class":1312},[1145,10676,1995],{"class":1312},[1145,10678,1966],{"class":1316},[1145,10680,10659],{"class":1162},[1145,10682,1966],{"class":1316},[1145,10684,1900],{"class":1312},[1145,10686,1317],{"class":1316},[1145,10688,2164],{"class":1162},[1145,10690,1966],{"class":1316},[1145,10692,3508],{"class":1312},[1145,10694,10695],{"class":1147,"line":2410},[1145,10696,4410],{"class":1312},[1145,10698,10699],{"class":1147,"line":2424},[1145,10700,3300],{"class":1890},[1145,10702,10703],{"class":1147,"line":2438},[1145,10704,10705],{"class":1151},"    # Get the queues that should receive this event type\n",[1145,10707,10708,10711,10713,10716,10718,10720,10722,10724,10726],{"class":1147,"line":2443},[1145,10709,10710],{"class":1890},"    target_queues ",[1145,10712,2247],{"class":1312},[1145,10714,10715],{"class":1890}," routing_map",[1145,10717,2554],{"class":1312},[1145,10719,3400],{"class":2214},[1145,10721,2218],{"class":1312},[1145,10723,4393],{"class":2214},[1145,10725,1900],{"class":1312},[1145,10727,10728],{"class":1312}," [])\n",[1145,10730,10731],{"class":1147,"line":2449},[1145,10732,3300],{"class":1890},[1145,10734,10735,10737,10739,10742],{"class":1147,"line":2463},[1145,10736,8471],{"class":1886},[1145,10738,5657],{"class":1814},[1145,10740,10741],{"class":1890}," target_queues",[1145,10743,1331],{"class":1312},[1145,10745,10746,10748,10750,10753,10755,10757,10760,10762,10764,10766,10768],{"class":1147,"line":3526},[1145,10747,3546],{"class":1890},[1145,10749,2554],{"class":1312},[1145,10751,10752],{"class":2214},"warning",[1145,10754,2218],{"class":1312},[1145,10756,2798],{"class":2761},[1145,10758,10759],{"class":1162},"\"No routing defined for event type: ",[1145,10761,2805],{"class":2804},[1145,10763,4393],{"class":2214},[1145,10765,2818],{"class":2804},[1145,10767,1382],{"class":1162},[1145,10769,2382],{"class":1312},[1145,10771,10772],{"class":1147,"line":3532},[1145,10773,10774],{"class":1886},"        return\n",[1145,10776,10777],{"class":1147,"line":3537},[1145,10778,3300],{"class":1890},[1145,10780,10781],{"class":1147,"line":3543},[1145,10782,10783],{"class":1151},"    # Send the event to all interested queues\n",[1145,10785,10786,10788,10791,10793,10795],{"class":1147,"line":3571},[1145,10787,4427],{"class":1886},[1145,10789,10790],{"class":1890}," queue ",[1145,10792,3927],{"class":1886},[1145,10794,10741],{"class":1890},[1145,10796,1331],{"class":1312},[1145,10798,10799,10801],{"class":1147,"line":3594},[1145,10800,4443],{"class":1886},[1145,10802,1331],{"class":1312},[1145,10804,10805,10808,10810,10812],{"class":1147,"line":3599},[1145,10806,10807],{"class":1890},"            handle_user_event",[1145,10809,2554],{"class":1312},[1145,10811,5101],{"class":2214},[1145,10813,3429],{"class":1312},[1145,10815,10816,10819,10821,10824],{"class":1147,"line":3614},[1145,10817,10818],{"class":2243},"                args",[1145,10820,3498],{"class":1312},[1145,10822,10823],{"class":2214},"event_payload",[1145,10825,3508],{"class":1312},[1145,10827,10828,10831,10833,10835],{"class":1147,"line":3620},[1145,10829,10830],{"class":2243},"                queue",[1145,10832,2247],{"class":1312},[1145,10834,2088],{"class":2214},[1145,10836,3446],{"class":1312},[1145,10838,10839,10842,10844,10846],{"class":1147,"line":3648},[1145,10840,10841],{"class":2243},"                retry",[1145,10843,2247],{"class":1312},[1145,10845,2754],{"class":2043},[1145,10847,3446],{"class":1312},[1145,10849,10850,10853],{"class":1147,"line":3654},[1145,10851,10852],{"class":2243},"                retry_policy",[1145,10854,5563],{"class":1312},[1145,10856,10857,10859,10862,10864,10866,10869],{"class":1147,"line":3659},[1145,10858,5568],{"class":1316},[1145,10860,10861],{"class":1162},"max_retries",[1145,10863,1966],{"class":1316},[1145,10865,1313],{"class":1312},[1145,10867,10868],{"class":1169}," 3",[1145,10870,3446],{"class":1312},[1145,10872,10873,10875,10878,10880,10882,10884],{"class":1147,"line":3676},[1145,10874,5568],{"class":1316},[1145,10876,10877],{"class":1162},"interval_start",[1145,10879,1966],{"class":1316},[1145,10881,1313],{"class":1312},[1145,10883,6263],{"class":1169},[1145,10885,3446],{"class":1312},[1145,10887,10888,10890,10893,10895,10897,10900],{"class":1147,"line":3682},[1145,10889,5568],{"class":1316},[1145,10891,10892],{"class":1162},"interval_step",[1145,10894,1966],{"class":1316},[1145,10896,1313],{"class":1312},[1145,10898,10899],{"class":1169}," 0.2",[1145,10901,3446],{"class":1312},[1145,10903,10904,10906,10909,10911,10913,10915],{"class":1147,"line":3718},[1145,10905,5568],{"class":1316},[1145,10907,10908],{"class":1162},"interval_max",[1145,10910,1966],{"class":1316},[1145,10912,1313],{"class":1312},[1145,10914,10899],{"class":1169},[1145,10916,3446],{"class":1312},[1145,10918,10919],{"class":1147,"line":3723},[1145,10920,9648],{"class":1312},[1145,10922,10923],{"class":1147,"line":3729},[1145,10924,4533],{"class":1312},[1145,10926,10927,10929,10931,10933,10935,10937,10940,10942,10944,10946,10949,10951,10953,10955,10957],{"class":1147,"line":3735},[1145,10928,4562],{"class":1890},[1145,10930,2554],{"class":1312},[1145,10932,3551],{"class":2214},[1145,10934,2218],{"class":1312},[1145,10936,2798],{"class":2761},[1145,10938,10939],{"class":1162},"\"Event ",[1145,10941,2805],{"class":2804},[1145,10943,4393],{"class":2214},[1145,10945,2818],{"class":2804},[1145,10947,10948],{"class":1162}," sent to queue ",[1145,10950,2805],{"class":2804},[1145,10952,2088],{"class":2214},[1145,10954,2818],{"class":2804},[1145,10956,1382],{"class":1162},[1145,10958,2382],{"class":1312},[1145,10960,10961],{"class":1147,"line":3792},[1145,10962,4556],{"class":1890},[1145,10964,10965,10967,10969,10971,10973],{"class":1147,"line":3797},[1145,10966,4605],{"class":1886},[1145,10968,3665],{"class":3664},[1145,10970,3668],{"class":1886},[1145,10972,3671],{"class":1890},[1145,10974,1331],{"class":1312},[1145,10976,10977,10979,10981,10983,10985,10987,10990,10992,10994,10996,10999,11001,11003,11005,11007,11009,11011,11013,11015],{"class":1147,"line":3805},[1145,10978,4562],{"class":1890},[1145,10980,2554],{"class":1312},[1145,10982,3627],{"class":2214},[1145,10984,2218],{"class":1312},[1145,10986,2798],{"class":2761},[1145,10988,10989],{"class":1162},"\"Failed to send event ",[1145,10991,2805],{"class":2804},[1145,10993,4393],{"class":2214},[1145,10995,2818],{"class":2804},[1145,10997,10998],{"class":1162}," to queue ",[1145,11000,2805],{"class":2804},[1145,11002,2088],{"class":2214},[1145,11004,2818],{"class":2804},[1145,11006,3704],{"class":1162},[1145,11008,2805],{"class":2804},[1145,11010,3709],{"class":2214},[1145,11012,2818],{"class":2804},[1145,11014,1382],{"class":1162},[1145,11016,2382],{"class":1312},[1145,11018,11019],{"class":1147,"line":3824},[1145,11020,1472],{"emptyLinePlaceholder":1471},[1145,11022,11023,11025],{"class":1147,"line":3829},[1145,11024,2736],{"class":1312},[1145,11026,3802],{"class":2739},[1145,11028,11029,11031,11034,11036,11038],{"class":1147,"line":3835},[1145,11030,2762],{"class":2761},[1145,11032,11033],{"class":2739}," handle_user_event",[1145,11035,2218],{"class":1312},[1145,11037,10823],{"class":3282},[1145,11039,2774],{"class":1312},[1145,11041,11042],{"class":1147,"line":3840},[1145,11043,3290],{"class":2779},[1145,11045,11046],{"class":1147,"line":3845},[1145,11047,11048],{"class":2783},"    Handle incoming user events\n",[1145,11050,11051],{"class":1147,"line":3851},[1145,11052,3300],{"class":2783},[1145,11054,11055],{"class":1147,"line":3857},[1145,11056,11057],{"class":2783},"    This is the consumer side of event-driven communication.\n",[1145,11059,11060],{"class":1147,"line":3863},[1145,11061,11062],{"class":2783},"    Different services can implement this task to react to user events\n",[1145,11064,11065],{"class":1147,"line":3868},[1145,11066,11067],{"class":2783},"    in their own specific way.\n",[1145,11069,11070],{"class":1147,"line":3875},[1145,11071,3300],{"class":2783},[1145,11073,11074],{"class":1147,"line":3902},[1145,11075,3305],{"class":2783},[1145,11077,11078],{"class":1147,"line":3907},[1145,11079,11080],{"class":2783},"        event_payload: The event data published by another service\n",[1145,11082,11083],{"class":1147,"line":3913},[1145,11084,3290],{"class":2779},[1145,11086,11087,11090,11092,11095,11097,11099,11101,11103],{"class":1147,"line":3940},[1145,11088,11089],{"class":1890},"    event_type ",[1145,11091,2247],{"class":1312},[1145,11093,11094],{"class":1890}," event_payload",[1145,11096,8618],{"class":1312},[1145,11098,1966],{"class":1316},[1145,11100,4393],{"class":1162},[1145,11102,1966],{"class":1316},[1145,11104,8627],{"class":1312},[1145,11106,11107,11109,11111,11113,11115,11117,11119,11121],{"class":1147,"line":3959},[1145,11108,8610],{"class":1890},[1145,11110,2247],{"class":1312},[1145,11112,11094],{"class":1890},[1145,11114,8618],{"class":1312},[1145,11116,1966],{"class":1316},[1145,11118,3410],{"class":1162},[1145,11120,1966],{"class":1316},[1145,11122,8627],{"class":1312},[1145,11124,11125,11128,11130,11132,11134,11136,11138,11140,11142,11144,11146],{"class":1147,"line":3980},[1145,11126,11127],{"class":1890},"    event_data ",[1145,11129,2247],{"class":1312},[1145,11131,11094],{"class":1890},[1145,11133,2554],{"class":1312},[1145,11135,3400],{"class":2214},[1145,11137,2218],{"class":1312},[1145,11139,1966],{"class":1316},[1145,11141,10387],{"class":1162},[1145,11143,1966],{"class":1316},[1145,11145,1900],{"class":1312},[1145,11147,11148],{"class":1312}," {})\n",[1145,11150,11151],{"class":1147,"line":3985},[1145,11152,3300],{"class":1890},[1145,11154,11155,11157,11159,11161,11163,11165,11168,11170,11172,11174,11177,11179,11181,11183,11185],{"class":1147,"line":3998},[1145,11156,5466],{"class":1890},[1145,11158,2554],{"class":1312},[1145,11160,3551],{"class":2214},[1145,11162,2218],{"class":1312},[1145,11164,2798],{"class":2761},[1145,11166,11167],{"class":1162},"\"Handling event ",[1145,11169,2805],{"class":2804},[1145,11171,4393],{"class":2214},[1145,11173,2818],{"class":2804},[1145,11175,11176],{"class":1162}," for user ",[1145,11178,2805],{"class":2804},[1145,11180,3410],{"class":2214},[1145,11182,2818],{"class":2804},[1145,11184,1382],{"class":1162},[1145,11186,2382],{"class":1312},[1145,11188,11189],{"class":1147,"line":4003},[1145,11190,3300],{"class":1890},[1145,11192,11193],{"class":1147,"line":4009},[1145,11194,11195],{"class":1151},"    # Define handlers for different event types\n",[1145,11197,11198],{"class":1147,"line":4015},[1145,11199,11200],{"class":1151},"    # Each handler implements the business logic for reacting to that event\n",[1145,11202,11203,11206,11208],{"class":1147,"line":4036},[1145,11204,11205],{"class":1890},"    handlers ",[1145,11207,2247],{"class":1312},[1145,11209,2068],{"class":1312},[1145,11211,11212,11214,11216,11218,11220,11223],{"class":1147,"line":4041},[1145,11213,4279],{"class":1316},[1145,11215,10524],{"class":1162},[1145,11217,1966],{"class":1316},[1145,11219,1313],{"class":1312},[1145,11221,11222],{"class":1890}," handle_user_created",[1145,11224,3446],{"class":1312},[1145,11226,11227,11229,11231,11233,11235,11238],{"class":1147,"line":4067},[1145,11228,4279],{"class":1316},[1145,11230,10563],{"class":1162},[1145,11232,1966],{"class":1316},[1145,11234,1313],{"class":1312},[1145,11236,11237],{"class":1890}," handle_user_updated",[1145,11239,3446],{"class":1312},[1145,11241,11242,11244,11246,11248,11250,11253],{"class":1147,"line":4084},[1145,11243,4279],{"class":1316},[1145,11245,10601],{"class":1162},[1145,11247,1966],{"class":1316},[1145,11249,1313],{"class":1312},[1145,11251,11252],{"class":1890}," handle_user_deleted",[1145,11254,3446],{"class":1312},[1145,11256,11257,11259,11261,11263,11265,11268],{"class":1147,"line":4089},[1145,11258,4279],{"class":1316},[1145,11260,10640],{"class":1162},[1145,11262,1966],{"class":1316},[1145,11264,1313],{"class":1312},[1145,11266,11267],{"class":1890}," handle_user_login",[1145,11269,3446],{"class":1312},[1145,11271,11272,11274,11276,11278,11280,11283],{"class":1147,"line":4102},[1145,11273,4279],{"class":1316},[1145,11275,10670],{"class":1162},[1145,11277,1966],{"class":1316},[1145,11279,1313],{"class":1312},[1145,11281,11282],{"class":1890}," handle_password_changed",[1145,11284,3446],{"class":1312},[1145,11286,11287],{"class":1147,"line":4128},[1145,11288,4410],{"class":1312},[1145,11290,11291],{"class":1147,"line":4133},[1145,11292,3300],{"class":1890},[1145,11294,11295],{"class":1147,"line":4146},[1145,11296,11297],{"class":1151},"    # Get the appropriate handler for this event type\n",[1145,11299,11300,11303,11305,11308,11310,11312,11314,11316],{"class":1147,"line":4180},[1145,11301,11302],{"class":1890},"    handler ",[1145,11304,2247],{"class":1312},[1145,11306,11307],{"class":1890}," handlers",[1145,11309,2554],{"class":1312},[1145,11311,3400],{"class":2214},[1145,11313,2218],{"class":1312},[1145,11315,4393],{"class":2214},[1145,11317,2382],{"class":1312},[1145,11319,11320,11322,11325],{"class":1147,"line":4185},[1145,11321,8471],{"class":1886},[1145,11323,11324],{"class":1890}," handler",[1145,11326,1331],{"class":1312},[1145,11328,11329,11331],{"class":1147,"line":4190},[1145,11330,4443],{"class":1886},[1145,11332,1331],{"class":1312},[1145,11334,11335,11338,11340,11342,11344,11346],{"class":1147,"line":4197},[1145,11336,11337],{"class":1890},"            result ",[1145,11339,2247],{"class":1312},[1145,11341,11324],{"class":2214},[1145,11343,2218],{"class":1312},[1145,11345,10823],{"class":2214},[1145,11347,2382],{"class":1312},[1145,11349,11350,11352,11354,11356,11358,11360,11363,11365,11367,11369,11371,11373,11375,11377,11379],{"class":1147,"line":4215},[1145,11351,4562],{"class":1890},[1145,11353,2554],{"class":1312},[1145,11355,3551],{"class":2214},[1145,11357,2218],{"class":1312},[1145,11359,2798],{"class":2761},[1145,11361,11362],{"class":1162},"\"Successfully handled event ",[1145,11364,2805],{"class":2804},[1145,11366,4393],{"class":2214},[1145,11368,2818],{"class":2804},[1145,11370,11176],{"class":1162},[1145,11372,2805],{"class":2804},[1145,11374,3410],{"class":2214},[1145,11376,2818],{"class":2804},[1145,11378,1382],{"class":1162},[1145,11380,2382],{"class":1312},[1145,11382,11383,11385],{"class":1147,"line":4220},[1145,11384,7032],{"class":1886},[1145,11386,11387],{"class":1890}," result\n",[1145,11389,11390,11392,11394,11396,11398],{"class":1147,"line":4226},[1145,11391,4605],{"class":1886},[1145,11393,3665],{"class":3664},[1145,11395,3668],{"class":1886},[1145,11397,3671],{"class":1890},[1145,11399,1331],{"class":1312},[1145,11401,11402,11404,11406,11408,11410,11412,11415,11417,11419,11421,11423,11425,11427,11429,11431,11433,11435,11437,11439],{"class":1147,"line":4231},[1145,11403,4562],{"class":1890},[1145,11405,2554],{"class":1312},[1145,11407,3627],{"class":2214},[1145,11409,2218],{"class":1312},[1145,11411,2798],{"class":2761},[1145,11413,11414],{"class":1162},"\"Error handling event ",[1145,11416,2805],{"class":2804},[1145,11418,4393],{"class":2214},[1145,11420,2818],{"class":2804},[1145,11422,11176],{"class":1162},[1145,11424,2805],{"class":2804},[1145,11426,3410],{"class":2214},[1145,11428,2818],{"class":2804},[1145,11430,3704],{"class":1162},[1145,11432,2805],{"class":2804},[1145,11434,3709],{"class":2214},[1145,11436,2818],{"class":2804},[1145,11438,1382],{"class":1162},[1145,11440,2382],{"class":1312},[1145,11442,11443],{"class":1147,"line":4236},[1145,11444,11445],{"class":1886},"            raise\n",[1145,11447,11448,11451],{"class":1147,"line":4242},[1145,11449,11450],{"class":1886},"    else",[1145,11452,1331],{"class":1312},[1145,11454,11455,11457,11459,11461,11463,11465,11468,11470,11472,11474,11476],{"class":1147,"line":4248},[1145,11456,3546],{"class":1890},[1145,11458,2554],{"class":1312},[1145,11460,10752],{"class":2214},[1145,11462,2218],{"class":1312},[1145,11464,2798],{"class":2761},[1145,11466,11467],{"class":1162},"\"No handler for event type: ",[1145,11469,2805],{"class":2804},[1145,11471,4393],{"class":2214},[1145,11473,2818],{"class":2804},[1145,11475,1382],{"class":1162},[1145,11477,2382],{"class":1312},[1145,11479,11480],{"class":1147,"line":4254},[1145,11481,1472],{"emptyLinePlaceholder":1471},[1145,11483,11484,11486,11488,11490,11492],{"class":1147,"line":4259},[1145,11485,2762],{"class":2761},[1145,11487,11222],{"class":2739},[1145,11489,2218],{"class":1312},[1145,11491,10823],{"class":3282},[1145,11493,2774],{"class":1312},[1145,11495,11496],{"class":1147,"line":4265},[1145,11497,3290],{"class":2779},[1145,11499,11500],{"class":1147,"line":4276},[1145,11501,11502],{"class":2783},"    Handle user creation events\n",[1145,11504,11505],{"class":1147,"line":4289},[1145,11506,3300],{"class":2783},[1145,11508,11509],{"class":1147,"line":4301},[1145,11510,11511],{"class":2783},"    This might be implemented differently in different services:\n",[1145,11513,11514],{"class":1147,"line":4307},[1145,11515,11516],{"class":2783},"    - Analytics service: Track new user registration\n",[1145,11518,11519],{"class":1147,"line":4312},[1145,11520,11521],{"class":2783},"    - Notification service: Send welcome email\n",[1145,11523,11524],{"class":1147,"line":4318},[1145,11525,11526],{"class":2783},"    - Recommendation service: Initialize user preferences\n",[1145,11528,11529],{"class":1147,"line":4328},[1145,11530,3290],{"class":2779},[1145,11532,11533,11535,11537,11539,11541,11543,11545,11547],{"class":1147,"line":4343},[1145,11534,8610],{"class":1890},[1145,11536,2247],{"class":1312},[1145,11538,11094],{"class":1890},[1145,11540,8618],{"class":1312},[1145,11542,1966],{"class":1316},[1145,11544,3410],{"class":1162},[1145,11546,1966],{"class":1316},[1145,11548,8627],{"class":1312},[1145,11550,11551,11554,11556,11558,11560,11562,11564,11566,11568,11570,11572],{"class":1147,"line":4359},[1145,11552,11553],{"class":1890},"    user_data ",[1145,11555,2247],{"class":1312},[1145,11557,11094],{"class":1890},[1145,11559,2554],{"class":1312},[1145,11561,3400],{"class":2214},[1145,11563,2218],{"class":1312},[1145,11565,1966],{"class":1316},[1145,11567,10387],{"class":1162},[1145,11569,1966],{"class":1316},[1145,11571,1900],{"class":1312},[1145,11573,11148],{"class":1312},[1145,11575,11576],{"class":1147,"line":4388},[1145,11577,3300],{"class":1890},[1145,11579,11580],{"class":1147,"line":4407},[1145,11581,11582],{"class":1151},"    # Example: Analytics service implementation\n",[1145,11584,11585,11587,11590,11592,11594,11596,11599,11601],{"class":1147,"line":4413},[1145,11586,8471],{"class":1886},[1145,11588,11589],{"class":2214}," get_current_service",[1145,11591,4547],{"class":1312},[1145,11593,9286],{"class":1814},[1145,11595,1317],{"class":1316},[1145,11597,11598],{"class":1162},"analytics_service",[1145,11600,1966],{"class":1316},[1145,11602,1331],{"class":1312},[1145,11604,11605],{"class":1147,"line":4418},[1145,11606,11607],{"class":1151},"        # Track user registration in analytics\n",[1145,11609,11610,11613,11615,11617,11619,11621,11623,11626],{"class":1147,"line":4424},[1145,11611,11612],{"class":1890},"        track_user_registration",[1145,11614,2554],{"class":1312},[1145,11616,4023],{"class":2214},[1145,11618,2218],{"class":1312},[1145,11620,3410],{"class":2214},[1145,11622,1900],{"class":1312},[1145,11624,11625],{"class":2214}," user_data",[1145,11627,2382],{"class":1312},[1145,11629,11630],{"class":1147,"line":4440},[1145,11631,3315],{"class":1890},[1145,11633,11634],{"class":1147,"line":4448},[1145,11635,11636],{"class":1151},"        # Update user statistics\n",[1145,11638,11639,11642,11644,11646],{"class":1147,"line":4466},[1145,11640,11641],{"class":1890},"        update_registration_stats",[1145,11643,2554],{"class":1312},[1145,11645,4023],{"class":2214},[1145,11647,2722],{"class":1312},[1145,11649,11650],{"class":1147,"line":4474},[1145,11651,3300],{"class":1890},[1145,11653,11654],{"class":1147,"line":4487},[1145,11655,11656],{"class":1151},"    # Example: Notification service implementation\n",[1145,11658,11659,11662,11664,11666,11668,11670,11673,11675],{"class":1147,"line":4503},[1145,11660,11661],{"class":1886},"    elif",[1145,11663,11589],{"class":2214},[1145,11665,4547],{"class":1312},[1145,11667,9286],{"class":1814},[1145,11669,1317],{"class":1316},[1145,11671,11672],{"class":1162},"notification_service",[1145,11674,1966],{"class":1316},[1145,11676,1331],{"class":1312},[1145,11678,11679],{"class":1147,"line":4530},[1145,11680,11681],{"class":1151},"        # Send welcome email\n",[1145,11683,11684,11686,11688,11690,11692,11694],{"class":1147,"line":4536},[1145,11685,8072],{"class":1890},[1145,11687,2554],{"class":1312},[1145,11689,4023],{"class":2214},[1145,11691,2218],{"class":1312},[1145,11693,3410],{"class":2214},[1145,11695,2382],{"class":1312},[1145,11697,11698],{"class":1147,"line":4553},[1145,11699,3315],{"class":1890},[1145,11701,11702],{"class":1147,"line":4559},[1145,11703,11704],{"class":1151},"        # Create notification preferences\n",[1145,11706,11707,11710,11712,11714,11716,11718],{"class":1147,"line":4597},[1145,11708,11709],{"class":1890},"        create_notification_preferences",[1145,11711,2554],{"class":1312},[1145,11713,4023],{"class":2214},[1145,11715,2218],{"class":1312},[1145,11717,3410],{"class":2214},[1145,11719,2382],{"class":1312},[1145,11721,11722],{"class":1147,"line":4602},[1145,11723,3300],{"class":1890},[1145,11725,11726,11728,11730,11733,11735,11737,11739],{"class":1147,"line":4621},[1145,11727,2827],{"class":1886},[1145,11729,2830],{"class":2761},[1145,11731,11732],{"class":1162},"\"User creation event handled for user ",[1145,11734,2805],{"class":2804},[1145,11736,3410],{"class":1890},[1145,11738,2818],{"class":2804},[1145,11740,1520],{"class":1162},[1145,11742,11743],{"class":1147,"line":4627},[1145,11744,1472],{"emptyLinePlaceholder":1471},[1145,11746,11747,11749,11751,11753,11755],{"class":1147,"line":4633},[1145,11748,2762],{"class":2761},[1145,11750,11237],{"class":2739},[1145,11752,2218],{"class":1312},[1145,11754,10823],{"class":3282},[1145,11756,2774],{"class":1312},[1145,11758,11759,11761,11764],{"class":1147,"line":6204},[1145,11760,2780],{"class":2779},[1145,11762,11763],{"class":2783},"Handle user update events",[1145,11765,2787],{"class":2779},[1145,11767,11768,11770,11772,11774,11776,11778,11780,11782],{"class":1147,"line":6216},[1145,11769,8610],{"class":1890},[1145,11771,2247],{"class":1312},[1145,11773,11094],{"class":1890},[1145,11775,8618],{"class":1312},[1145,11777,1966],{"class":1316},[1145,11779,3410],{"class":1162},[1145,11781,1966],{"class":1316},[1145,11783,8627],{"class":1312},[1145,11785,11786,11789,11791,11793,11795,11797,11799,11801,11803,11805,11807,11810,11812,11814,11816,11819,11821,11823],{"class":1147,"line":6221},[1145,11787,11788],{"class":1890},"    updated_fields ",[1145,11790,2247],{"class":1312},[1145,11792,11094],{"class":1890},[1145,11794,2554],{"class":1312},[1145,11796,3400],{"class":2214},[1145,11798,2218],{"class":1312},[1145,11800,1966],{"class":1316},[1145,11802,10387],{"class":1162},[1145,11804,1966],{"class":1316},[1145,11806,1900],{"class":1312},[1145,11808,11809],{"class":1312}," {}).",[1145,11811,3400],{"class":2214},[1145,11813,2218],{"class":1312},[1145,11815,1966],{"class":1316},[1145,11817,11818],{"class":1162},"updated_fields",[1145,11820,1966],{"class":1316},[1145,11822,1900],{"class":1312},[1145,11824,10728],{"class":1312},[1145,11826,11827],{"class":1147,"line":6237},[1145,11828,3300],{"class":1890},[1145,11830,11831],{"class":1147,"line":6268},[1145,11832,11833],{"class":1151},"    # Different services react to different field updates\n",[1145,11835,11836,11838,11840,11842,11844,11846,11849],{"class":1147,"line":6293},[1145,11837,8471],{"class":1886},[1145,11839,1317],{"class":1316},[1145,11841,3505],{"class":1162},[1145,11843,1966],{"class":1316},[1145,11845,8397],{"class":1814},[1145,11847,11848],{"class":1890}," updated_fields",[1145,11850,1331],{"class":1312},[1145,11852,11853],{"class":1147,"line":6298},[1145,11854,11855],{"class":1151},"        # Email changed - update email verification status\n",[1145,11857,11858,11861,11863,11865,11867,11869],{"class":1147,"line":6304},[1145,11859,11860],{"class":1890},"        verify_new_email",[1145,11862,2554],{"class":1312},[1145,11864,4023],{"class":2214},[1145,11866,2218],{"class":1312},[1145,11868,3410],{"class":2214},[1145,11870,2382],{"class":1312},[1145,11872,11873],{"class":1147,"line":6319},[1145,11874,3300],{"class":1890},[1145,11876,11877,11879,11881,11884,11886,11888,11890],{"class":1147,"line":6333},[1145,11878,8471],{"class":1886},[1145,11880,1317],{"class":1316},[1145,11882,11883],{"class":1162},"preferences",[1145,11885,1966],{"class":1316},[1145,11887,8397],{"class":1814},[1145,11889,11848],{"class":1890},[1145,11891,1331],{"class":1312},[1145,11893,11894],{"class":1147,"line":6357},[1145,11895,11896],{"class":1151},"        # Preferences changed - update recommendation engine\n",[1145,11898,11899,11902,11904,11906,11908,11910],{"class":1147,"line":6368},[1145,11900,11901],{"class":1890},"        update_user_recommendations",[1145,11903,2554],{"class":1312},[1145,11905,4023],{"class":2214},[1145,11907,2218],{"class":1312},[1145,11909,3410],{"class":2214},[1145,11911,2382],{"class":1312},[1145,11913,11914],{"class":1147,"line":6373},[1145,11915,3300],{"class":1890},[1145,11917,11918],{"class":1147,"line":6408},[1145,11919,11920],{"class":1151},"    # Invalidate caches that might contain user data\n",[1145,11922,11923,11926,11928,11930,11932,11934],{"class":1147,"line":6416},[1145,11924,11925],{"class":1890},"    invalidate_user_caches",[1145,11927,2554],{"class":1312},[1145,11929,4023],{"class":2214},[1145,11931,2218],{"class":1312},[1145,11933,3410],{"class":2214},[1145,11935,2382],{"class":1312},[1145,11937,11938],{"class":1147,"line":6421},[1145,11939,3300],{"class":1890},[1145,11941,11942,11944,11946,11949,11951,11953,11955],{"class":1147,"line":6438},[1145,11943,2827],{"class":1886},[1145,11945,2830],{"class":2761},[1145,11947,11948],{"class":1162},"\"User update event handled for user ",[1145,11950,2805],{"class":2804},[1145,11952,3410],{"class":1890},[1145,11954,2818],{"class":2804},[1145,11956,1520],{"class":1162},[1145,11958,11959],{"class":1147,"line":6472},[1145,11960,1472],{"emptyLinePlaceholder":1471},[1145,11962,11963,11965,11967,11969,11971],{"class":1147,"line":6496},[1145,11964,2762],{"class":2761},[1145,11966,11252],{"class":2739},[1145,11968,2218],{"class":1312},[1145,11970,10823],{"class":3282},[1145,11972,2774],{"class":1312},[1145,11974,11975,11977,11980],{"class":1147,"line":6501},[1145,11976,2780],{"class":2779},[1145,11978,11979],{"class":2783},"Handle user deletion events",[1145,11981,2787],{"class":2779},[1145,11983,11984,11986,11988,11990,11992,11994,11996,11998],{"class":1147,"line":6508},[1145,11985,8610],{"class":1890},[1145,11987,2247],{"class":1312},[1145,11989,11094],{"class":1890},[1145,11991,8618],{"class":1312},[1145,11993,1966],{"class":1316},[1145,11995,3410],{"class":1162},[1145,11997,1966],{"class":1316},[1145,11999,8627],{"class":1312},[1145,12001,12002],{"class":1147,"line":6522},[1145,12003,3300],{"class":1890},[1145,12005,12006],{"class":1147,"line":6527},[1145,12007,12008],{"class":1151},"    # GDPR compliance - remove user data from all systems\n",[1145,12010,12011,12014,12016,12018,12020,12022],{"class":1147,"line":6533},[1145,12012,12013],{"class":1890},"    cleanup_user_data",[1145,12015,2554],{"class":1312},[1145,12017,4023],{"class":2214},[1145,12019,2218],{"class":1312},[1145,12021,3410],{"class":2214},[1145,12023,2382],{"class":1312},[1145,12025,12026],{"class":1147,"line":6538},[1145,12027,3300],{"class":1890},[1145,12029,12030],{"class":1147,"line":6543},[1145,12031,12032],{"class":1151},"    # Update analytics\n",[1145,12034,12035,12038,12040,12042,12044,12046],{"class":1147,"line":6549},[1145,12036,12037],{"class":1890},"    track_user_deletion",[1145,12039,2554],{"class":1312},[1145,12041,4023],{"class":2214},[1145,12043,2218],{"class":1312},[1145,12045,3410],{"class":2214},[1145,12047,2382],{"class":1312},[1145,12049,12050],{"class":1147,"line":6555},[1145,12051,3300],{"class":1890},[1145,12053,12054],{"class":1147,"line":6561},[1145,12055,12056],{"class":1151},"    # Cancel any pending tasks for this user\n",[1145,12058,12059,12062,12064,12066,12068,12070],{"class":1147,"line":6567},[1145,12060,12061],{"class":1890},"    cancel_user_tasks",[1145,12063,2554],{"class":1312},[1145,12065,4023],{"class":2214},[1145,12067,2218],{"class":1312},[1145,12069,3410],{"class":2214},[1145,12071,2382],{"class":1312},[1145,12073,12074],{"class":1147,"line":6572},[1145,12075,3300],{"class":1890},[1145,12077,12078,12080,12082,12085,12087,12089,12091],{"class":1147,"line":6599},[1145,12079,2827],{"class":1886},[1145,12081,2830],{"class":2761},[1145,12083,12084],{"class":1162},"\"User deletion event handled for user ",[1145,12086,2805],{"class":2804},[1145,12088,3410],{"class":1890},[1145,12090,2818],{"class":2804},[1145,12092,1520],{"class":1162},[1145,12094,12095],{"class":1147,"line":6604},[1145,12096,1472],{"emptyLinePlaceholder":1471},[1145,12098,12099],{"class":1147,"line":6630},[1145,12100,12101],{"class":1151},"# Example of how to publish events from your Django views or services\n",[1145,12103,12104,12106,12109,12111,12114],{"class":1147,"line":6635},[1145,12105,2762],{"class":2761},[1145,12107,12108],{"class":2739}," create_user_with_events",[1145,12110,2218],{"class":1312},[1145,12112,12113],{"class":3282},"user_data",[1145,12115,2774],{"class":1312},[1145,12117,12118],{"class":1147,"line":6642},[1145,12119,3290],{"class":2779},[1145,12121,12122],{"class":1147,"line":6648},[1145,12123,12124],{"class":2783},"    Create a user and publish appropriate events\n",[1145,12126,12127],{"class":1147,"line":6663},[1145,12128,3300],{"class":2783},[1145,12130,12131],{"class":1147,"line":6675},[1145,12132,12133],{"class":2783},"    This shows how to integrate event publishing into your business logic\n",[1145,12135,12136],{"class":1147,"line":6682},[1145,12137,3290],{"class":2779},[1145,12139,12140],{"class":1147,"line":6697},[1145,12141,12142],{"class":1151},"    # Create the user\n",[1145,12144,12145,12147,12149,12151,12153,12155,12157,12159,12161,12164,12166],{"class":1147,"line":6722},[1145,12146,8337],{"class":1890},[1145,12148,2247],{"class":1312},[1145,12150,3390],{"class":1890},[1145,12152,2554],{"class":1312},[1145,12154,3395],{"class":2586},[1145,12156,2554],{"class":1312},[1145,12158,8681],{"class":2214},[1145,12160,2218],{"class":1312},[1145,12162,12163],{"class":1814},"**",[1145,12165,12113],{"class":2214},[1145,12167,2382],{"class":1312},[1145,12169,12170],{"class":1147,"line":6743},[1145,12171,3300],{"class":1890},[1145,12173,12174],{"class":1147,"line":6763},[1145,12175,12176],{"class":1151},"    # Publish user creation event\n",[1145,12178,12179,12182,12184,12186],{"class":1147,"line":6783},[1145,12180,12181],{"class":1890},"    publish_user_event",[1145,12183,2554],{"class":1312},[1145,12185,4023],{"class":2214},[1145,12187,3429],{"class":1312},[1145,12189,12190,12193,12195,12197,12199,12201],{"class":1147,"line":6808},[1145,12191,12192],{"class":2243},"        event_type",[1145,12194,2247],{"class":1312},[1145,12196,1966],{"class":1316},[1145,12198,10524],{"class":1162},[1145,12200,1966],{"class":1316},[1145,12202,3446],{"class":1312},[1145,12204,12205,12208,12210,12212,12214,12216],{"class":1147,"line":6813},[1145,12206,12207],{"class":2243},"        user_id",[1145,12209,2247],{"class":1312},[1145,12211,2279],{"class":2214},[1145,12213,2554],{"class":1312},[1145,12215,3405],{"class":2586},[1145,12217,3446],{"class":1312},[1145,12219,12220,12223],{"class":1147,"line":6826},[1145,12221,12222],{"class":2243},"        data",[1145,12224,5563],{"class":1312},[1145,12226,12227,12229,12232,12234,12236,12238,12240,12242],{"class":1147,"line":6831},[1145,12228,6012],{"class":1316},[1145,12230,12231],{"class":1162},"username",[1145,12233,1966],{"class":1316},[1145,12235,1313],{"class":1312},[1145,12237,8400],{"class":2214},[1145,12239,2554],{"class":1312},[1145,12241,12231],{"class":2586},[1145,12243,3446],{"class":1312},[1145,12245,12246,12248,12250,12252,12254,12256,12258,12260],{"class":1147,"line":6842},[1145,12247,6012],{"class":1316},[1145,12249,3505],{"class":1162},[1145,12251,1966],{"class":1316},[1145,12253,1313],{"class":1312},[1145,12255,8400],{"class":2214},[1145,12257,2554],{"class":1312},[1145,12259,3505],{"class":2586},[1145,12261,3446],{"class":1312},[1145,12263,12264,12266,12269,12271,12273,12275,12278,12280],{"class":1147,"line":6847},[1145,12265,6012],{"class":1316},[1145,12267,12268],{"class":1162},"registration_source",[1145,12270,1966],{"class":1316},[1145,12272,1313],{"class":1312},[1145,12274,1317],{"class":1316},[1145,12276,12277],{"class":1162},"web",[1145,12279,1966],{"class":1316},[1145,12281,3446],{"class":1312},[1145,12283,12284,12286,12289,12291,12293,12296,12298,12302,12304,12306,12308,12310,12313,12315,12317,12320],{"class":1147,"line":6863},[1145,12285,6012],{"class":1316},[1145,12287,12288],{"class":1162},"user_agent",[1145,12290,1966],{"class":1316},[1145,12292,1313],{"class":1312},[1145,12294,12295],{"class":2214}," request",[1145,12297,2554],{"class":1312},[1145,12299,12301],{"class":12300},"sFGJz","META",[1145,12303,2554],{"class":1312},[1145,12305,3400],{"class":2214},[1145,12307,2218],{"class":1312},[1145,12309,1966],{"class":1316},[1145,12311,12312],{"class":1162},"HTTP_USER_AGENT",[1145,12314,1966],{"class":1316},[1145,12316,1900],{"class":1312},[1145,12318,12319],{"class":1316}," ''",[1145,12321,2256],{"class":1312},[1145,12323,12324],{"class":1147,"line":6868},[1145,12325,9679],{"class":1312},[1145,12327,12328],{"class":1147,"line":6892},[1145,12329,7421],{"class":1312},[1145,12331,12332],{"class":1147,"line":6898},[1145,12333,3300],{"class":1890},[1145,12335,12336,12338],{"class":1147,"line":6916},[1145,12337,2827],{"class":1886},[1145,12339,12340],{"class":1890}," user\n",[1145,12342,12343],{"class":1147,"line":6944},[1145,12344,1472],{"emptyLinePlaceholder":1471},[1145,12346,12347],{"class":1147,"line":6964},[1145,12348,12349],{"class":1151},"# Example of event-driven cache invalidation\n",[1145,12351,12352,12354],{"class":1147,"line":6975},[1145,12353,2736],{"class":1312},[1145,12355,3802],{"class":2739},[1145,12357,12358,12360,12363,12365,12367],{"class":1147,"line":6980},[1145,12359,2762],{"class":2761},[1145,12361,12362],{"class":2739}," invalidate_user_caches",[1145,12364,2218],{"class":1312},[1145,12366,3410],{"class":3282},[1145,12368,2774],{"class":1312},[1145,12370,12371],{"class":1147,"line":7029},[1145,12372,3290],{"class":2779},[1145,12374,12375],{"class":1147,"line":7037},[1145,12376,12377],{"class":2783},"    Invalidate all caches related to a user\n",[1145,12379,12380],{"class":1147,"line":7045},[1145,12381,3300],{"class":2783},[1145,12383,12384],{"class":1147,"line":7051},[1145,12385,12386],{"class":2783},"    This task can be triggered by user update events to ensure\n",[1145,12388,12389],{"class":1147,"line":7084},[1145,12390,12391],{"class":2783},"    cached data stays consistent across services\n",[1145,12393,12394],{"class":1147,"line":7118},[1145,12395,3290],{"class":2779},[1145,12397,12398,12401,12403],{"class":1147,"line":7142},[1145,12399,12400],{"class":1890},"    cache_keys ",[1145,12402,2247],{"class":1312},[1145,12404,4273],{"class":1312},[1145,12406,12407,12409,12412,12414,12416,12418,12420],{"class":1147,"line":7147},[1145,12408,7403],{"class":2761},[1145,12410,12411],{"class":1162},"'user:",[1145,12413,2805],{"class":2804},[1145,12415,3410],{"class":1890},[1145,12417,2818],{"class":2804},[1145,12419,1966],{"class":1162},[1145,12421,3446],{"class":1312},[1145,12423,12424,12426,12429,12431,12433,12435,12437],{"class":1147,"line":7164},[1145,12425,7403],{"class":2761},[1145,12427,12428],{"class":1162},"'user_profile:",[1145,12430,2805],{"class":2804},[1145,12432,3410],{"class":1890},[1145,12434,2818],{"class":2804},[1145,12436,1966],{"class":1162},[1145,12438,3446],{"class":1312},[1145,12440,12441,12443,12446,12448,12450,12452,12454],{"class":1147,"line":7198},[1145,12442,7403],{"class":2761},[1145,12444,12445],{"class":1162},"'user_preferences:",[1145,12447,2805],{"class":2804},[1145,12449,3410],{"class":1890},[1145,12451,2818],{"class":2804},[1145,12453,1966],{"class":1162},[1145,12455,3446],{"class":1312},[1145,12457,12458,12460,12463,12465,12467,12469,12471],{"class":1147,"line":7222},[1145,12459,7403],{"class":2761},[1145,12461,12462],{"class":1162},"'user_orders:",[1145,12464,2805],{"class":2804},[1145,12466,3410],{"class":1890},[1145,12468,2818],{"class":2804},[1145,12470,1966],{"class":1162},[1145,12472,3446],{"class":1312},[1145,12474,12475],{"class":1147,"line":7227},[1145,12476,4304],{"class":1312},[1145,12478,12479],{"class":1147,"line":7234},[1145,12480,3300],{"class":1890},[1145,12482,12483,12485,12488,12490,12493],{"class":1147,"line":7248},[1145,12484,4427],{"class":1886},[1145,12486,12487],{"class":1890}," key ",[1145,12489,3927],{"class":1886},[1145,12491,12492],{"class":1890}," cache_keys",[1145,12494,1331],{"class":1312},[1145,12496,12497,12500,12502,12505,12507,12510],{"class":1147,"line":7253},[1145,12498,12499],{"class":1890},"        cache",[1145,12501,2554],{"class":1312},[1145,12503,12504],{"class":2214},"delete",[1145,12506,2218],{"class":1312},[1145,12508,12509],{"class":2214},"key",[1145,12511,2382],{"class":1312},[1145,12513,12514,12516,12518,12521,12523,12525,12528,12530,12532,12534,12536],{"class":1147,"line":7259},[1145,12515,3546],{"class":1890},[1145,12517,2554],{"class":1312},[1145,12519,12520],{"class":2214},"debug",[1145,12522,2218],{"class":1312},[1145,12524,2798],{"class":2761},[1145,12526,12527],{"class":1162},"\"Invalidated cache key: ",[1145,12529,2805],{"class":2804},[1145,12531,12509],{"class":2214},[1145,12533,2818],{"class":2804},[1145,12535,1382],{"class":1162},[1145,12537,2382],{"class":1312},[1145,12539,12540],{"class":1147,"line":7264},[1145,12541,3300],{"class":1890},[1145,12543,12544],{"class":1147,"line":7269},[1145,12545,12546],{"class":1151},"    # Also invalidate pattern-based caches\n",[1145,12548,12549,12552,12554],{"class":1147,"line":7275},[1145,12550,12551],{"class":1890},"    cache_patterns ",[1145,12553,2247],{"class":1312},[1145,12555,4273],{"class":1312},[1145,12557,12558,12560,12563],{"class":1147,"line":7281},[1145,12559,7403],{"class":2761},[1145,12561,12562],{"class":1162},"'user_list:*'",[1145,12564,3446],{"class":1312},[1145,12566,12567,12569,12572],{"class":1147,"line":7287},[1145,12568,7403],{"class":2761},[1145,12570,12571],{"class":1162},"'user_stats:*'",[1145,12573,3446],{"class":1312},[1145,12575,12576],{"class":1147,"line":7292},[1145,12577,4304],{"class":1312},[1145,12579,12580],{"class":1147,"line":7319},[1145,12581,3300],{"class":1890},[1145,12583,12584,12586,12589,12591,12594],{"class":1147,"line":7324},[1145,12585,4427],{"class":1886},[1145,12587,12588],{"class":1890}," pattern ",[1145,12590,3927],{"class":1886},[1145,12592,12593],{"class":1890}," cache_patterns",[1145,12595,1331],{"class":1312},[1145,12597,12598,12601,12603,12605,12607,12610],{"class":1147,"line":7350},[1145,12599,12600],{"class":1890},"        invalidate_cache_pattern",[1145,12602,2554],{"class":1312},[1145,12604,4023],{"class":2214},[1145,12606,2218],{"class":1312},[1145,12608,12609],{"class":2214},"pattern",[1145,12611,2382],{"class":1312},[1026,12613,12614],{},[1050,12615,12616],{},"Key concepts in event-driven communication:",[1754,12618,12619,12625,12631,12637,12643],{},[1047,12620,12621,12624],{},[1050,12622,12623],{},"Event Schema",": Standardized event format ensures all services can understand events",[1047,12626,12627,12630],{},[1050,12628,12629],{},"Event Routing",": Different event types go to different queues based on which services care about them",[1047,12632,12633,12636],{},[1050,12634,12635],{},"Event Handlers",": Each service implements handlers for events it cares about",[1047,12638,12639,12642],{},[1050,12640,12641],{},"Idempotency",": Events should be safe to process multiple times",[1047,12644,12645,12648],{},[1050,12646,12647],{},"Event Versioning",": Include version information for backward compatibility",[1030,12650,12652],{"id":12651},"monitoring-and-error-handling","Monitoring and Error Handling",[1246,12654,12656],{"id":12655},"task-monitoring","Task Monitoring",[1135,12658,12660],{"className":1872,"code":12659,"language":1874,"meta":1140,"style":1140},"# Monitoring and logging\nimport structlog\nfrom celery.signals import task_prerun, task_postrun, task_failure\n\nlogger = structlog.get_logger()\n\n@task_prerun.connect\ndef task_prerun_handler(sender=None, task_id=None, task=None, args=None, kwargs=None, **kwds):\n    logger.info(\"Task started\", task_id=task_id, task_name=task.name)\n\n@task_postrun.connect\ndef task_postrun_handler(sender=None, task_id=None, task=None, args=None, kwargs=None, retval=None, state=None, **kwds):\n    logger.info(\"Task completed\", task_id=task_id, task_name=task.name, state=state)\n\n@task_failure.connect\ndef task_failure_handler(sender=None, task_id=None, exception=None, traceback=None, einfo=None, **kwds):\n    logger.error(\"Task failed\", task_id=task_id, task_name=sender.name, exception=str(exception))\n\n# Custom task base class with enhanced error handling\nfrom celery import Task\n\nclass CallbackTask(Task):\n    \"\"\"Custom task class with callbacks and enhanced error handling\"\"\"\n    \n    def on_success(self, retval, task_id, args, kwargs):\n        \"\"\"Called on task success\"\"\"\n        logger.info(f\"Task {task_id} succeeded with result: {retval}\")\n    \n    def on_failure(self, exc, task_id, args, kwargs, einfo):\n        \"\"\"Called on task failure\"\"\"\n        logger.error(f\"Task {task_id} failed: {exc}\")\n        \n        # Send failure notification\n        send_failure_notification.delay(task_id, str(exc))\n    \n    def on_retry(self, exc, task_id, args, kwargs, einfo):\n        \"\"\"Called on task retry\"\"\"\n        logger.warning(f\"Task {task_id} retrying due to: {exc}\")\n\n@shared_task(base=CallbackTask, bind=True)\ndef robust_task(self, data):\n    \"\"\"Example task with robust error handling\"\"\"\n    try:\n        # Task logic here\n        result = process_data(data)\n        return result\n    except RetryableException as exc:\n        # Retry with exponential backoff\n        raise self.retry(\n            exc=exc,\n            countdown=2 ** self.request.retries,\n            max_retries=5\n        )\n    except FatalException as exc:\n        # Don't retry fatal exceptions\n        logger.error(f\"Fatal error in task: {exc}\")\n        raise\n",[1142,12661,12662,12667,12674,12701,12705,12721,12725,12737,12798,12840,12844,12855,12928,12976,12980,12991,13049,13102,13106,13111,13122,13126,13142,13151,13155,13185,13195,13230,13234,13267,13276,13309,13313,13318,13341,13345,13378,13387,13420,13424,13451,13468,13477,13483,13488,13503,13509,13522,13526,13538,13549,13572,13582,13586,13599,13604,13629],{"__ignoreMap":1140},[1145,12663,12664],{"class":1147,"line":1148},[1145,12665,12666],{"class":1151},"# Monitoring and logging\n",[1145,12668,12669,12671],{"class":1147,"line":1155},[1145,12670,1894],{"class":1886},[1145,12672,12673],{"class":1890}," structlog\n",[1145,12675,12676,12678,12681,12683,12686,12688,12691,12693,12696,12698],{"class":1147,"line":1173},[1145,12677,1887],{"class":1886},[1145,12679,12680],{"class":1890}," celery",[1145,12682,2554],{"class":1312},[1145,12684,12685],{"class":1890},"signals ",[1145,12687,1894],{"class":1886},[1145,12689,12690],{"class":1890}," task_prerun",[1145,12692,1900],{"class":1312},[1145,12694,12695],{"class":1890}," task_postrun",[1145,12697,1900],{"class":1312},[1145,12699,12700],{"class":1890}," task_failure\n",[1145,12702,12703],{"class":1147,"line":1186},[1145,12704,1472],{"emptyLinePlaceholder":1471},[1145,12706,12707,12709,12711,12714,12716,12719],{"class":1147,"line":1199},[1145,12708,3218],{"class":1890},[1145,12710,2247],{"class":1312},[1145,12712,12713],{"class":1890}," structlog",[1145,12715,2554],{"class":1312},[1145,12717,12718],{"class":2214},"get_logger",[1145,12720,2722],{"class":1312},[1145,12722,12723],{"class":1147,"line":1351},[1145,12724,1472],{"emptyLinePlaceholder":1471},[1145,12726,12727,12729,12732,12734],{"class":1147,"line":1362},[1145,12728,2736],{"class":1312},[1145,12730,12731],{"class":2739},"task_prerun",[1145,12733,2554],{"class":1312},[1145,12735,12736],{"class":2739},"connect\n",[1145,12738,12739,12741,12744,12746,12749,12751,12753,12755,12758,12760,12762,12764,12767,12769,12771,12773,12776,12778,12780,12782,12785,12787,12789,12791,12793,12796],{"class":1147,"line":1370},[1145,12740,2762],{"class":2761},[1145,12742,12743],{"class":2739}," task_prerun_handler",[1145,12745,2218],{"class":1312},[1145,12747,12748],{"class":3282},"sender",[1145,12750,2247],{"class":1814},[1145,12752,10276],{"class":2043},[1145,12754,1900],{"class":1312},[1145,12756,12757],{"class":3282}," task_id",[1145,12759,2247],{"class":1814},[1145,12761,10276],{"class":2043},[1145,12763,1900],{"class":1312},[1145,12765,12766],{"class":3282}," task",[1145,12768,2247],{"class":1814},[1145,12770,10276],{"class":2043},[1145,12772,1900],{"class":1312},[1145,12774,12775],{"class":3282}," args",[1145,12777,2247],{"class":1814},[1145,12779,10276],{"class":2043},[1145,12781,1900],{"class":1312},[1145,12783,12784],{"class":3282}," kwargs",[1145,12786,2247],{"class":1814},[1145,12788,10276],{"class":2043},[1145,12790,1900],{"class":1312},[1145,12792,3775],{"class":1814},[1145,12794,12795],{"class":3282},"kwds",[1145,12797,2774],{"class":1312},[1145,12799,12800,12802,12804,12806,12808,12810,12813,12815,12817,12819,12821,12824,12826,12829,12831,12833,12835,12838],{"class":1147,"line":1388},[1145,12801,5466],{"class":1890},[1145,12803,2554],{"class":1312},[1145,12805,3551],{"class":2214},[1145,12807,2218],{"class":1312},[1145,12809,1382],{"class":1316},[1145,12811,12812],{"class":1162},"Task started",[1145,12814,1382],{"class":1316},[1145,12816,1900],{"class":1312},[1145,12818,12757],{"class":2243},[1145,12820,2247],{"class":1312},[1145,12822,12823],{"class":2214},"task_id",[1145,12825,1900],{"class":1312},[1145,12827,12828],{"class":2243}," task_name",[1145,12830,2247],{"class":1312},[1145,12832,2744],{"class":2214},[1145,12834,2554],{"class":1312},[1145,12836,12837],{"class":2586},"name",[1145,12839,2382],{"class":1312},[1145,12841,12842],{"class":1147,"line":1403},[1145,12843,1472],{"emptyLinePlaceholder":1471},[1145,12845,12846,12848,12851,12853],{"class":1147,"line":1411},[1145,12847,2736],{"class":1312},[1145,12849,12850],{"class":2739},"task_postrun",[1145,12852,2554],{"class":1312},[1145,12854,12736],{"class":2739},[1145,12856,12857,12859,12862,12864,12866,12868,12870,12872,12874,12876,12878,12880,12882,12884,12886,12888,12890,12892,12894,12896,12898,12900,12902,12904,12907,12909,12911,12913,12916,12918,12920,12922,12924,12926],{"class":1147,"line":1422},[1145,12858,2762],{"class":2761},[1145,12860,12861],{"class":2739}," task_postrun_handler",[1145,12863,2218],{"class":1312},[1145,12865,12748],{"class":3282},[1145,12867,2247],{"class":1814},[1145,12869,10276],{"class":2043},[1145,12871,1900],{"class":1312},[1145,12873,12757],{"class":3282},[1145,12875,2247],{"class":1814},[1145,12877,10276],{"class":2043},[1145,12879,1900],{"class":1312},[1145,12881,12766],{"class":3282},[1145,12883,2247],{"class":1814},[1145,12885,10276],{"class":2043},[1145,12887,1900],{"class":1312},[1145,12889,12775],{"class":3282},[1145,12891,2247],{"class":1814},[1145,12893,10276],{"class":2043},[1145,12895,1900],{"class":1312},[1145,12897,12784],{"class":3282},[1145,12899,2247],{"class":1814},[1145,12901,10276],{"class":2043},[1145,12903,1900],{"class":1312},[1145,12905,12906],{"class":3282}," retval",[1145,12908,2247],{"class":1814},[1145,12910,10276],{"class":2043},[1145,12912,1900],{"class":1312},[1145,12914,12915],{"class":3282}," state",[1145,12917,2247],{"class":1814},[1145,12919,10276],{"class":2043},[1145,12921,1900],{"class":1312},[1145,12923,3775],{"class":1814},[1145,12925,12795],{"class":3282},[1145,12927,2774],{"class":1312},[1145,12929,12930,12932,12934,12936,12938,12940,12943,12945,12947,12949,12951,12953,12955,12957,12959,12961,12963,12965,12967,12969,12971,12974],{"class":1147,"line":1433},[1145,12931,5466],{"class":1890},[1145,12933,2554],{"class":1312},[1145,12935,3551],{"class":2214},[1145,12937,2218],{"class":1312},[1145,12939,1382],{"class":1316},[1145,12941,12942],{"class":1162},"Task completed",[1145,12944,1382],{"class":1316},[1145,12946,1900],{"class":1312},[1145,12948,12757],{"class":2243},[1145,12950,2247],{"class":1312},[1145,12952,12823],{"class":2214},[1145,12954,1900],{"class":1312},[1145,12956,12828],{"class":2243},[1145,12958,2247],{"class":1312},[1145,12960,2744],{"class":2214},[1145,12962,2554],{"class":1312},[1145,12964,12837],{"class":2586},[1145,12966,1900],{"class":1312},[1145,12968,12915],{"class":2243},[1145,12970,2247],{"class":1312},[1145,12972,12973],{"class":2214},"state",[1145,12975,2382],{"class":1312},[1145,12977,12978],{"class":1147,"line":1441},[1145,12979,1472],{"emptyLinePlaceholder":1471},[1145,12981,12982,12984,12987,12989],{"class":1147,"line":1452},[1145,12983,2736],{"class":1312},[1145,12985,12986],{"class":2739},"task_failure",[1145,12988,2554],{"class":1312},[1145,12990,12736],{"class":2739},[1145,12992,12993,12995,12998,13000,13002,13004,13006,13008,13010,13012,13014,13016,13019,13021,13023,13025,13028,13030,13032,13034,13037,13039,13041,13043,13045,13047],{"class":1147,"line":1460},[1145,12994,2762],{"class":2761},[1145,12996,12997],{"class":2739}," task_failure_handler",[1145,12999,2218],{"class":1312},[1145,13001,12748],{"class":3282},[1145,13003,2247],{"class":1814},[1145,13005,10276],{"class":2043},[1145,13007,1900],{"class":1312},[1145,13009,12757],{"class":3282},[1145,13011,2247],{"class":1814},[1145,13013,10276],{"class":2043},[1145,13015,1900],{"class":1312},[1145,13017,13018],{"class":3282}," exception",[1145,13020,2247],{"class":1814},[1145,13022,10276],{"class":2043},[1145,13024,1900],{"class":1312},[1145,13026,13027],{"class":3282}," traceback",[1145,13029,2247],{"class":1814},[1145,13031,10276],{"class":2043},[1145,13033,1900],{"class":1312},[1145,13035,13036],{"class":3282}," einfo",[1145,13038,2247],{"class":1814},[1145,13040,10276],{"class":2043},[1145,13042,1900],{"class":1312},[1145,13044,3775],{"class":1814},[1145,13046,12795],{"class":3282},[1145,13048,2774],{"class":1312},[1145,13050,13051,13053,13055,13057,13059,13061,13064,13066,13068,13070,13072,13074,13076,13078,13080,13082,13084,13086,13088,13090,13092,13095,13097,13100],{"class":1147,"line":1468},[1145,13052,5466],{"class":1890},[1145,13054,2554],{"class":1312},[1145,13056,3627],{"class":2214},[1145,13058,2218],{"class":1312},[1145,13060,1382],{"class":1316},[1145,13062,13063],{"class":1162},"Task failed",[1145,13065,1382],{"class":1316},[1145,13067,1900],{"class":1312},[1145,13069,12757],{"class":2243},[1145,13071,2247],{"class":1312},[1145,13073,12823],{"class":2214},[1145,13075,1900],{"class":1312},[1145,13077,12828],{"class":2243},[1145,13079,2247],{"class":1312},[1145,13081,12748],{"class":2214},[1145,13083,2554],{"class":1312},[1145,13085,12837],{"class":2586},[1145,13087,1900],{"class":1312},[1145,13089,13018],{"class":2243},[1145,13091,2247],{"class":1312},[1145,13093,13094],{"class":3664},"str",[1145,13096,2218],{"class":1312},[1145,13098,13099],{"class":2214},"exception",[1145,13101,3789],{"class":1312},[1145,13103,13104],{"class":1147,"line":1475},[1145,13105,1472],{"emptyLinePlaceholder":1471},[1145,13107,13108],{"class":1147,"line":1483},[1145,13109,13110],{"class":1151},"# Custom task base class with enhanced error handling\n",[1145,13112,13113,13115,13117,13119],{"class":1147,"line":1493},[1145,13114,1887],{"class":1886},[1145,13116,2539],{"class":1890},[1145,13118,1894],{"class":1886},[1145,13120,13121],{"class":1890}," Task\n",[1145,13123,13124],{"class":1147,"line":1503},[1145,13125,1472],{"emptyLinePlaceholder":1471},[1145,13127,13128,13131,13135,13137,13140],{"class":1147,"line":1510},[1145,13129,13130],{"class":2761},"class",[1145,13132,13134],{"class":13133},"sD-vU"," CallbackTask",[1145,13136,2218],{"class":1312},[1145,13138,13139],{"class":1158},"Task",[1145,13141,2774],{"class":1312},[1145,13143,13144,13146,13149],{"class":1147,"line":1523},[1145,13145,2780],{"class":2779},[1145,13147,13148],{"class":2783},"Custom task class with callbacks and enhanced error handling",[1145,13150,2787],{"class":2779},[1145,13152,13153],{"class":1147,"line":1530},[1145,13154,3300],{"class":1890},[1145,13156,13157,13160,13163,13165,13167,13169,13171,13173,13175,13177,13179,13181,13183],{"class":1147,"line":1537},[1145,13158,13159],{"class":2761},"    def",[1145,13161,13162],{"class":2739}," on_success",[1145,13164,2218],{"class":1312},[1145,13166,2771],{"class":2770},[1145,13168,1900],{"class":1312},[1145,13170,12906],{"class":3282},[1145,13172,1900],{"class":1312},[1145,13174,12757],{"class":3282},[1145,13176,1900],{"class":1312},[1145,13178,12775],{"class":3282},[1145,13180,1900],{"class":1312},[1145,13182,12784],{"class":3282},[1145,13184,2774],{"class":1312},[1145,13186,13187,13190,13193],{"class":1147,"line":1542},[1145,13188,13189],{"class":2779},"        \"\"\"",[1145,13191,13192],{"class":2783},"Called on task success",[1145,13194,2787],{"class":2779},[1145,13196,13197,13199,13201,13203,13205,13207,13210,13212,13214,13216,13219,13221,13224,13226,13228],{"class":1147,"line":1550},[1145,13198,3546],{"class":1890},[1145,13200,2554],{"class":1312},[1145,13202,3551],{"class":2214},[1145,13204,2218],{"class":1312},[1145,13206,2798],{"class":2761},[1145,13208,13209],{"class":1162},"\"Task ",[1145,13211,2805],{"class":2804},[1145,13213,12823],{"class":2214},[1145,13215,2818],{"class":2804},[1145,13217,13218],{"class":1162}," succeeded with result: ",[1145,13220,2805],{"class":2804},[1145,13222,13223],{"class":2214},"retval",[1145,13225,2818],{"class":2804},[1145,13227,1382],{"class":1162},[1145,13229,2382],{"class":1312},[1145,13231,13232],{"class":1147,"line":1561},[1145,13233,3300],{"class":1890},[1145,13235,13236,13238,13241,13243,13245,13247,13249,13251,13253,13255,13257,13259,13261,13263,13265],{"class":1147,"line":1566},[1145,13237,13159],{"class":2761},[1145,13239,13240],{"class":2739}," on_failure",[1145,13242,2218],{"class":1312},[1145,13244,2771],{"class":2770},[1145,13246,1900],{"class":1312},[1145,13248,3671],{"class":3282},[1145,13250,1900],{"class":1312},[1145,13252,12757],{"class":3282},[1145,13254,1900],{"class":1312},[1145,13256,12775],{"class":3282},[1145,13258,1900],{"class":1312},[1145,13260,12784],{"class":3282},[1145,13262,1900],{"class":1312},[1145,13264,13036],{"class":3282},[1145,13266,2774],{"class":1312},[1145,13268,13269,13271,13274],{"class":1147,"line":1574},[1145,13270,13189],{"class":2779},[1145,13272,13273],{"class":2783},"Called on task failure",[1145,13275,2787],{"class":2779},[1145,13277,13278,13280,13282,13284,13286,13288,13290,13292,13294,13296,13299,13301,13303,13305,13307],{"class":1147,"line":1582},[1145,13279,3546],{"class":1890},[1145,13281,2554],{"class":1312},[1145,13283,3627],{"class":2214},[1145,13285,2218],{"class":1312},[1145,13287,2798],{"class":2761},[1145,13289,13209],{"class":1162},[1145,13291,2805],{"class":2804},[1145,13293,12823],{"class":2214},[1145,13295,2818],{"class":2804},[1145,13297,13298],{"class":1162}," failed: ",[1145,13300,2805],{"class":2804},[1145,13302,3709],{"class":2214},[1145,13304,2818],{"class":2804},[1145,13306,1382],{"class":1162},[1145,13308,2382],{"class":1312},[1145,13310,13311],{"class":1147,"line":2379},[1145,13312,3315],{"class":1890},[1145,13314,13315],{"class":1147,"line":2385},[1145,13316,13317],{"class":1151},"        # Send failure notification\n",[1145,13319,13320,13323,13325,13327,13329,13331,13333,13335,13337,13339],{"class":1147,"line":2390},[1145,13321,13322],{"class":1890},"        send_failure_notification",[1145,13324,2554],{"class":1312},[1145,13326,4023],{"class":2214},[1145,13328,2218],{"class":1312},[1145,13330,12823],{"class":2214},[1145,13332,1900],{"class":1312},[1145,13334,5309],{"class":3664},[1145,13336,2218],{"class":1312},[1145,13338,3709],{"class":2214},[1145,13340,3789],{"class":1312},[1145,13342,13343],{"class":1147,"line":2396},[1145,13344,3300],{"class":1890},[1145,13346,13347,13349,13352,13354,13356,13358,13360,13362,13364,13366,13368,13370,13372,13374,13376],{"class":1147,"line":2410},[1145,13348,13159],{"class":2761},[1145,13350,13351],{"class":2739}," on_retry",[1145,13353,2218],{"class":1312},[1145,13355,2771],{"class":2770},[1145,13357,1900],{"class":1312},[1145,13359,3671],{"class":3282},[1145,13361,1900],{"class":1312},[1145,13363,12757],{"class":3282},[1145,13365,1900],{"class":1312},[1145,13367,12775],{"class":3282},[1145,13369,1900],{"class":1312},[1145,13371,12784],{"class":3282},[1145,13373,1900],{"class":1312},[1145,13375,13036],{"class":3282},[1145,13377,2774],{"class":1312},[1145,13379,13380,13382,13385],{"class":1147,"line":2424},[1145,13381,13189],{"class":2779},[1145,13383,13384],{"class":2783},"Called on task retry",[1145,13386,2787],{"class":2779},[1145,13388,13389,13391,13393,13395,13397,13399,13401,13403,13405,13407,13410,13412,13414,13416,13418],{"class":1147,"line":2438},[1145,13390,3546],{"class":1890},[1145,13392,2554],{"class":1312},[1145,13394,10752],{"class":2214},[1145,13396,2218],{"class":1312},[1145,13398,2798],{"class":2761},[1145,13400,13209],{"class":1162},[1145,13402,2805],{"class":2804},[1145,13404,12823],{"class":2214},[1145,13406,2818],{"class":2804},[1145,13408,13409],{"class":1162}," retrying due to: ",[1145,13411,2805],{"class":2804},[1145,13413,3709],{"class":2214},[1145,13415,2818],{"class":2804},[1145,13417,1382],{"class":1162},[1145,13419,2382],{"class":1312},[1145,13421,13422],{"class":1147,"line":2443},[1145,13423,1472],{"emptyLinePlaceholder":1471},[1145,13425,13426,13428,13430,13432,13435,13437,13440,13442,13445,13447,13449],{"class":1147,"line":2449},[1145,13427,2736],{"class":1312},[1145,13429,3246],{"class":2739},[1145,13431,2218],{"class":1312},[1145,13433,13434],{"class":2243},"base",[1145,13436,2247],{"class":1312},[1145,13438,13439],{"class":2214},"CallbackTask",[1145,13441,1900],{"class":1312},[1145,13443,13444],{"class":2243}," bind",[1145,13446,2247],{"class":1312},[1145,13448,2754],{"class":2043},[1145,13450,2382],{"class":1312},[1145,13452,13453,13455,13458,13460,13462,13464,13466],{"class":1147,"line":2463},[1145,13454,2762],{"class":2761},[1145,13456,13457],{"class":2739}," robust_task",[1145,13459,2218],{"class":1312},[1145,13461,2771],{"class":2770},[1145,13463,1900],{"class":1312},[1145,13465,10271],{"class":3282},[1145,13467,2774],{"class":1312},[1145,13469,13470,13472,13475],{"class":1147,"line":3526},[1145,13471,2780],{"class":2779},[1145,13473,13474],{"class":2783},"Example task with robust error handling",[1145,13476,2787],{"class":2779},[1145,13478,13479,13481],{"class":1147,"line":3532},[1145,13480,3363],{"class":1886},[1145,13482,1331],{"class":1312},[1145,13484,13485],{"class":1147,"line":3537},[1145,13486,13487],{"class":1151},"        # Task logic here\n",[1145,13489,13490,13492,13494,13497,13499,13501],{"class":1147,"line":3543},[1145,13491,5091],{"class":1890},[1145,13493,2247],{"class":1312},[1145,13495,13496],{"class":2214}," process_data",[1145,13498,2218],{"class":1312},[1145,13500,10387],{"class":2214},[1145,13502,2382],{"class":1312},[1145,13504,13505,13507],{"class":1147,"line":3571},[1145,13506,3574],{"class":1886},[1145,13508,11387],{"class":1890},[1145,13510,13511,13513,13516,13518,13520],{"class":1147,"line":3594},[1145,13512,3602],{"class":1886},[1145,13514,13515],{"class":1890}," RetryableException ",[1145,13517,2895],{"class":1886},[1145,13519,3671],{"class":1890},[1145,13521,1331],{"class":1312},[1145,13523,13524],{"class":1147,"line":3599},[1145,13525,3726],{"class":1151},[1145,13527,13528,13530,13532,13534,13536],{"class":1147,"line":3614},[1145,13529,3738],{"class":1886},[1145,13531,3741],{"class":1917},[1145,13533,2554],{"class":1312},[1145,13535,3746],{"class":2214},[1145,13537,3429],{"class":1312},[1145,13539,13540,13543,13545,13547],{"class":1147,"line":3620},[1145,13541,13542],{"class":2243},"            exc",[1145,13544,2247],{"class":1312},[1145,13546,3709],{"class":2214},[1145,13548,3446],{"class":1312},[1145,13550,13551,13554,13556,13558,13560,13562,13564,13566,13568,13570],{"class":1147,"line":3648},[1145,13552,13553],{"class":2243},"            countdown",[1145,13555,2247],{"class":1312},[1145,13557,3772],{"class":1169},[1145,13559,3775],{"class":1814},[1145,13561,3741],{"class":1917},[1145,13563,2554],{"class":1312},[1145,13565,2812],{"class":2586},[1145,13567,2554],{"class":1312},[1145,13569,3786],{"class":2586},[1145,13571,3446],{"class":1312},[1145,13573,13574,13577,13579],{"class":1147,"line":3654},[1145,13575,13576],{"class":2243},"            max_retries",[1145,13578,2247],{"class":1312},[1145,13580,13581],{"class":1169},"5\n",[1145,13583,13584],{"class":1147,"line":3659},[1145,13585,3529],{"class":1312},[1145,13587,13588,13590,13593,13595,13597],{"class":1147,"line":3676},[1145,13589,3602],{"class":1886},[1145,13591,13592],{"class":1890}," FatalException ",[1145,13594,2895],{"class":1886},[1145,13596,3671],{"class":1890},[1145,13598,1331],{"class":1312},[1145,13600,13601],{"class":1147,"line":3682},[1145,13602,13603],{"class":1151},"        # Don't retry fatal exceptions\n",[1145,13605,13606,13608,13610,13612,13614,13616,13619,13621,13623,13625,13627],{"class":1147,"line":3718},[1145,13607,3546],{"class":1890},[1145,13609,2554],{"class":1312},[1145,13611,3627],{"class":2214},[1145,13613,2218],{"class":1312},[1145,13615,2798],{"class":2761},[1145,13617,13618],{"class":1162},"\"Fatal error in task: ",[1145,13620,2805],{"class":2804},[1145,13622,3709],{"class":2214},[1145,13624,2818],{"class":2804},[1145,13626,1382],{"class":1162},[1145,13628,2382],{"class":1312},[1145,13630,13631],{"class":1147,"line":3723},[1145,13632,3651],{"class":1886},[1246,13634,13636],{"id":13635},"health-checks-and-circuit-breakers","Health Checks and Circuit Breakers",[1135,13638,13640],{"className":1872,"code":13639,"language":1874,"meta":1140,"style":1140},"# Circuit breaker pattern for external service calls\nimport time\nfrom functools import wraps\n\nclass CircuitBreaker:\n    def __init__(self, failure_threshold=5, recovery_timeout=60):\n        self.failure_threshold = failure_threshold\n        self.recovery_timeout = recovery_timeout\n        self.failure_count = 0\n        self.last_failure_time = None\n        self.state = 'CLOSED'  # CLOSED, OPEN, HALF_OPEN\n    \n    def call(self, func, *args, **kwargs):\n        if self.state == 'OPEN':\n            if time.time() - self.last_failure_time > self.recovery_timeout:\n                self.state = 'HALF_OPEN'\n            else:\n                raise Exception(\"Circuit breaker is OPEN\")\n        \n        try:\n            result = func(*args, **kwargs)\n            self.on_success()\n            return result\n        except Exception as exc:\n            self.on_failure()\n            raise exc\n    \n    def on_success(self):\n        self.failure_count = 0\n        self.state = 'CLOSED'\n    \n    def on_failure(self):\n        self.failure_count += 1\n        self.last_failure_time = time.time()\n        \n        if self.failure_count >= self.failure_threshold:\n            self.state = 'OPEN'\n\n# Usage in tasks\npayment_circuit_breaker = CircuitBreaker(failure_threshold=3, recovery_timeout=30)\n\n@shared_task(bind=True, max_retries=3)\ndef process_payment_with_circuit_breaker(self, order_id, amount):\n    \"\"\"Process payment with circuit breaker protection\"\"\"\n    try:\n        def make_payment_call():\n            response = requests.post(\n                'http://payment-service:8005/api/charge/',\n                json={'order_id': order_id, 'amount': amount},\n                timeout=10\n            )\n            response.raise_for_status()\n            return response.json()\n        \n        result = payment_circuit_breaker.call(make_payment_call)\n        return result\n        \n    except Exception as exc:\n        logger.error(f\"Payment processing failed: {exc}\")\n        raise self.retry(exc=exc, countdown=60)\n",[1142,13641,13642,13647,13654,13666,13670,13679,13711,13726,13740,13753,13767,13787,13791,13823,13844,13878,13896,13903,13920,13924,13930,13953,13965,13971,13983,13994,14001,14005,14017,14029,14045,14049,14061,14075,14093,14097,14118,14134,14138,14143,14170,14174,14198,14220,14229,14235,14245,14259,14269,14300,14308,14312,14322,14334,14338,14359,14365,14369,14381,14406],{"__ignoreMap":1140},[1145,13643,13644],{"class":1147,"line":1148},[1145,13645,13646],{"class":1151},"# Circuit breaker pattern for external service calls\n",[1145,13648,13649,13651],{"class":1147,"line":1155},[1145,13650,1894],{"class":1886},[1145,13652,13653],{"class":1890}," time\n",[1145,13655,13656,13658,13661,13663],{"class":1147,"line":1173},[1145,13657,1887],{"class":1886},[1145,13659,13660],{"class":1890}," functools ",[1145,13662,1894],{"class":1886},[1145,13664,13665],{"class":1890}," wraps\n",[1145,13667,13668],{"class":1147,"line":1186},[1145,13669,1472],{"emptyLinePlaceholder":1471},[1145,13671,13672,13674,13677],{"class":1147,"line":1199},[1145,13673,13130],{"class":2761},[1145,13675,13676],{"class":13133}," CircuitBreaker",[1145,13678,1331],{"class":1312},[1145,13680,13681,13683,13686,13688,13690,13692,13695,13697,13700,13702,13705,13707,13709],{"class":1147,"line":1351},[1145,13682,13159],{"class":2761},[1145,13684,13685],{"class":2792}," __init__",[1145,13687,2218],{"class":1312},[1145,13689,2771],{"class":2770},[1145,13691,1900],{"class":1312},[1145,13693,13694],{"class":3282}," failure_threshold",[1145,13696,2247],{"class":1814},[1145,13698,13699],{"class":1169},"5",[1145,13701,1900],{"class":1312},[1145,13703,13704],{"class":3282}," recovery_timeout",[1145,13706,2247],{"class":1814},[1145,13708,3764],{"class":1169},[1145,13710,2774],{"class":1312},[1145,13712,13713,13716,13718,13721,13723],{"class":1147,"line":1362},[1145,13714,13715],{"class":1917},"        self",[1145,13717,2554],{"class":1312},[1145,13719,13720],{"class":2586},"failure_threshold",[1145,13722,1921],{"class":1312},[1145,13724,13725],{"class":1890}," failure_threshold\n",[1145,13727,13728,13730,13732,13735,13737],{"class":1147,"line":1370},[1145,13729,13715],{"class":1917},[1145,13731,2554],{"class":1312},[1145,13733,13734],{"class":2586},"recovery_timeout",[1145,13736,1921],{"class":1312},[1145,13738,13739],{"class":1890}," recovery_timeout\n",[1145,13741,13742,13744,13746,13749,13751],{"class":1147,"line":1388},[1145,13743,13715],{"class":1917},[1145,13745,2554],{"class":1312},[1145,13747,13748],{"class":2586},"failure_count",[1145,13750,1921],{"class":1312},[1145,13752,9852],{"class":1169},[1145,13754,13755,13757,13759,13762,13764],{"class":1147,"line":1403},[1145,13756,13715],{"class":1917},[1145,13758,2554],{"class":1312},[1145,13760,13761],{"class":2586},"last_failure_time",[1145,13763,1921],{"class":1312},[1145,13765,13766],{"class":2043}," None\n",[1145,13768,13769,13771,13773,13775,13777,13779,13782,13784],{"class":1147,"line":1411},[1145,13770,13715],{"class":1917},[1145,13772,2554],{"class":1312},[1145,13774,12973],{"class":2586},[1145,13776,1921],{"class":1312},[1145,13778,1317],{"class":1316},[1145,13780,13781],{"class":1162},"CLOSED",[1145,13783,1966],{"class":1316},[1145,13785,13786],{"class":1151},"  # CLOSED, OPEN, HALF_OPEN\n",[1145,13788,13789],{"class":1147,"line":1422},[1145,13790,3300],{"class":1890},[1145,13792,13793,13795,13798,13800,13802,13804,13807,13809,13811,13814,13816,13818,13821],{"class":1147,"line":1433},[1145,13794,13159],{"class":2761},[1145,13796,13797],{"class":2739}," call",[1145,13799,2218],{"class":1312},[1145,13801,2771],{"class":2770},[1145,13803,1900],{"class":1312},[1145,13805,13806],{"class":3282}," func",[1145,13808,1900],{"class":1312},[1145,13810,3767],{"class":1814},[1145,13812,13813],{"class":3282},"args",[1145,13815,1900],{"class":1312},[1145,13817,3775],{"class":1814},[1145,13819,13820],{"class":3282},"kwargs",[1145,13822,2774],{"class":1312},[1145,13824,13825,13827,13829,13831,13833,13835,13837,13840,13842],{"class":1147,"line":1441},[1145,13826,6871],{"class":1886},[1145,13828,3741],{"class":1917},[1145,13830,2554],{"class":1312},[1145,13832,12973],{"class":2586},[1145,13834,9286],{"class":1814},[1145,13836,1317],{"class":1316},[1145,13838,13839],{"class":1162},"OPEN",[1145,13841,1966],{"class":1316},[1145,13843,1331],{"class":1312},[1145,13845,13846,13848,13851,13853,13856,13858,13861,13863,13865,13867,13870,13872,13874,13876],{"class":1147,"line":1452},[1145,13847,3943],{"class":1886},[1145,13849,13850],{"class":1890}," time",[1145,13852,2554],{"class":1312},[1145,13854,13855],{"class":2214},"time",[1145,13857,4547],{"class":1312},[1145,13859,13860],{"class":1814}," -",[1145,13862,3741],{"class":1917},[1145,13864,2554],{"class":1312},[1145,13866,13761],{"class":2586},[1145,13868,13869],{"class":1814}," >",[1145,13871,3741],{"class":1917},[1145,13873,2554],{"class":1312},[1145,13875,13734],{"class":2586},[1145,13877,1331],{"class":1312},[1145,13879,13880,13883,13885,13887,13889,13891,13894],{"class":1147,"line":1460},[1145,13881,13882],{"class":1917},"                self",[1145,13884,2554],{"class":1312},[1145,13886,12973],{"class":2586},[1145,13888,1921],{"class":1312},[1145,13890,1317],{"class":1316},[1145,13892,13893],{"class":1162},"HALF_OPEN",[1145,13895,1323],{"class":1316},[1145,13897,13898,13901],{"class":1147,"line":1468},[1145,13899,13900],{"class":1886},"            else",[1145,13902,1331],{"class":1312},[1145,13904,13905,13907,13909,13911,13913,13916,13918],{"class":1147,"line":1475},[1145,13906,5685],{"class":1886},[1145,13908,3665],{"class":3664},[1145,13910,2218],{"class":1312},[1145,13912,1382],{"class":1316},[1145,13914,13915],{"class":1162},"Circuit breaker is OPEN",[1145,13917,1382],{"class":1316},[1145,13919,2382],{"class":1312},[1145,13921,13922],{"class":1147,"line":1483},[1145,13923,3315],{"class":1890},[1145,13925,13926,13928],{"class":1147,"line":1493},[1145,13927,4443],{"class":1886},[1145,13929,1331],{"class":1312},[1145,13931,13932,13934,13936,13938,13940,13943,13945,13947,13949,13951],{"class":1147,"line":1503},[1145,13933,11337],{"class":1890},[1145,13935,2247],{"class":1312},[1145,13937,13806],{"class":2214},[1145,13939,2218],{"class":1312},[1145,13941,13942],{"class":1814},"*",[1145,13944,13813],{"class":2214},[1145,13946,1900],{"class":1312},[1145,13948,3775],{"class":1814},[1145,13950,13820],{"class":2214},[1145,13952,2382],{"class":1312},[1145,13954,13955,13958,13960,13963],{"class":1147,"line":1510},[1145,13956,13957],{"class":1917},"            self",[1145,13959,2554],{"class":1312},[1145,13961,13962],{"class":2214},"on_success",[1145,13964,2722],{"class":1312},[1145,13966,13967,13969],{"class":1147,"line":1523},[1145,13968,7032],{"class":1886},[1145,13970,11387],{"class":1890},[1145,13972,13973,13975,13977,13979,13981],{"class":1147,"line":1530},[1145,13974,4605],{"class":1886},[1145,13976,3665],{"class":3664},[1145,13978,3668],{"class":1886},[1145,13980,3671],{"class":1890},[1145,13982,1331],{"class":1312},[1145,13984,13985,13987,13989,13992],{"class":1147,"line":1537},[1145,13986,13957],{"class":1917},[1145,13988,2554],{"class":1312},[1145,13990,13991],{"class":2214},"on_failure",[1145,13993,2722],{"class":1312},[1145,13995,13996,13998],{"class":1147,"line":1542},[1145,13997,5805],{"class":1886},[1145,13999,14000],{"class":1890}," exc\n",[1145,14002,14003],{"class":1147,"line":1550},[1145,14004,3300],{"class":1890},[1145,14006,14007,14009,14011,14013,14015],{"class":1147,"line":1561},[1145,14008,13159],{"class":2761},[1145,14010,13162],{"class":2739},[1145,14012,2218],{"class":1312},[1145,14014,2771],{"class":2770},[1145,14016,2774],{"class":1312},[1145,14018,14019,14021,14023,14025,14027],{"class":1147,"line":1566},[1145,14020,13715],{"class":1917},[1145,14022,2554],{"class":1312},[1145,14024,13748],{"class":2586},[1145,14026,1921],{"class":1312},[1145,14028,9852],{"class":1169},[1145,14030,14031,14033,14035,14037,14039,14041,14043],{"class":1147,"line":1574},[1145,14032,13715],{"class":1917},[1145,14034,2554],{"class":1312},[1145,14036,12973],{"class":2586},[1145,14038,1921],{"class":1312},[1145,14040,1317],{"class":1316},[1145,14042,13781],{"class":1162},[1145,14044,1323],{"class":1316},[1145,14046,14047],{"class":1147,"line":1582},[1145,14048,3300],{"class":1890},[1145,14050,14051,14053,14055,14057,14059],{"class":1147,"line":2379},[1145,14052,13159],{"class":2761},[1145,14054,13240],{"class":2739},[1145,14056,2218],{"class":1312},[1145,14058,2771],{"class":2770},[1145,14060,2774],{"class":1312},[1145,14062,14063,14065,14067,14069,14072],{"class":1147,"line":2385},[1145,14064,13715],{"class":1917},[1145,14066,2554],{"class":1312},[1145,14068,13748],{"class":2586},[1145,14070,14071],{"class":1312}," +=",[1145,14073,14074],{"class":1169}," 1\n",[1145,14076,14077,14079,14081,14083,14085,14087,14089,14091],{"class":1147,"line":2390},[1145,14078,13715],{"class":1917},[1145,14080,2554],{"class":1312},[1145,14082,13761],{"class":2586},[1145,14084,1921],{"class":1312},[1145,14086,13850],{"class":1890},[1145,14088,2554],{"class":1312},[1145,14090,13855],{"class":2214},[1145,14092,2722],{"class":1312},[1145,14094,14095],{"class":1147,"line":2396},[1145,14096,3315],{"class":1890},[1145,14098,14099,14101,14103,14105,14107,14110,14112,14114,14116],{"class":1147,"line":2410},[1145,14100,6871],{"class":1886},[1145,14102,3741],{"class":1917},[1145,14104,2554],{"class":1312},[1145,14106,13748],{"class":2586},[1145,14108,14109],{"class":1814}," >=",[1145,14111,3741],{"class":1917},[1145,14113,2554],{"class":1312},[1145,14115,13720],{"class":2586},[1145,14117,1331],{"class":1312},[1145,14119,14120,14122,14124,14126,14128,14130,14132],{"class":1147,"line":2424},[1145,14121,13957],{"class":1917},[1145,14123,2554],{"class":1312},[1145,14125,12973],{"class":2586},[1145,14127,1921],{"class":1312},[1145,14129,1317],{"class":1316},[1145,14131,13839],{"class":1162},[1145,14133,1323],{"class":1316},[1145,14135,14136],{"class":1147,"line":2438},[1145,14137,1472],{"emptyLinePlaceholder":1471},[1145,14139,14140],{"class":1147,"line":2443},[1145,14141,14142],{"class":1151},"# Usage in tasks\n",[1145,14144,14145,14148,14150,14152,14154,14156,14158,14160,14162,14164,14166,14168],{"class":1147,"line":2449},[1145,14146,14147],{"class":1890},"payment_circuit_breaker ",[1145,14149,2247],{"class":1312},[1145,14151,13676],{"class":2214},[1145,14153,2218],{"class":1312},[1145,14155,13720],{"class":2243},[1145,14157,2247],{"class":1312},[1145,14159,3264],{"class":1169},[1145,14161,1900],{"class":1312},[1145,14163,13704],{"class":2243},[1145,14165,2247],{"class":1312},[1145,14167,6820],{"class":1169},[1145,14169,2382],{"class":1312},[1145,14171,14172],{"class":1147,"line":2463},[1145,14173,1472],{"emptyLinePlaceholder":1471},[1145,14175,14176,14178,14180,14182,14184,14186,14188,14190,14192,14194,14196],{"class":1147,"line":3526},[1145,14177,2736],{"class":1312},[1145,14179,3246],{"class":2739},[1145,14181,2218],{"class":1312},[1145,14183,2749],{"class":2243},[1145,14185,2247],{"class":1312},[1145,14187,2754],{"class":2043},[1145,14189,1900],{"class":1312},[1145,14191,3259],{"class":2243},[1145,14193,2247],{"class":1312},[1145,14195,3264],{"class":1169},[1145,14197,2382],{"class":1312},[1145,14199,14200,14202,14205,14207,14209,14211,14213,14215,14218],{"class":1147,"line":3532},[1145,14201,2762],{"class":2761},[1145,14203,14204],{"class":2739}," process_payment_with_circuit_breaker",[1145,14206,2218],{"class":1312},[1145,14208,2771],{"class":2770},[1145,14210,1900],{"class":1312},[1145,14212,4847],{"class":3282},[1145,14214,1900],{"class":1312},[1145,14216,14217],{"class":3282}," amount",[1145,14219,2774],{"class":1312},[1145,14221,14222,14224,14227],{"class":1147,"line":3537},[1145,14223,2780],{"class":2779},[1145,14225,14226],{"class":2783},"Process payment with circuit breaker protection",[1145,14228,2787],{"class":2779},[1145,14230,14231,14233],{"class":1147,"line":3543},[1145,14232,3363],{"class":1886},[1145,14234,1331],{"class":1312},[1145,14236,14237,14240,14243],{"class":1147,"line":3571},[1145,14238,14239],{"class":2761},"        def",[1145,14241,14242],{"class":2739}," make_payment_call",[1145,14244,3937],{"class":1312},[1145,14246,14247,14249,14251,14253,14255,14257],{"class":1147,"line":3594},[1145,14248,4451],{"class":1890},[1145,14250,2247],{"class":1312},[1145,14252,4456],{"class":1890},[1145,14254,2554],{"class":1312},[1145,14256,4461],{"class":2214},[1145,14258,3429],{"class":1312},[1145,14260,14261,14263,14265,14267],{"class":1147,"line":3599},[1145,14262,5549],{"class":1316},[1145,14264,6668],{"class":1162},[1145,14266,1966],{"class":1316},[1145,14268,3446],{"class":1312},[1145,14270,14271,14273,14275,14277,14279,14281,14283,14285,14287,14289,14291,14293,14295,14297],{"class":1147,"line":3614},[1145,14272,4477],{"class":2243},[1145,14274,4509],{"class":1312},[1145,14276,1966],{"class":1316},[1145,14278,4927],{"class":1162},[1145,14280,1966],{"class":1316},[1145,14282,1313],{"class":1312},[1145,14284,4847],{"class":2214},[1145,14286,1900],{"class":1312},[1145,14288,1317],{"class":1316},[1145,14290,6702],{"class":1162},[1145,14292,1966],{"class":1316},[1145,14294,1313],{"class":1312},[1145,14296,14217],{"class":2214},[1145,14298,14299],{"class":1312},"},\n",[1145,14301,14302,14304,14306],{"class":1147,"line":3620},[1145,14303,4490],{"class":2243},[1145,14305,2247],{"class":1312},[1145,14307,5616],{"class":1169},[1145,14309,14310],{"class":1147,"line":3648},[1145,14311,4533],{"class":1312},[1145,14313,14314,14316,14318,14320],{"class":1147,"line":3654},[1145,14315,4539],{"class":1890},[1145,14317,2554],{"class":1312},[1145,14319,4544],{"class":2214},[1145,14321,2722],{"class":1312},[1145,14323,14324,14326,14328,14330,14332],{"class":1147,"line":3659},[1145,14325,7032],{"class":1886},[1145,14327,5644],{"class":1890},[1145,14329,2554],{"class":1312},[1145,14331,1963],{"class":2214},[1145,14333,2722],{"class":1312},[1145,14335,14336],{"class":1147,"line":3676},[1145,14337,3315],{"class":1890},[1145,14339,14340,14342,14344,14347,14349,14352,14354,14357],{"class":1147,"line":3682},[1145,14341,5091],{"class":1890},[1145,14343,2247],{"class":1312},[1145,14345,14346],{"class":1890}," payment_circuit_breaker",[1145,14348,2554],{"class":1312},[1145,14350,14351],{"class":2214},"call",[1145,14353,2218],{"class":1312},[1145,14355,14356],{"class":2214},"make_payment_call",[1145,14358,2382],{"class":1312},[1145,14360,14361,14363],{"class":1147,"line":3718},[1145,14362,3574],{"class":1886},[1145,14364,11387],{"class":1890},[1145,14366,14367],{"class":1147,"line":3723},[1145,14368,3315],{"class":1890},[1145,14370,14371,14373,14375,14377,14379],{"class":1147,"line":3729},[1145,14372,3602],{"class":1886},[1145,14374,3665],{"class":3664},[1145,14376,3668],{"class":1886},[1145,14378,3671],{"class":1890},[1145,14380,1331],{"class":1312},[1145,14382,14383,14385,14387,14389,14391,14393,14396,14398,14400,14402,14404],{"class":1147,"line":3735},[1145,14384,3546],{"class":1890},[1145,14386,2554],{"class":1312},[1145,14388,3627],{"class":2214},[1145,14390,2218],{"class":1312},[1145,14392,2798],{"class":2761},[1145,14394,14395],{"class":1162},"\"Payment processing failed: ",[1145,14397,2805],{"class":2804},[1145,14399,3709],{"class":2214},[1145,14401,2818],{"class":2804},[1145,14403,1382],{"class":1162},[1145,14405,2382],{"class":1312},[1145,14407,14408,14410,14412,14414,14416,14418,14420,14422,14424,14426,14428,14430,14432],{"class":1147,"line":3792},[1145,14409,3738],{"class":1886},[1145,14411,3741],{"class":1917},[1145,14413,2554],{"class":1312},[1145,14415,3746],{"class":2214},[1145,14417,2218],{"class":1312},[1145,14419,3709],{"class":2243},[1145,14421,2247],{"class":1312},[1145,14423,3709],{"class":2214},[1145,14425,1900],{"class":1312},[1145,14427,3759],{"class":2243},[1145,14429,2247],{"class":1312},[1145,14431,3764],{"class":1169},[1145,14433,2382],{"class":1312},[1030,14435,14437],{"id":14436},"deployment-and-scaling","Deployment and Scaling",[1246,14439,14441],{"id":14440},"docker-configuration","Docker Configuration",[1135,14443,14447],{"className":14444,"code":14445,"language":14446,"meta":1140,"style":1140},"language-dockerfile shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","# Dockerfile for Celery worker\nFROM python:3.11-slim\n\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\n# Create celery user\nRUN adduser --disabled-password --gecos '' celery\n\nUSER celery\n\nCMD [\"celery\", \"-A\", \"user_service\", \"worker\", \"--loglevel=info\", \"--concurrency=4\"]\n","dockerfile",[1142,14448,14449,14454,14463,14467,14475,14479,14487,14495,14499,14506,14510,14515,14528,14532,14539,14543],{"__ignoreMap":1140},[1145,14450,14451],{"class":1147,"line":1148},[1145,14452,14453],{"class":1151},"# Dockerfile for Celery worker\n",[1145,14455,14456,14460],{"class":1147,"line":1155},[1145,14457,14459],{"class":14458},"scgAs","FROM",[1145,14461,14462],{"class":1890}," python:3.11-slim\n",[1145,14464,14465],{"class":1147,"line":1173},[1145,14466,1472],{"emptyLinePlaceholder":1471},[1145,14468,14469,14472],{"class":1147,"line":1186},[1145,14470,14471],{"class":14458},"WORKDIR",[1145,14473,14474],{"class":1890}," /app\n",[1145,14476,14477],{"class":1147,"line":1199},[1145,14478,1472],{"emptyLinePlaceholder":1471},[1145,14480,14481,14484],{"class":1147,"line":1351},[1145,14482,14483],{"class":14458},"COPY",[1145,14485,14486],{"class":1890}," requirements.txt .\n",[1145,14488,14489,14492],{"class":1147,"line":1362},[1145,14490,14491],{"class":14458},"RUN",[1145,14493,14494],{"class":1890}," pip install --no-cache-dir -r requirements.txt\n",[1145,14496,14497],{"class":1147,"line":1370},[1145,14498,1472],{"emptyLinePlaceholder":1471},[1145,14500,14501,14503],{"class":1147,"line":1388},[1145,14502,14483],{"class":14458},[1145,14504,14505],{"class":1890}," . .\n",[1145,14507,14508],{"class":1147,"line":1403},[1145,14509,1472],{"emptyLinePlaceholder":1471},[1145,14511,14512],{"class":1147,"line":1411},[1145,14513,14514],{"class":1151},"# Create celery user\n",[1145,14516,14517,14519,14522,14525],{"class":1147,"line":1422},[1145,14518,14491],{"class":14458},[1145,14520,14521],{"class":1890}," adduser --disabled-password --gecos ",[1145,14523,14524],{"class":1162},"''",[1145,14526,14527],{"class":1890}," celery\n",[1145,14529,14530],{"class":1147,"line":1433},[1145,14531,1472],{"emptyLinePlaceholder":1471},[1145,14533,14534,14537],{"class":1147,"line":1441},[1145,14535,14536],{"class":14458},"USER",[1145,14538,14527],{"class":1890},[1145,14540,14541],{"class":1147,"line":1452},[1145,14542,1472],{"emptyLinePlaceholder":1471},[1145,14544,14545,14548,14550,14553,14556,14559,14561,14564,14566,14569,14571,14574,14576,14579],{"class":1147,"line":1460},[1145,14546,14547],{"class":14458},"CMD",[1145,14549,1995],{"class":1890},[1145,14551,14552],{"class":1162},"\"celery\"",[1145,14554,14555],{"class":1890},", ",[1145,14557,14558],{"class":1162},"\"-A\"",[1145,14560,14555],{"class":1890},[1145,14562,14563],{"class":1162},"\"user_service\"",[1145,14565,14555],{"class":1890},[1145,14567,14568],{"class":1162},"\"worker\"",[1145,14570,14555],{"class":1890},[1145,14572,14573],{"class":1162},"\"--loglevel=info\"",[1145,14575,14555],{"class":1890},[1145,14577,14578],{"class":1162},"\"--concurrency=4\"",[1145,14580,8627],{"class":1890},[1246,14582,14584],{"id":14583},"docker-compose-for-complete-setup","Docker Compose for Complete Setup",[1135,14586,14588],{"className":1294,"code":14587,"language":1296,"meta":1140,"style":1140},"# docker-compose.yml for microservices with Celery\nversion: '3.8'\n\nservices:\n  rabbitmq:\n    image: rabbitmq:3.11-management\n    environment:\n      RABBITMQ_DEFAULT_USER: admin\n      RABBITMQ_DEFAULT_PASS: password123\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    volumes:\n      - rabbitmq_data:/var/lib/rabbitmq\n\n  redis:\n    image: redis:7-alpine\n    ports:\n      - \"6379:6379\"\n\n  user-service:\n    build: ./user_service\n    ports:\n      - \"8000:8000\"\n    depends_on:\n      - rabbitmq\n      - redis\n    environment:\n      - CELERY_BROKER_URL=amqp://admin:password123@rabbitmq:5672//\n      - CELERY_RESULT_BACKEND=redis://redis:6379/0\n\n  user-worker:\n    build: ./user_service\n    command: celery -A user_service worker --loglevel=info --concurrency=4 -Q user_queue\n    depends_on:\n      - rabbitmq\n      - redis\n    environment:\n      - CELERY_BROKER_URL=amqp://admin:password123@rabbitmq:5672//\n      - CELERY_RESULT_BACKEND=redis://redis:6379/0\n\n  order-service:\n    build: ./order_service\n    ports:\n      - \"8001:8000\"\n    depends_on:\n      - rabbitmq\n      - redis\n\n  order-worker:\n    build: ./order_service\n    command: celery -A order_service worker --loglevel=info --concurrency=2 -Q order_queue\n    depends_on:\n      - rabbitmq\n      - redis\n\n  celery-beat:\n    build: ./user_service\n    command: celery -A user_service beat --loglevel=info\n    depends_on:\n      - rabbitmq\n      - redis\n    environment:\n      - CELERY_BROKER_URL=amqp://admin:password123@rabbitmq:5672//\n\n  flower:\n    build: ./user_service\n    command: celery -A user_service flower --port=5555\n    ports:\n      - \"5555:5555\"\n    depends_on:\n      - rabbitmq\n      - redis\n    environment:\n      - CELERY_BROKER_URL=amqp://admin:password123@rabbitmq:5672//\n\nvolumes:\n  rabbitmq_data:\n",[1142,14589,14590,14595,14607,14611,14617,14623,14631,14637,14645,14653,14659,14669,14679,14685,14692,14696,14702,14710,14716,14726,14730,14737,14747,14753,14764,14771,14777,14784,14790,14797,14804,14808,14815,14823,14833,14839,14845,14851,14857,14863,14869,14873,14880,14889,14895,14906,14912,14918,14924,14928,14935,14943,14952,14958,14964,14970,14974,14981,14989,14998,15004,15010,15016,15022,15028,15032,15039,15047,15056,15062,15073,15079,15085,15091,15097,15103,15107,15113],{"__ignoreMap":1140},[1145,14591,14592],{"class":1147,"line":1148},[1145,14593,14594],{"class":1151},"# docker-compose.yml for microservices with Celery\n",[1145,14596,14597,14599,14601,14603,14605],{"class":1147,"line":1155},[1145,14598,1309],{"class":1308},[1145,14600,1313],{"class":1312},[1145,14602,1317],{"class":1316},[1145,14604,1320],{"class":1162},[1145,14606,1323],{"class":1316},[1145,14608,14609],{"class":1147,"line":1173},[1145,14610,1472],{"emptyLinePlaceholder":1471},[1145,14612,14613,14615],{"class":1147,"line":1186},[1145,14614,1328],{"class":1308},[1145,14616,1331],{"class":1312},[1145,14618,14619,14621],{"class":1147,"line":1199},[1145,14620,1336],{"class":1308},[1145,14622,1331],{"class":1312},[1145,14624,14625,14627,14629],{"class":1147,"line":1351},[1145,14626,1343],{"class":1308},[1145,14628,1313],{"class":1312},[1145,14630,1348],{"class":1162},[1145,14632,14633,14635],{"class":1147,"line":1362},[1145,14634,1406],{"class":1308},[1145,14636,1331],{"class":1312},[1145,14638,14639,14641,14643],{"class":1147,"line":1370},[1145,14640,1414],{"class":1308},[1145,14642,1313],{"class":1312},[1145,14644,1419],{"class":1162},[1145,14646,14647,14649,14651],{"class":1147,"line":1388},[1145,14648,1425],{"class":1308},[1145,14650,1313],{"class":1312},[1145,14652,1430],{"class":1162},[1145,14654,14655,14657],{"class":1147,"line":1403},[1145,14656,1365],{"class":1308},[1145,14658,1331],{"class":1312},[1145,14660,14661,14663,14665,14667],{"class":1147,"line":1411},[1145,14662,1373],{"class":1312},[1145,14664,1376],{"class":1316},[1145,14666,1379],{"class":1162},[1145,14668,1520],{"class":1316},[1145,14670,14671,14673,14675,14677],{"class":1147,"line":1422},[1145,14672,1373],{"class":1312},[1145,14674,1376],{"class":1316},[1145,14676,1395],{"class":1162},[1145,14678,1520],{"class":1316},[1145,14680,14681,14683],{"class":1147,"line":1433},[1145,14682,1436],{"class":1308},[1145,14684,1331],{"class":1312},[1145,14686,14687,14689],{"class":1147,"line":1441},[1145,14688,1373],{"class":1312},[1145,14690,14691],{"class":1162}," rabbitmq_data:/var/lib/rabbitmq\n",[1145,14693,14694],{"class":1147,"line":1452},[1145,14695,1472],{"emptyLinePlaceholder":1471},[1145,14697,14698,14700],{"class":1147,"line":1460},[1145,14699,1478],{"class":1308},[1145,14701,1331],{"class":1312},[1145,14703,14704,14706,14708],{"class":1147,"line":1468},[1145,14705,1343],{"class":1308},[1145,14707,1313],{"class":1312},[1145,14709,1490],{"class":1162},[1145,14711,14712,14714],{"class":1147,"line":1475},[1145,14713,1365],{"class":1308},[1145,14715,1331],{"class":1312},[1145,14717,14718,14720,14722,14724],{"class":1147,"line":1483},[1145,14719,1373],{"class":1312},[1145,14721,1376],{"class":1316},[1145,14723,1517],{"class":1162},[1145,14725,1520],{"class":1316},[1145,14727,14728],{"class":1147,"line":1493},[1145,14729,1472],{"emptyLinePlaceholder":1471},[1145,14731,14732,14735],{"class":1147,"line":1503},[1145,14733,14734],{"class":1308},"  user-service",[1145,14736,1331],{"class":1312},[1145,14738,14739,14742,14744],{"class":1147,"line":1510},[1145,14740,14741],{"class":1308},"    build",[1145,14743,1313],{"class":1312},[1145,14745,14746],{"class":1162}," ./user_service\n",[1145,14748,14749,14751],{"class":1147,"line":1523},[1145,14750,1365],{"class":1308},[1145,14752,1331],{"class":1312},[1145,14754,14755,14757,14759,14762],{"class":1147,"line":1530},[1145,14756,1373],{"class":1312},[1145,14758,1376],{"class":1316},[1145,14760,14761],{"class":1162},"8000:8000",[1145,14763,1520],{"class":1316},[1145,14765,14766,14769],{"class":1147,"line":1537},[1145,14767,14768],{"class":1308},"    depends_on",[1145,14770,1331],{"class":1312},[1145,14772,14773,14775],{"class":1147,"line":1542},[1145,14774,1373],{"class":1312},[1145,14776,1690],{"class":1162},[1145,14778,14779,14781],{"class":1147,"line":1550},[1145,14780,1373],{"class":1312},[1145,14782,14783],{"class":1162}," redis\n",[1145,14785,14786,14788],{"class":1147,"line":1561},[1145,14787,1406],{"class":1308},[1145,14789,1331],{"class":1312},[1145,14791,14792,14794],{"class":1147,"line":1566},[1145,14793,1373],{"class":1312},[1145,14795,14796],{"class":1162}," CELERY_BROKER_URL=amqp://admin:password123@rabbitmq:5672//\n",[1145,14798,14799,14801],{"class":1147,"line":1574},[1145,14800,1373],{"class":1312},[1145,14802,14803],{"class":1162}," CELERY_RESULT_BACKEND=redis://redis:6379/0\n",[1145,14805,14806],{"class":1147,"line":1582},[1145,14807,1472],{"emptyLinePlaceholder":1471},[1145,14809,14810,14813],{"class":1147,"line":2379},[1145,14811,14812],{"class":1308},"  user-worker",[1145,14814,1331],{"class":1312},[1145,14816,14817,14819,14821],{"class":1147,"line":2385},[1145,14818,14741],{"class":1308},[1145,14820,1313],{"class":1312},[1145,14822,14746],{"class":1162},[1145,14824,14825,14828,14830],{"class":1147,"line":2390},[1145,14826,14827],{"class":1308},"    command",[1145,14829,1313],{"class":1312},[1145,14831,14832],{"class":1162}," celery -A user_service worker --loglevel=info --concurrency=4 -Q user_queue\n",[1145,14834,14835,14837],{"class":1147,"line":2396},[1145,14836,14768],{"class":1308},[1145,14838,1331],{"class":1312},[1145,14840,14841,14843],{"class":1147,"line":2410},[1145,14842,1373],{"class":1312},[1145,14844,1690],{"class":1162},[1145,14846,14847,14849],{"class":1147,"line":2424},[1145,14848,1373],{"class":1312},[1145,14850,14783],{"class":1162},[1145,14852,14853,14855],{"class":1147,"line":2438},[1145,14854,1406],{"class":1308},[1145,14856,1331],{"class":1312},[1145,14858,14859,14861],{"class":1147,"line":2443},[1145,14860,1373],{"class":1312},[1145,14862,14796],{"class":1162},[1145,14864,14865,14867],{"class":1147,"line":2449},[1145,14866,1373],{"class":1312},[1145,14868,14803],{"class":1162},[1145,14870,14871],{"class":1147,"line":2463},[1145,14872,1472],{"emptyLinePlaceholder":1471},[1145,14874,14875,14878],{"class":1147,"line":3526},[1145,14876,14877],{"class":1308},"  order-service",[1145,14879,1331],{"class":1312},[1145,14881,14882,14884,14886],{"class":1147,"line":3532},[1145,14883,14741],{"class":1308},[1145,14885,1313],{"class":1312},[1145,14887,14888],{"class":1162}," ./order_service\n",[1145,14890,14891,14893],{"class":1147,"line":3537},[1145,14892,1365],{"class":1308},[1145,14894,1331],{"class":1312},[1145,14896,14897,14899,14901,14904],{"class":1147,"line":3543},[1145,14898,1373],{"class":1312},[1145,14900,1376],{"class":1316},[1145,14902,14903],{"class":1162},"8001:8000",[1145,14905,1520],{"class":1316},[1145,14907,14908,14910],{"class":1147,"line":3571},[1145,14909,14768],{"class":1308},[1145,14911,1331],{"class":1312},[1145,14913,14914,14916],{"class":1147,"line":3594},[1145,14915,1373],{"class":1312},[1145,14917,1690],{"class":1162},[1145,14919,14920,14922],{"class":1147,"line":3599},[1145,14921,1373],{"class":1312},[1145,14923,14783],{"class":1162},[1145,14925,14926],{"class":1147,"line":3614},[1145,14927,1472],{"emptyLinePlaceholder":1471},[1145,14929,14930,14933],{"class":1147,"line":3620},[1145,14931,14932],{"class":1308},"  order-worker",[1145,14934,1331],{"class":1312},[1145,14936,14937,14939,14941],{"class":1147,"line":3648},[1145,14938,14741],{"class":1308},[1145,14940,1313],{"class":1312},[1145,14942,14888],{"class":1162},[1145,14944,14945,14947,14949],{"class":1147,"line":3654},[1145,14946,14827],{"class":1308},[1145,14948,1313],{"class":1312},[1145,14950,14951],{"class":1162}," celery -A order_service worker --loglevel=info --concurrency=2 -Q order_queue\n",[1145,14953,14954,14956],{"class":1147,"line":3659},[1145,14955,14768],{"class":1308},[1145,14957,1331],{"class":1312},[1145,14959,14960,14962],{"class":1147,"line":3676},[1145,14961,1373],{"class":1312},[1145,14963,1690],{"class":1162},[1145,14965,14966,14968],{"class":1147,"line":3682},[1145,14967,1373],{"class":1312},[1145,14969,14783],{"class":1162},[1145,14971,14972],{"class":1147,"line":3718},[1145,14973,1472],{"emptyLinePlaceholder":1471},[1145,14975,14976,14979],{"class":1147,"line":3723},[1145,14977,14978],{"class":1308},"  celery-beat",[1145,14980,1331],{"class":1312},[1145,14982,14983,14985,14987],{"class":1147,"line":3729},[1145,14984,14741],{"class":1308},[1145,14986,1313],{"class":1312},[1145,14988,14746],{"class":1162},[1145,14990,14991,14993,14995],{"class":1147,"line":3735},[1145,14992,14827],{"class":1308},[1145,14994,1313],{"class":1312},[1145,14996,14997],{"class":1162}," celery -A user_service beat --loglevel=info\n",[1145,14999,15000,15002],{"class":1147,"line":3792},[1145,15001,14768],{"class":1308},[1145,15003,1331],{"class":1312},[1145,15005,15006,15008],{"class":1147,"line":3797},[1145,15007,1373],{"class":1312},[1145,15009,1690],{"class":1162},[1145,15011,15012,15014],{"class":1147,"line":3805},[1145,15013,1373],{"class":1312},[1145,15015,14783],{"class":1162},[1145,15017,15018,15020],{"class":1147,"line":3824},[1145,15019,1406],{"class":1308},[1145,15021,1331],{"class":1312},[1145,15023,15024,15026],{"class":1147,"line":3829},[1145,15025,1373],{"class":1312},[1145,15027,14796],{"class":1162},[1145,15029,15030],{"class":1147,"line":3835},[1145,15031,1472],{"emptyLinePlaceholder":1471},[1145,15033,15034,15037],{"class":1147,"line":3840},[1145,15035,15036],{"class":1308},"  flower",[1145,15038,1331],{"class":1312},[1145,15040,15041,15043,15045],{"class":1147,"line":3845},[1145,15042,14741],{"class":1308},[1145,15044,1313],{"class":1312},[1145,15046,14746],{"class":1162},[1145,15048,15049,15051,15053],{"class":1147,"line":3851},[1145,15050,14827],{"class":1308},[1145,15052,1313],{"class":1312},[1145,15054,15055],{"class":1162}," celery -A user_service flower --port=5555\n",[1145,15057,15058,15060],{"class":1147,"line":3857},[1145,15059,1365],{"class":1308},[1145,15061,1331],{"class":1312},[1145,15063,15064,15066,15068,15071],{"class":1147,"line":3863},[1145,15065,1373],{"class":1312},[1145,15067,1376],{"class":1316},[1145,15069,15070],{"class":1162},"5555:5555",[1145,15072,1520],{"class":1316},[1145,15074,15075,15077],{"class":1147,"line":3868},[1145,15076,14768],{"class":1308},[1145,15078,1331],{"class":1312},[1145,15080,15081,15083],{"class":1147,"line":3875},[1145,15082,1373],{"class":1312},[1145,15084,1690],{"class":1162},[1145,15086,15087,15089],{"class":1147,"line":3902},[1145,15088,1373],{"class":1312},[1145,15090,14783],{"class":1162},[1145,15092,15093,15095],{"class":1147,"line":3907},[1145,15094,1406],{"class":1308},[1145,15096,1331],{"class":1312},[1145,15098,15099,15101],{"class":1147,"line":3913},[1145,15100,1373],{"class":1312},[1145,15102,14796],{"class":1162},[1145,15104,15105],{"class":1147,"line":3940},[1145,15106,1472],{"emptyLinePlaceholder":1471},[1145,15108,15109,15111],{"class":1147,"line":3959},[1145,15110,1545],{"class":1308},[1145,15112,1331],{"class":1312},[1145,15114,15115,15117],{"class":1147,"line":3980},[1145,15116,1553],{"class":1308},[1145,15118,1331],{"class":1312},[1030,15120,15122],{"id":15121},"best-practices-and-troubleshooting","Best Practices and Troubleshooting",[1246,15124,15126],{"id":15125},"performance-optimization","Performance Optimization",[1135,15128,15130],{"className":1872,"code":15129,"language":1874,"meta":1140,"style":1140},"# Optimized task configuration\n@shared_task(\n    bind=True,\n    max_retries=3,\n    default_retry_delay=60,\n    rate_limit='100/m',  # 100 tasks per minute\n    time_limit=300,      # 5 minutes hard limit\n    soft_time_limit=240, # 4 minutes soft limit\n)\ndef optimized_task(self, data):\n    \"\"\"Example of well-configured task\"\"\"\n    pass\n\n# Batch processing for efficiency\n@shared_task\ndef process_batch_emails(email_batch):\n    \"\"\"Process emails in batches for better performance\"\"\"\n    from django.core.mail import send_mass_mail\n    \n    messages = []\n    for email_data in email_batch:\n        message = (\n            email_data['subject'],\n            email_data['body'],\n            'noreply@example.com',\n            [email_data['recipient']]\n        )\n        messages.append(message)\n    \n    send_mass_mail(messages, fail_silently=False)\n    return f\"Sent {len(messages)} emails\"\n\n# Chunking large datasets\nfrom celery import group\n\n@shared_task\ndef process_large_dataset(dataset_id, chunk_size=100):\n    \"\"\"Process large datasets in chunks\"\"\"\n    dataset = get_dataset(dataset_id)\n    total_items = dataset.count()\n    \n    # Create chunks\n    chunks = []\n    for i in range(0, total_items, chunk_size):\n        chunk_data = list(dataset[i:i + chunk_size])\n        chunks.append(process_chunk.s(chunk_data))\n    \n    # Process chunks in parallel\n    job = group(chunks)\n    result = job.apply_async()\n    \n    return f\"Processing {len(chunks)} chunks\"\n\n@shared_task\ndef process_chunk(chunk_data):\n    \"\"\"Process a single chunk of data\"\"\"\n    results = []\n    for item in chunk_data:\n        result = process_single_item(item)\n        results.append(result)\n    return results\n",[1142,15131,15132,15137,15145,15156,15167,15178,15197,15212,15227,15231,15248,15257,15262,15266,15271,15277,15291,15300,15320,15324,15333,15347,15356,15372,15387,15397,15416,15420,15436,15440,15461,15486,15490,15495,15506,15510,15516,15540,15549,15565,15582,15586,15591,15600,15628,15660,15685,15689,15694,15710,15725,15729,15753,15757,15763,15776,15785,15794,15807,15822,15837],{"__ignoreMap":1140},[1145,15133,15134],{"class":1147,"line":1148},[1145,15135,15136],{"class":1151},"# Optimized task configuration\n",[1145,15138,15139,15141,15143],{"class":1147,"line":1155},[1145,15140,2736],{"class":1312},[1145,15142,3246],{"class":2739},[1145,15144,3429],{"class":1312},[1145,15146,15147,15150,15152,15154],{"class":1147,"line":1173},[1145,15148,15149],{"class":2243},"    bind",[1145,15151,2247],{"class":1312},[1145,15153,2754],{"class":2043},[1145,15155,3446],{"class":1312},[1145,15157,15158,15161,15163,15165],{"class":1147,"line":1186},[1145,15159,15160],{"class":2243},"    max_retries",[1145,15162,2247],{"class":1312},[1145,15164,3264],{"class":1169},[1145,15166,3446],{"class":1312},[1145,15168,15169,15172,15174,15176],{"class":1147,"line":1199},[1145,15170,15171],{"class":2243},"    default_retry_delay",[1145,15173,2247],{"class":1312},[1145,15175,3764],{"class":1169},[1145,15177,3446],{"class":1312},[1145,15179,15180,15183,15185,15187,15190,15192,15194],{"class":1147,"line":1351},[1145,15181,15182],{"class":2243},"    rate_limit",[1145,15184,2247],{"class":1312},[1145,15186,1966],{"class":1316},[1145,15188,15189],{"class":1162},"100/m",[1145,15191,1966],{"class":1316},[1145,15193,1900],{"class":1312},[1145,15195,15196],{"class":1151},"  # 100 tasks per minute\n",[1145,15198,15199,15202,15204,15207,15209],{"class":1147,"line":1362},[1145,15200,15201],{"class":2243},"    time_limit",[1145,15203,2247],{"class":1312},[1145,15205,15206],{"class":1169},"300",[1145,15208,1900],{"class":1312},[1145,15210,15211],{"class":1151},"      # 5 minutes hard limit\n",[1145,15213,15214,15217,15219,15222,15224],{"class":1147,"line":1370},[1145,15215,15216],{"class":2243},"    soft_time_limit",[1145,15218,2247],{"class":1312},[1145,15220,15221],{"class":1169},"240",[1145,15223,1900],{"class":1312},[1145,15225,15226],{"class":1151}," # 4 minutes soft limit\n",[1145,15228,15229],{"class":1147,"line":1388},[1145,15230,2382],{"class":1312},[1145,15232,15233,15235,15238,15240,15242,15244,15246],{"class":1147,"line":1403},[1145,15234,2762],{"class":2761},[1145,15236,15237],{"class":2739}," optimized_task",[1145,15239,2218],{"class":1312},[1145,15241,2771],{"class":2770},[1145,15243,1900],{"class":1312},[1145,15245,10271],{"class":3282},[1145,15247,2774],{"class":1312},[1145,15249,15250,15252,15255],{"class":1147,"line":1411},[1145,15251,2780],{"class":2779},[1145,15253,15254],{"class":2783},"Example of well-configured task",[1145,15256,2787],{"class":2779},[1145,15258,15259],{"class":1147,"line":1422},[1145,15260,15261],{"class":1886},"    pass\n",[1145,15263,15264],{"class":1147,"line":1433},[1145,15265,1472],{"emptyLinePlaceholder":1471},[1145,15267,15268],{"class":1147,"line":1441},[1145,15269,15270],{"class":1151},"# Batch processing for efficiency\n",[1145,15272,15273,15275],{"class":1147,"line":1452},[1145,15274,2736],{"class":1312},[1145,15276,3802],{"class":2739},[1145,15278,15279,15281,15284,15286,15289],{"class":1147,"line":1460},[1145,15280,2762],{"class":2761},[1145,15282,15283],{"class":2739}," process_batch_emails",[1145,15285,2218],{"class":1312},[1145,15287,15288],{"class":3282},"email_batch",[1145,15290,2774],{"class":1312},[1145,15292,15293,15295,15298],{"class":1147,"line":1468},[1145,15294,2780],{"class":2779},[1145,15296,15297],{"class":2783},"Process emails in batches for better performance",[1145,15299,2787],{"class":2779},[1145,15301,15302,15305,15307,15309,15311,15313,15315,15317],{"class":1147,"line":1475},[1145,15303,15304],{"class":1886},"    from",[1145,15306,2551],{"class":1890},[1145,15308,2554],{"class":1312},[1145,15310,3138],{"class":1890},[1145,15312,2554],{"class":1312},[1145,15314,3143],{"class":1890},[1145,15316,1894],{"class":1886},[1145,15318,15319],{"class":1890}," send_mass_mail\n",[1145,15321,15322],{"class":1147,"line":1483},[1145,15323,3300],{"class":1890},[1145,15325,15326,15329,15331],{"class":1147,"line":1493},[1145,15327,15328],{"class":1890},"    messages ",[1145,15330,2247],{"class":1312},[1145,15332,9155],{"class":1312},[1145,15334,15335,15337,15340,15342,15345],{"class":1147,"line":1503},[1145,15336,4427],{"class":1886},[1145,15338,15339],{"class":1890}," email_data ",[1145,15341,3927],{"class":1886},[1145,15343,15344],{"class":1890}," email_batch",[1145,15346,1331],{"class":1312},[1145,15348,15349,15352,15354],{"class":1147,"line":1510},[1145,15350,15351],{"class":1890},"        message ",[1145,15353,2247],{"class":1312},[1145,15355,2209],{"class":1312},[1145,15357,15358,15361,15363,15365,15368,15370],{"class":1147,"line":1523},[1145,15359,15360],{"class":1890},"            email_data",[1145,15362,8618],{"class":1312},[1145,15364,1966],{"class":1316},[1145,15366,15367],{"class":1162},"subject",[1145,15369,1966],{"class":1316},[1145,15371,3508],{"class":1312},[1145,15373,15374,15376,15378,15380,15383,15385],{"class":1147,"line":1530},[1145,15375,15360],{"class":1890},[1145,15377,8618],{"class":1312},[1145,15379,1966],{"class":1316},[1145,15381,15382],{"class":1162},"body",[1145,15384,1966],{"class":1316},[1145,15386,3508],{"class":1312},[1145,15388,15389,15391,15393,15395],{"class":1147,"line":1537},[1145,15390,6012],{"class":1316},[1145,15392,3486],{"class":1162},[1145,15394,1966],{"class":1316},[1145,15396,3446],{"class":1312},[1145,15398,15399,15401,15404,15406,15408,15411,15413],{"class":1147,"line":1542},[1145,15400,7665],{"class":1312},[1145,15402,15403],{"class":1890},"email_data",[1145,15405,8618],{"class":1312},[1145,15407,1966],{"class":1316},[1145,15409,15410],{"class":1162},"recipient",[1145,15412,1966],{"class":1316},[1145,15414,15415],{"class":1312},"]]\n",[1145,15417,15418],{"class":1147,"line":1550},[1145,15419,3529],{"class":1312},[1145,15421,15422,15425,15427,15429,15431,15434],{"class":1147,"line":1561},[1145,15423,15424],{"class":1890},"        messages",[1145,15426,2554],{"class":1312},[1145,15428,9329],{"class":2214},[1145,15430,2218],{"class":1312},[1145,15432,15433],{"class":2214},"message",[1145,15435,2382],{"class":1312},[1145,15437,15438],{"class":1147,"line":1566},[1145,15439,3300],{"class":1890},[1145,15441,15442,15445,15447,15450,15452,15455,15457,15459],{"class":1147,"line":1574},[1145,15443,15444],{"class":2214},"    send_mass_mail",[1145,15446,2218],{"class":1312},[1145,15448,15449],{"class":2214},"messages",[1145,15451,1900],{"class":1312},[1145,15453,15454],{"class":2243}," fail_silently",[1145,15456,2247],{"class":1312},[1145,15458,3518],{"class":2043},[1145,15460,2382],{"class":1312},[1145,15462,15463,15465,15467,15470,15472,15475,15477,15479,15481,15483],{"class":1147,"line":1582},[1145,15464,2827],{"class":1886},[1145,15466,2830],{"class":2761},[1145,15468,15469],{"class":1162},"\"Sent ",[1145,15471,2805],{"class":2804},[1145,15473,15474],{"class":2792},"len",[1145,15476,2218],{"class":1312},[1145,15478,15449],{"class":2214},[1145,15480,1623],{"class":1312},[1145,15482,2818],{"class":2804},[1145,15484,15485],{"class":1162}," emails\"\n",[1145,15487,15488],{"class":1147,"line":2379},[1145,15489,1472],{"emptyLinePlaceholder":1471},[1145,15491,15492],{"class":1147,"line":2385},[1145,15493,15494],{"class":1151},"# Chunking large datasets\n",[1145,15496,15497,15499,15501,15503],{"class":1147,"line":2390},[1145,15498,1887],{"class":1886},[1145,15500,2539],{"class":1890},[1145,15502,1894],{"class":1886},[1145,15504,15505],{"class":1890}," group\n",[1145,15507,15508],{"class":1147,"line":2396},[1145,15509,1472],{"emptyLinePlaceholder":1471},[1145,15511,15512,15514],{"class":1147,"line":2410},[1145,15513,2736],{"class":1312},[1145,15515,3802],{"class":2739},[1145,15517,15518,15520,15523,15525,15528,15530,15533,15535,15538],{"class":1147,"line":2424},[1145,15519,2762],{"class":2761},[1145,15521,15522],{"class":2739}," process_large_dataset",[1145,15524,2218],{"class":1312},[1145,15526,15527],{"class":3282},"dataset_id",[1145,15529,1900],{"class":1312},[1145,15531,15532],{"class":3282}," chunk_size",[1145,15534,2247],{"class":1814},[1145,15536,15537],{"class":1169},"100",[1145,15539,2774],{"class":1312},[1145,15541,15542,15544,15547],{"class":1147,"line":2438},[1145,15543,2780],{"class":2779},[1145,15545,15546],{"class":2783},"Process large datasets in chunks",[1145,15548,2787],{"class":2779},[1145,15550,15551,15554,15556,15559,15561,15563],{"class":1147,"line":2443},[1145,15552,15553],{"class":1890},"    dataset ",[1145,15555,2247],{"class":1312},[1145,15557,15558],{"class":2214}," get_dataset",[1145,15560,2218],{"class":1312},[1145,15562,15527],{"class":2214},[1145,15564,2382],{"class":1312},[1145,15566,15567,15570,15572,15575,15577,15580],{"class":1147,"line":2449},[1145,15568,15569],{"class":1890},"    total_items ",[1145,15571,2247],{"class":1312},[1145,15573,15574],{"class":1890}," dataset",[1145,15576,2554],{"class":1312},[1145,15578,15579],{"class":2214},"count",[1145,15581,2722],{"class":1312},[1145,15583,15584],{"class":1147,"line":2463},[1145,15585,3300],{"class":1890},[1145,15587,15588],{"class":1147,"line":3526},[1145,15589,15590],{"class":1151},"    # Create chunks\n",[1145,15592,15593,15596,15598],{"class":1147,"line":3532},[1145,15594,15595],{"class":1890},"    chunks ",[1145,15597,2247],{"class":1312},[1145,15599,9155],{"class":1312},[1145,15601,15602,15604,15607,15609,15612,15614,15617,15619,15622,15624,15626],{"class":1147,"line":3537},[1145,15603,4427],{"class":1886},[1145,15605,15606],{"class":1890}," i ",[1145,15608,3927],{"class":1886},[1145,15610,15611],{"class":2792}," range",[1145,15613,2218],{"class":1312},[1145,15615,15616],{"class":1169},"0",[1145,15618,1900],{"class":1312},[1145,15620,15621],{"class":2214}," total_items",[1145,15623,1900],{"class":1312},[1145,15625,15532],{"class":2214},[1145,15627,2774],{"class":1312},[1145,15629,15630,15633,15635,15638,15640,15643,15645,15648,15650,15653,15656,15658],{"class":1147,"line":3543},[1145,15631,15632],{"class":1890},"        chunk_data ",[1145,15634,2247],{"class":1312},[1145,15636,15637],{"class":3664}," list",[1145,15639,2218],{"class":1312},[1145,15641,15642],{"class":2214},"dataset",[1145,15644,8618],{"class":1312},[1145,15646,15647],{"class":2214},"i",[1145,15649,1313],{"class":1312},[1145,15651,15652],{"class":2214},"i ",[1145,15654,15655],{"class":1814},"+",[1145,15657,15532],{"class":2214},[1145,15659,9955],{"class":1312},[1145,15661,15662,15665,15667,15669,15671,15674,15676,15678,15680,15683],{"class":1147,"line":3571},[1145,15663,15664],{"class":1890},"        chunks",[1145,15666,2554],{"class":1312},[1145,15668,9329],{"class":2214},[1145,15670,2218],{"class":1312},[1145,15672,15673],{"class":2214},"process_chunk",[1145,15675,2554],{"class":1312},[1145,15677,5021],{"class":2214},[1145,15679,2218],{"class":1312},[1145,15681,15682],{"class":2214},"chunk_data",[1145,15684,3789],{"class":1312},[1145,15686,15687],{"class":1147,"line":3594},[1145,15688,3300],{"class":1890},[1145,15690,15691],{"class":1147,"line":3599},[1145,15692,15693],{"class":1151},"    # Process chunks in parallel\n",[1145,15695,15696,15699,15701,15703,15705,15708],{"class":1147,"line":3614},[1145,15697,15698],{"class":1890},"    job ",[1145,15700,2247],{"class":1312},[1145,15702,4727],{"class":2214},[1145,15704,2218],{"class":1312},[1145,15706,15707],{"class":2214},"chunks",[1145,15709,2382],{"class":1312},[1145,15711,15712,15714,15716,15719,15721,15723],{"class":1147,"line":3620},[1145,15713,8224],{"class":1890},[1145,15715,2247],{"class":1312},[1145,15717,15718],{"class":1890}," job",[1145,15720,2554],{"class":1312},[1145,15722,5101],{"class":2214},[1145,15724,2722],{"class":1312},[1145,15726,15727],{"class":1147,"line":3648},[1145,15728,3300],{"class":1890},[1145,15730,15731,15733,15735,15738,15740,15742,15744,15746,15748,15750],{"class":1147,"line":3654},[1145,15732,2827],{"class":1886},[1145,15734,2830],{"class":2761},[1145,15736,15737],{"class":1162},"\"Processing ",[1145,15739,2805],{"class":2804},[1145,15741,15474],{"class":2792},[1145,15743,2218],{"class":1312},[1145,15745,15707],{"class":2214},[1145,15747,1623],{"class":1312},[1145,15749,2818],{"class":2804},[1145,15751,15752],{"class":1162}," chunks\"\n",[1145,15754,15755],{"class":1147,"line":3659},[1145,15756,1472],{"emptyLinePlaceholder":1471},[1145,15758,15759,15761],{"class":1147,"line":3676},[1145,15760,2736],{"class":1312},[1145,15762,3802],{"class":2739},[1145,15764,15765,15767,15770,15772,15774],{"class":1147,"line":3682},[1145,15766,2762],{"class":2761},[1145,15768,15769],{"class":2739}," process_chunk",[1145,15771,2218],{"class":1312},[1145,15773,15682],{"class":3282},[1145,15775,2774],{"class":1312},[1145,15777,15778,15780,15783],{"class":1147,"line":3718},[1145,15779,2780],{"class":2779},[1145,15781,15782],{"class":2783},"Process a single chunk of data",[1145,15784,2787],{"class":2779},[1145,15786,15787,15790,15792],{"class":1147,"line":3723},[1145,15788,15789],{"class":1890},"    results ",[1145,15791,2247],{"class":1312},[1145,15793,9155],{"class":1312},[1145,15795,15796,15798,15800,15802,15805],{"class":1147,"line":3729},[1145,15797,4427],{"class":1886},[1145,15799,5503],{"class":1890},[1145,15801,3927],{"class":1886},[1145,15803,15804],{"class":1890}," chunk_data",[1145,15806,1331],{"class":1312},[1145,15808,15809,15811,15813,15816,15818,15820],{"class":1147,"line":3735},[1145,15810,5091],{"class":1890},[1145,15812,2247],{"class":1312},[1145,15814,15815],{"class":2214}," process_single_item",[1145,15817,2218],{"class":1312},[1145,15819,5699],{"class":2214},[1145,15821,2382],{"class":1312},[1145,15823,15824,15827,15829,15831,15833,15835],{"class":1147,"line":3792},[1145,15825,15826],{"class":1890},"        results",[1145,15828,2554],{"class":1312},[1145,15830,9329],{"class":2214},[1145,15832,2218],{"class":1312},[1145,15834,3024],{"class":2214},[1145,15836,2382],{"class":1312},[1145,15838,15839,15841],{"class":1147,"line":3797},[1145,15840,2827],{"class":1886},[1145,15842,15843],{"class":1890}," results\n",[1246,15845,15847],{"id":15846},"common-issues-and-solutions","Common Issues and Solutions",[1754,15849,15850,15859,15864,15870,15876],{},[1047,15851,15852,15855,15856,15858],{},[1050,15853,15854],{},"Memory Leaks",": Use ",[1142,15857,2427],{}," to restart workers periodically",[1047,15860,15861,15863],{},[1050,15862,2486],{},": Ensure proper queue configuration and routing",[1047,15865,15866,15869],{},[1050,15867,15868],{},"Connection Issues",": Implement connection pooling and retry logic",[1047,15871,15872,15875],{},[1050,15873,15874],{},"Monitoring",": Use Flower for real-time monitoring",[1047,15877,15878,15880],{},[1050,15879,4693],{},": Implement structured logging for better debugging",[1026,15882,15883],{},"This comprehensive guide provides the foundation for orchestrating microservices with Celery and RabbitMQ. The patterns and examples shown here can be adapted to your specific use cases and requirements.",[15885,15886,15887],"style",{},"html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .s7CZa, html code.shiki .s7CZa{--shiki-light:#F76D47;--shiki-default:#2F798A;--shiki-dark:#4C9A91}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .suXOh, html code.shiki .suXOh{--shiki-light:#E53935;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sz9Cv, html code.shiki .sz9Cv{--shiki-light:#91B859;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .siDh9, html code.shiki .siDh9{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#1E754F;--shiki-default-font-style:inherit;--shiki-dark:#4D9375;--shiki-dark-font-style:inherit}html pre.shiki code .sftqT, html code.shiki .sftqT{--shiki-light:#90A4AE;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .se3Ec, html code.shiki .se3Ec{--shiki-light:#90A4AE;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .s8XtY, html code.shiki .s8XtY{--shiki-light:#39ADB5;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .siWMO, html code.shiki .siWMO{--shiki-light:#6182B8;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sqOPj, html code.shiki .sqOPj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B07D48;--shiki-default-font-style:inherit;--shiki-dark:#BD976A;--shiki-dark-font-style:inherit}html pre.shiki code .sBPpx, html code.shiki .sBPpx{--shiki-light:#E53935;--shiki-default:#393A34;--shiki-dark:#DBD7CAEE}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sRjD_, html code.shiki .sRjD_{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sm7ve, html code.shiki .sm7ve{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#B5695977;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D77;--shiki-dark-font-style:inherit}html pre.shiki code .sVyVU, html code.shiki .sVyVU{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#B56959;--shiki-default-font-style:inherit;--shiki-dark:#C98A7D;--shiki-dark-font-style:inherit}html pre.shiki code .sJdAF, html code.shiki .sJdAF{--shiki-light:#6182B8;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .s3h35, html code.shiki .s3h35{--shiki-light:#F76D47;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .s131V, html code.shiki .s131V{--shiki-light:#90A4AE;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sCyAa, html code.shiki .sCyAa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#393A34;--shiki-default-font-style:inherit;--shiki-dark:#DBD7CAEE;--shiki-dark-font-style:inherit}html pre.shiki code .sa2tF, html code.shiki .sa2tF{--shiki-light:#E2931D;--shiki-default:#998418;--shiki-dark:#B8A965}html pre.shiki code .sFGJz, html code.shiki .sFGJz{--shiki-light:#E53935;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .scgAs, html code.shiki .scgAs{--shiki-light:#F76D47;--shiki-default:#1E754F;--shiki-dark:#4D9375}",{"title":1140,"searchDepth":1148,"depth":1155,"links":15889},[15890,15891,15892,15897,15902,15907,15912,15916,15920],{"id":1032,"depth":1155,"text":1033},{"id":1074,"depth":1155,"text":1075},{"id":1240,"depth":1155,"text":1241,"children":15893},[15894,15895,15896],{"id":1248,"depth":1173,"text":1249},{"id":1287,"depth":1173,"text":1288},{"id":1635,"depth":1173,"text":1636},{"id":1824,"depth":1155,"text":1825,"children":15898},[15899,15900,15901],{"id":1831,"depth":1173,"text":1832},{"id":1865,"depth":1173,"text":1866},{"id":2511,"depth":1173,"text":2512},{"id":3049,"depth":1155,"text":3050,"children":15903},[15904,15905,15906],{"id":3056,"depth":1173,"text":3057},{"id":3102,"depth":1173,"text":3103},{"id":4697,"depth":1173,"text":4698},{"id":7834,"depth":1155,"text":7835,"children":15908},[15909,15910,15911],{"id":7841,"depth":1173,"text":7842},{"id":7880,"depth":1173,"text":7881},{"id":10201,"depth":1173,"text":10202},{"id":12651,"depth":1155,"text":12652,"children":15913},[15914,15915],{"id":12655,"depth":1173,"text":12656},{"id":13635,"depth":1173,"text":13636},{"id":14436,"depth":1155,"text":14437,"children":15917},[15918,15919],{"id":14440,"depth":1173,"text":14441},{"id":14583,"depth":1173,"text":14584},{"id":15121,"depth":1155,"text":15122,"children":15921},[15922,15923],{"id":15125,"depth":1173,"text":15126},{"id":15846,"depth":1173,"text":15847},"md",null,{},{"title":901,"description":1028},"-OmEm70ySqmfvgXCe7g-3XJxF72_IaqrV9lU4Jx2hRM",[15930,15932],{"title":897,"path":898,"stem":899,"description":15931,"children":-1},"RESTful APIs are the backbone of microservices communication. This section covers designing, implementing, and optimizing REST APIs using Django REST Framework for microservices architecture.",{"title":905,"path":906,"stem":907,"description":15933,"children":-1},"Testing microservices presents unique challenges compared to monolithic applications. This chapter covers comprehensive testing strategies, tools, and best practices for ensuring reliability and quality in your Django microservices architecture.",1772474963687]