lilydocs
HTTP APIWebSocketConsumer
Veri4 dk okuma

MongoDB ve cache

MongoDB collection ve cache servislerini DI ile kullanın; operation context’lerini mesaj cancellation’ına açıkça bağlayın.

MongoDB ve cache servisleri ortak DI altyapısını kullanır. WebSocket'e özgü kısım, bu servislerin operation context'leri ile mesaj execution sinyalini bağlamaktır. Bağlantı boyunca açık transaction veya sınırsız operation varsaymayın.

MongoDB kurulumu#

İlk uygulamanın lilyrs feature listesini güncelleyip diğer bağımlılıkları ekleyin:

Cargo.toml bağımlılıkları
lilyrs = { version = "0.1.0", features = ["websocket", "mongodb"] }
tokio-util = "0.7"

mongodb single modunu seçer; named database kurulumu için bunun yerine mongodb-factory kullanılır. MongoFilter ve MongoRepositoryError, lilyrs::mongodb tarafından re-export edilir; ayrı bir repository crate bağımlılığı gerekmez. Serde ve Tokio ilk uygulamadaki gibi kalır. Makroların ihtiyaç duyduğu helper'lar facade üzerinden çözülür. Bu örnek BSON tiplerini de lilyrs::mongodb::bson yolundan alır; yalnız generated kod için ayrıca mongodb, async-trait veya futures eklemek gerekmez. Uygulamanın doğrudan kullandığı tokio-util ise manifestte kalır.

Yerel lily.toml
[database]
mode = "single"
database_type = "mongodb"
connection_string = "mongodb://127.0.0.1:27017"
database_name = "lily"
query_timeout_secs = 10

MongoDB bölümü [database]'dir; [mongodb] değildir. [postgresql] ve [cache] ayrı bölümlerdir. Canlı ortamda kendi bağlantı, TLS ve secret ayarlarınızı kullanın.

Typed collection ve iptal köprüsü#

mongodb.rs
use std::sync::Arc;
use lilyrs::websocket::Injectable;
use lilyrs::websocket::ServiceTrait;
use lilyrs::websocket::ExecutionCancellation;
use lilyrs::mongodb::{Collection, DatabaseService, MongoCollection};
use lilyrs::mongodb::{MongoFilter, MongoRepositoryError};
use lilyrs::mongodb::bson::{doc, oid::ObjectId};
use serde::{Deserialize, Serialize};
use tokio_util::sync::CancellationToken;

#[derive(Clone, Serialize, Deserialize)]
struct User {
    #[serde(skip_serializing_if = "Option::is_none")]
    _id: Option<ObjectId>,
    name: String,
}
#[derive(Default, Injectable, MongoCollection)]
#[service(lifetime = "Singleton")]
#[collection("users")]
#[collection_type(User)]
struct UserCollection {
    #[inject]
    db: Arc<DatabaseService>,
    collection: Option<Collection<User>>,
}
// MongoCollection, ServiceTrait implementasyonunu üretir.

#[derive(Injectable)]
#[service(lifetime = "Singleton")]
struct UserService {
    #[inject]
    database: Arc<DatabaseService>,
    #[inject]
    users: Arc<UserCollection>,
}
impl ServiceTrait for UserService {}
impl UserService {
    async fn find_by_name(&self, name: &str, stopping: ExecutionCancellation)
        -> Result<Option<User>, MongoRepositoryError>
    {
        let token = CancellationToken::new();
        let _cancel_on_drop = token.clone().drop_guard();
        let operation = self.database.operation_context(token.clone())?;
        let filter = MongoFilter::new(doc! { "name": name })?;
        let work = self.users.find_one(filter, &operation);
        tokio::pin!(work);
        tokio::select! {
            biased;
            _ = stopping.cancelled() => { token.cancel(); work.await }
            result = &mut work => result,
        }
    }
}

Tam örnek dosyasını indirin.

MongoCollection, ServiceTrait implementation'ını üretir; aynı tip için tekrar yazmayın. collection runtime alanı inject edilmediği için struct Default da türetir. Örnekteki private servis method'unu aynı modüldeki action'dan Service<UserService> ve ExecutionCancellation ile çağırabilirsiniz; başka modüle açarsanız görünürlüğünü bilinçli düzenleyin.

Operation sahipliği#

database.operation_context(token) config query timeout'unu kullanır. Örnek uygulamaya ait CancellationToken oluşturur, WS sinyalini gözleyip onu cancel eder ve işi aynı invocation içinde bekler. Early drop için token drop guard'ı vardır; raw WS token'ı çıkarılmaz ve detached worker açılmaz.

Gerektiğinde with_deadline ile daha kısa kalan mesaj süresini seçin. Aynı context üzerinde tekrar çağrının timeout'u değiştirdiğini hesaba katın. DI scope tek başına Mongo transaction başlatmaz; explicit begin, context bağlantısı ve commit/abort gerekir. Transaction/migration rehberi ortak veri katmanını açıklar.

Cache kullanımı#

Yerel cache config
[cache]
mode = "single"
provider = "redis"
redis_url = "redis://127.0.0.1:6379/0"
key_namespace = "chat-api"
operation_timeout_secs = 2

lilyrs için redis feature'ı, lilyrs::redis import'ları ve CacheOperationContext köprüsü rate limiter sayfasında tam örneklidir. redis tek servis için single seçer; adlandırılmış bağlantılar için bunun yerine redis-factory kullanın. Mongo ile birlikte kullanıyorsanız aynı lilyrs satırının feature listesine seçilen Redis profilini ekleyin. [cache] config adı değişmez. Cache Redis'i ile backplane Redis'i ayrı client ve lifecycle sahibidir; aynı sunucuya bağlanmaları pool paylaşımı anlamına gelmez.

Bu örneklerin derlemesi doğrulanmıştır. Canlı Mongo replica set, transaction, migration ve Redis veri işlemleri kendi entegrasyon ortamınızda ayrıca test edilmelidir.

Bu sayfanın kaynakları v0.1.0

Anlatım, incelenen framework commit’ine dayanır.

HIZLI BAŞLANGIÇ
Dokümantasyon
Kaynak kod