[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-24-propagacion-contexto-rust-asincrono":3},{"article":4,"author":42},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":22,"related_articles":23},"d8000000-0000-0000-0000-000000000124","a0000000-0000-0000-0000-000000000086","Deep EVM #24: Propagación de Contexto en Rust Asíncrono — Deadlines, Cancelación y Tracing","deep-evm-24-propagacion-contexto-rust-asincrono","Implementa propagación de contexto en Rust asíncrono: deadlines con tokio timeout, cancelación cooperativa, propagación de trace IDs, y patrones para pipelines de procesamiento.","## El problema del contexto en async Rust\n\nEn Go, el paquete `context` propaga deadlines, cancelación y valores a través de la cadena de llamadas. Rust no tiene un equivalente estándar, pero podemos construir patrones similares con tokio.\n\n## Deadlines con tokio::time::timeout\n\n```rust\nuse tokio::time::{timeout, Duration};\n\nasync fn process_block(block: Block) -> Result\u003CVec\u003CBundle>> {\n    \u002F\u002F Deadline total: 10 segundos\n    let result = timeout(\n        Duration::from_secs(10),\n        process_block_inner(block)\n    ).await;\n    \n    match result {\n        Ok(Ok(bundles)) => Ok(bundles),\n        Ok(Err(e)) => Err(e),\n        Err(_) => {\n            tracing::warn!(\"Block processing timed out\");\n            Ok(vec![]) \u002F\u002F Retornar vacío en timeout\n        }\n    }\n}\n```\n\n## Cancelación cooperativa con CancellationToken\n\n```rust\nuse tokio_util::sync::CancellationToken;\n\nasync fn worker(token: CancellationToken) {\n    loop {\n        tokio::select! {\n            _ = token.cancelled() => {\n                tracing::info!(\"Worker cancelado\");\n                return;\n            }\n            result = do_work() => {\n                handle_result(result);\n            }\n        }\n    }\n}\n\n\u002F\u002F Uso:\nlet token = CancellationToken::new();\nlet child_token = token.child_token();\n\ntokio::spawn(worker(child_token));\n\n\u002F\u002F Cancelar todos los workers:\ntoken.cancel();\n```\n\n## Propagación de trace IDs\n\nPara correlacionar logs a través de componentes async:\n\n```rust\nuse tracing::{instrument, Span};\nuse uuid::Uuid;\n\n#[instrument(fields(request_id = %Uuid::new_v4()))]\nasync fn handle_request(req: Request) -> Response {\n    let result = process(req).await; \u002F\u002F Hereda el span\n    respond(result).await            \u002F\u002F También hereda\n}\n```\n\n## Struct de contexto personalizado\n\n```rust\nstruct PipelineContext {\n    deadline: Instant,\n    cancellation: CancellationToken,\n    trace_id: String,\n    block_number: u64,\n}\n\nimpl PipelineContext {\n    fn remaining(&self) -> Duration {\n        self.deadline.saturating_duration_since(Instant::now())\n    }\n    \n    fn is_expired(&self) -> bool {\n        Instant::now() >= self.deadline\n    }\n}\n```\n\nEste contexto se pasa a cada etapa del pipeline, permitiendo cancelación temprana y seguimiento distribuido.\n\n## Conclusión\n\nLa propagación de contexto en Rust asíncrono requiere composición manual de timeout, CancellationToken y tracing spans. Aunque no es tan integrado como el context.Context de Go, los patrones resultantes son más explícitos y tipo-seguros.","\u003Ch2 id=\"el-problema-del-contexto-en-async-rust\">El problema del contexto en async Rust\u003C\u002Fh2>\n\u003Cp>En Go, el paquete \u003Ccode>context\u003C\u002Fcode> propaga deadlines, cancelación y valores a través de la cadena de llamadas. Rust no tiene un equivalente estándar, pero podemos construir patrones similares con tokio.\u003C\u002Fp>\n\u003Ch2 id=\"deadlines-con-tokio-time-timeout\">Deadlines con tokio::time::timeout\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">use tokio::time::{timeout, Duration};\n\nasync fn process_block(block: Block) -&gt; Result&lt;Vec&lt;Bundle&gt;&gt; {\n    \u002F\u002F Deadline total: 10 segundos\n    let result = timeout(\n        Duration::from_secs(10),\n        process_block_inner(block)\n    ).await;\n    \n    match result {\n        Ok(Ok(bundles)) =&gt; Ok(bundles),\n        Ok(Err(e)) =&gt; Err(e),\n        Err(_) =&gt; {\n            tracing::warn!(\"Block processing timed out\");\n            Ok(vec![]) \u002F\u002F Retornar vacío en timeout\n        }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"cancelaci-n-cooperativa-con-cancellationtoken\">Cancelación cooperativa con CancellationToken\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">use tokio_util::sync::CancellationToken;\n\nasync fn worker(token: CancellationToken) {\n    loop {\n        tokio::select! {\n            _ = token.cancelled() =&gt; {\n                tracing::info!(\"Worker cancelado\");\n                return;\n            }\n            result = do_work() =&gt; {\n                handle_result(result);\n            }\n        }\n    }\n}\n\n\u002F\u002F Uso:\nlet token = CancellationToken::new();\nlet child_token = token.child_token();\n\ntokio::spawn(worker(child_token));\n\n\u002F\u002F Cancelar todos los workers:\ntoken.cancel();\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"propagaci-n-de-trace-ids\">Propagación de trace IDs\u003C\u002Fh2>\n\u003Cp>Para correlacionar logs a través de componentes async:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">use tracing::{instrument, Span};\nuse uuid::Uuid;\n\n#[instrument(fields(request_id = %Uuid::new_v4()))]\nasync fn handle_request(req: Request) -&gt; Response {\n    let result = process(req).await; \u002F\u002F Hereda el span\n    respond(result).await            \u002F\u002F También hereda\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"struct-de-contexto-personalizado\">Struct de contexto personalizado\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct PipelineContext {\n    deadline: Instant,\n    cancellation: CancellationToken,\n    trace_id: String,\n    block_number: u64,\n}\n\nimpl PipelineContext {\n    fn remaining(&amp;self) -&gt; Duration {\n        self.deadline.saturating_duration_since(Instant::now())\n    }\n    \n    fn is_expired(&amp;self) -&gt; bool {\n        Instant::now() &gt;= self.deadline\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Este contexto se pasa a cada etapa del pipeline, permitiendo cancelación temprana y seguimiento distribuido.\u003C\u002Fp>\n\u003Ch2 id=\"conclusi-n\">Conclusión\u003C\u002Fh2>\n\u003Cp>La propagación de contexto en Rust asíncrono requiere composición manual de timeout, CancellationToken y tracing spans. Aunque no es tan integrado como el context.Context de Go, los patrones resultantes son más explícitos y tipo-seguros.\u003C\u002Fp>\n","es","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:31.642178Z","Propagación de Contexto en Rust Asíncrono — Deadlines, Cancelación y Tracing","Propagación de contexto en async Rust: deadlines con tokio, cancelación cooperativa, trace IDs y patrones para pipelines.","Rust async contexto propagación",null,"index, follow",[],"Ingeniería",[24,30,36],{"id":25,"title":26,"slug":27,"excerpt":28,"locale":12,"category_name":22,"published_at":29},"d0000000-0000-0000-0000-000000000683","Por qué Bali se está convirtiendo en el hub de impact-tech del Sudeste Asiático en 2026","por-que-bali-hub-impact-tech-sudeste-asiatico-2026","Bali ocupa el puesto 16 entre los ecosistemas startup del Sudeste Asiático. Con una concentración creciente de constructores Web3, startups de AI sostenible y empresas de eco-travel tech, la isla se consolida como capital de impact-tech de la región.","2026-03-28T10:44:49.926489Z",{"id":31,"title":32,"slug":33,"excerpt":34,"locale":12,"category_name":22,"published_at":35},"d0000000-0000-0000-0000-000000000682","El mosaico de protección de datos de ASEAN: checklist de cumplimiento para desarrolladores","mosaico-proteccion-datos-asean-checklist-cumplimiento-desarrolladores","Siete países de ASEAN tienen ahora leyes integrales de protección de datos, cada una con diferentes modelos de consentimiento, requisitos de localización y estructuras de sanciones. Un checklist práctico de cumplimiento para desarrolladores.","2026-03-28T10:44:49.919345Z",{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":22,"published_at":41},"d0000000-0000-0000-0000-000000000681","La transformación digital de 29 mil millones de dólares de Indonesia: oportunidades para empresas de software","transformacion-digital-29-mil-millones-dolares-indonesia-oportunidades-empresas-software","El mercado de servicios IT de Indonesia alcanzará los 29.030 millones de dólares en 2026, frente a los 24.370 millones de 2025. La infraestructura cloud, la AI, el comercio electrónico y los centros de datos impulsan el crecimiento más rápido del Sudeste Asiático.","2026-03-28T10:44:49.897658Z",{"id":13,"name":43,"slug":44,"bio":45,"photo_url":19,"linkedin":19,"role":46,"created_at":47,"updated_at":47},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]