v0.3.2-pre.011
This commit is contained in:
95
crates/ksp-store-lib/README.md
Normal file
95
crates/ksp-store-lib/README.md
Normal file
@@ -0,0 +1,95 @@
|
||||
<!-- file: crates/ksp-store-lib/README.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# ksp-store-lib
|
||||
|
||||
`ksp-store-lib` est la façade runtime Store commune de KSP.
|
||||
|
||||
Elle expose aux consumers une surface backend-neutral, réexporte les contrats RAW de `ksp-store-api`, sélectionne uniquement les backends compilés et masque leurs objets physiques. Le backend PostgreSQL officiel est activé par défaut via la feature `postgres` et reste implémenté dans `ksp-store-postgres-lib`.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
`ksp-store-lib` possède :
|
||||
|
||||
- `StoreSettings`, avec un réseau logique unique, un backend sélectionné et un timeout de fermeture borné ;
|
||||
- les settings PostgreSQL publics KSP-owned : pool, TLS, bootstrap/migrations et URI sensible ;
|
||||
- la feature `postgres` par défaut et le comportement explicite `backend_not_compiled` lorsque PostgreSQL est sélectionné sans cette feature ;
|
||||
- `Store::open`, qui ne retourne une instance qu'après validation, ouverture physique du backend compilé et bootstrap/history réussis ;
|
||||
- `Store::runtime_snapshot()` pour les compteurs runtime sûrs sans I/O ;
|
||||
- `Store::health().await` pour la readiness portable et bornée ;
|
||||
- `Store::close(self).await` pour la fermeture explicite bornée ;
|
||||
- le mapping des erreurs backend vers des codes Store stables sans exposer les erreurs physiques ;
|
||||
- les réexports crate-root de `ksp-store-api` nécessaires aux consumers ordinaires.
|
||||
|
||||
## Une instance = un réseau
|
||||
|
||||
Une instance `Store` représente exactement :
|
||||
|
||||
```text
|
||||
1 Store = 1 RawNetworkId + 1 backend physique sélectionné
|
||||
```
|
||||
|
||||
Le runtime Store n'est pas un multiplexeur multi-database ou multi-réseau. La sélection d'un target nommé appartient à Config. Le document `std.store` peut donc définir plusieurs targets indépendants — par exemple Devnet, Mainnet et Testnet — mais un appel à `Store::open` reçoit les settings d'un seul target.
|
||||
|
||||
Cette séparation permet d'utiliser des bases PostgreSQL distinctes par réseau tout en conservant le réseau dans l'identité logique des données RAW.
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
Avec la feature par défaut :
|
||||
|
||||
```text
|
||||
ksp-store-lib
|
||||
-> ksp-store-api
|
||||
-> ksp-logging-lib
|
||||
-> ksp-store-postgres-lib
|
||||
```
|
||||
|
||||
`ksp-store-lib` ne réexporte aucun type `tokio-postgres`, Deadpool ou Rustls.
|
||||
|
||||
Les modes TLS publics sont volontairement limités à :
|
||||
|
||||
```text
|
||||
Disabled
|
||||
VerifyFull
|
||||
```
|
||||
|
||||
`VerifyFull` impose TLS avec vérification de la chaîne et de l'identité serveur. La policy typée Store prime sur les paramètres TLS présents dans l'URI.
|
||||
|
||||
## Config et secrets
|
||||
|
||||
Store ne lit ni `.env`, ni variables `KSP_*` / `KSPB_*`, ni variables/fichiers implicites libpq (`PG*`, `.pgpass`, fichiers TLS PostgreSQL).
|
||||
|
||||
`ksp-config-lib` possède `std.store`, la résolution des secrets et la sélection du target. Il construit ensuite un `StoreSettings` backend-neutral. L'URI PostgreSQL reste nécessaire au runtime mais n'a aucun getter public dans `ksp-store-lib` et son `Debug` est redacted.
|
||||
|
||||
Les targets committed sont actuellement :
|
||||
|
||||
```text
|
||||
devnet -> network devnet -> base indépendante
|
||||
mainnet -> network mainnet-beta -> base indépendante
|
||||
testnet -> network testnet -> base indépendante
|
||||
```
|
||||
|
||||
Les credentials restent dans les variables `KSP_SECRET_STORE_*_POSTGRES_URI` ou le `.env` possédé par Config.
|
||||
|
||||
## Surface actuelle et hors périmètre
|
||||
|
||||
La fondation runtime ne fournit encore aucune implémentation PostgreSQL des capabilities métier RAW de `ksp-store-api`.
|
||||
|
||||
Sont volontairement hors de cette surface :
|
||||
|
||||
- persistence/query/rétention PostgreSQL de `RawTransaction` ;
|
||||
- persistence/query/rétention PostgreSQL de `RawAccountState` ;
|
||||
- batch-size, priorité, backlog ou policy de worker/job ;
|
||||
- transport d'acquisition, Program decoding et materialization ;
|
||||
- exposition publique de SQL, pool, client, row, statement ou transaction PostgreSQL.
|
||||
|
||||
Les premières vertical slices métier sont ajoutées séparément afin que la façade runtime reste stable et backend-neutral.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [`USAGE.md`](USAGE.md) — construction des settings, ouverture, health et fermeture ;
|
||||
- [`../ksp-store-postgres-lib/README.md`](../ksp-store-postgres-lib/README.md) — responsabilité du backend PostgreSQL physique ;
|
||||
- [`../../config/std.store.json`](../../config/std.store.json) — targets Store committed ;
|
||||
- [`../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md`](../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md) — architecture durable Store ;
|
||||
- [`../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) — plan de fondation ;
|
||||
- [`../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) — matrice de validation.
|
||||
219
crates/ksp-store-lib/USAGE.md
Normal file
219
crates/ksp-store-lib/USAGE.md
Normal file
@@ -0,0 +1,219 @@
|
||||
<!-- file: crates/ksp-store-lib/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Utilisation de ksp-store-lib
|
||||
|
||||
## 1. Dépendance et features
|
||||
|
||||
Le consumer runtime normal dépend uniquement de la façade :
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ksp-store-lib = { path = "../ksp-store-lib" }
|
||||
```
|
||||
|
||||
La feature par défaut est :
|
||||
|
||||
```text
|
||||
postgres
|
||||
```
|
||||
|
||||
Pour construire un binaire sans backend physique :
|
||||
|
||||
```toml
|
||||
ksp-store-lib = { path = "../ksp-store-lib", default-features = false }
|
||||
```
|
||||
|
||||
Dans ce mode, le type PostgreSQL reste connu par la surface de settings mais `Store::open` retourne `ERROR_CODE_BACKEND_NOT_COMPILED` avant toute I/O si PostgreSQL est sélectionné.
|
||||
|
||||
Un consumer ordinaire ne dépend pas directement de `ksp-store-postgres-lib`.
|
||||
|
||||
## 2. Construire des settings PostgreSQL programmatiquement
|
||||
|
||||
La construction directe est utile pour les tests, outils internes ou compositions qui n'utilisent pas `ksp-config-lib`.
|
||||
|
||||
```rust
|
||||
fn programmatic_store_settings(connection_uri: std::string::String) -> ksp_store_lib::Result<ksp_store_lib::StoreSettings> {
|
||||
let network = ksp_store_lib::RawNetworkId::new("devnet");
|
||||
let network = match network {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
|
||||
let postgres = ksp_store_lib::PostgresStoreSettings::new(
|
||||
connection_uri,
|
||||
ksp_store_lib::PostgresPoolSettings::default(),
|
||||
ksp_store_lib::PostgresTlsMode::VerifyFull,
|
||||
ksp_store_lib::PostgresBootstrapSettings::default(),
|
||||
);
|
||||
|
||||
let settings = ksp_store_lib::StoreSettings::with_default_shutdown(
|
||||
network,
|
||||
ksp_store_lib::StoreBackendSettings::Postgres(postgres),
|
||||
);
|
||||
|
||||
let validation = settings.validate();
|
||||
if let std::result::Result::Err(error) = validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
|
||||
return std::result::Result::Ok(settings);
|
||||
}
|
||||
```
|
||||
|
||||
`PostgresStoreSettings` ne fournit volontairement aucun getter public de l'URI. Son `Debug` remplace cette valeur par `<redacted>`.
|
||||
|
||||
## 3. Ouvrir et fermer un Store
|
||||
|
||||
`Store::open` est async et ne retourne un succès qu'après que le backend compilé a prouvé sa fondation runtime.
|
||||
|
||||
```rust
|
||||
async fn use_store(settings: ksp_store_lib::StoreSettings) -> ksp_store_lib::Result<()> {
|
||||
let store = ksp_store_lib::Store::open(settings).await;
|
||||
let store = match store {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
|
||||
let runtime = store.runtime_snapshot();
|
||||
let _network = runtime.network();
|
||||
let _capacity = runtime.pool_capacity();
|
||||
let _size = runtime.pool_size();
|
||||
let _available = runtime.pool_available();
|
||||
let _waiting = runtime.pool_waiting();
|
||||
|
||||
let health = store.health().await;
|
||||
match health.state() {
|
||||
ksp_store_lib::StoreHealthState::Ready => {}
|
||||
ksp_store_lib::StoreHealthState::NotReady => {
|
||||
let _safe_error_code = health.last_error_code();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
return store.close().await;
|
||||
}
|
||||
```
|
||||
|
||||
`Store::close(self)` consomme l'instance afin qu'une fermeture explicite ne puisse pas être suivie d'une nouvelle opération via la même valeur.
|
||||
|
||||
## 4. Construire les settings depuis Config
|
||||
|
||||
Le chemin applicatif recommandé utilise `ksp-config-lib`, propriétaire du document `std.store`, de `.env` et des secrets.
|
||||
|
||||
Après construction du `ConfigDocumentEngine` :
|
||||
|
||||
```rust
|
||||
fn resolve_store_settings(
|
||||
engine: &ksp_config_lib::ConfigDocumentEngine,
|
||||
environment: &ksp_config_lib::ConfigEnvironment,
|
||||
target: std::option::Option<&str>,
|
||||
) -> ksp_core_lib::Result<ksp_store_lib::StoreSettings> {
|
||||
let resolved = engine.load_resolved_store_config(target, environment);
|
||||
let resolved = match resolved {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
|
||||
return std::result::Result::Ok(resolved.into_settings());
|
||||
}
|
||||
```
|
||||
|
||||
Targets committed :
|
||||
|
||||
```text
|
||||
devnet -> RawNetworkId("devnet")
|
||||
mainnet -> RawNetworkId("mainnet-beta")
|
||||
testnet -> RawNetworkId("testnet")
|
||||
```
|
||||
|
||||
Chaque target peut utiliser une URI PostgreSQL distincte. `default_profile` sélectionne un seul target ; `Store` ne route pas automatiquement entre plusieurs targets.
|
||||
|
||||
## 5. Settings disponibles
|
||||
|
||||
### `PostgresPoolSettings`
|
||||
|
||||
Valeurs par défaut :
|
||||
|
||||
```text
|
||||
max_connections 8
|
||||
connect_timeout 10 s
|
||||
wait_timeout 5 s
|
||||
create_timeout 10 s
|
||||
recycle_timeout 5 s
|
||||
```
|
||||
|
||||
Les getters sont :
|
||||
|
||||
```text
|
||||
max_connections()
|
||||
connect_timeout()
|
||||
wait_timeout()
|
||||
create_timeout()
|
||||
recycle_timeout()
|
||||
```
|
||||
|
||||
`validate()` vérifie les bornes sans I/O.
|
||||
|
||||
### `PostgresBootstrapSettings`
|
||||
|
||||
Valeurs par défaut :
|
||||
|
||||
```text
|
||||
auto_migrate true
|
||||
migration_timeout 30 s
|
||||
migration_lock_timeout 10 s
|
||||
```
|
||||
|
||||
Getters :
|
||||
|
||||
```text
|
||||
auto_migrate()
|
||||
migration_timeout()
|
||||
migration_lock_timeout()
|
||||
```
|
||||
|
||||
### `StoreSettings`
|
||||
|
||||
La surface expose :
|
||||
|
||||
```text
|
||||
backend()
|
||||
backend_kind()
|
||||
network()
|
||||
shutdown_timeout()
|
||||
validate()
|
||||
```
|
||||
|
||||
`StoreSettings::new` permet de choisir explicitement le timeout de shutdown. `StoreSettings::with_default_shutdown` utilise la borne commune par défaut de 5 secondes.
|
||||
|
||||
## 6. Health et diagnostics
|
||||
|
||||
`StoreRuntimeSnapshot` est synchrone et ne déclenche aucune I/O. Il expose uniquement :
|
||||
|
||||
```text
|
||||
backend_kind
|
||||
network
|
||||
pool_capacity
|
||||
pool_size
|
||||
pool_available
|
||||
pool_waiting
|
||||
```
|
||||
|
||||
`StoreHealthSnapshot` ajoute une probe async bornée :
|
||||
|
||||
```text
|
||||
state = Ready | NotReady
|
||||
migration_version
|
||||
pending_migration_count
|
||||
last_error_code
|
||||
runtime snapshot
|
||||
```
|
||||
|
||||
Aucun snapshot n'expose URI, host, user, database, SQL, handle backend ou texte d'erreur PostgreSQL.
|
||||
|
||||
## 7. Limite fonctionnelle actuelle
|
||||
|
||||
`ksp-store-lib` réexporte les modèles et traits RAW de `ksp-store-api`, mais le backend PostgreSQL de la fondation n'implémente encore aucune capability `RawTransaction*` ou `RawAccount*`.
|
||||
|
||||
Les consumers ne doivent donc pas interpréter la disponibilité du runtime PostgreSQL comme une persistence métier déjà présente.
|
||||
Reference in New Issue
Block a user