الهندسةMar 28, 2026
Deep EVM #24: نشر السياق في Rust غير المتزامن — المواعيد النهائية والإلغاء والتتبع
OS
Open Soft Team
Engineering Team
السياق في الأنظمة غير المتزامنة
عندما يصل طلب إلى خادمك، يمر عبر عدة مراحل: المعالج، الخدمة، قاعدة البيانات. كيف تنشر معلومات السياق (الموعد النهائي، معرف التتبع، بيانات الاعتماد) عبر هذه المراحل؟
المواعيد النهائية مع tokio::time
use tokio::time::{timeout, Duration};
async fn handle_request(req: Request) -> Result<Response> {
// الموعد النهائي: 5 ثوانٍ لكل العملية
timeout(Duration::from_secs(5), async {
let data = fetch_from_db(&req).await?;
let result = process(data).await?;
Ok(Response::new(result))
})
.await
.map_err(|_| Error::Timeout)?
}
الإلغاء التعاوني
use tokio_util::sync::CancellationToken;
let token = CancellationToken::new();
let child_token = token.child_token();
tokio::spawn(async move {
tokio::select! {
_ = child_token.cancelled() => {
tracing::info!("تم الإلغاء");
}
result = do_work() => {
// العمل اكتمل
}
}
});
// إلغاء كل المهام الفرعية
token.cancel();
التتبع الموزع
use tracing::{instrument, info_span};
#[instrument(skip(pool))]
async fn get_article(pool: &PgPool, slug: &str) -> Result<Article> {
let span = info_span!("db_query", table = "articles");
let _guard = span.enter();
sqlx::query_as::<_, Article>("SELECT * FROM articles WHERE slug = $1")
.bind(slug)
.fetch_one(pool)
.await
.map_err(Into::into)
}
task_local لسياق المهمة
tokio::task_local! {
static REQUEST_ID: String;
}
async fn handle(req: Request) -> Response {
let request_id = Uuid::new_v4().to_string();
REQUEST_ID.scope(request_id, async {
// كل الكود هنا يمكنه الوصول لـ REQUEST_ID
let article = get_article(&pool, &slug).await?;
Ok(Response::new(article))
}).await
}
الخلاصة
نشر السياق في Rust غير المتزامن يعتمد على timeout للمواعيد النهائية، CancellationToken للإلغاء، وtracing للتتبع الموزع. هذه الأنماط ضرورية لبناء خدمات إنتاجية قابلة للمراقبة.
الوسوم