Skip to main content

canic_core/api/placement/
sharding.rs

1use crate::{
2    cdk::types::Principal,
3    dto::{
4        error::Error,
5        placement::sharding::{
6            ShardingPlanStateResponse, ShardingRegistryResponse, ShardingTenantsResponse,
7        },
8    },
9    workflow::placement::sharding::{ShardingWorkflow, query::ShardingQuery},
10};
11
12///
13/// ShardingApi
14///
15/// Public API façade for shard placement and inspection.
16///
17/// Responsibilities:
18/// - Expose read-only sharding queries
19/// - Expose sharding workflows (assignment / planning)
20/// - Normalize internal `InternalError` into `Error`
21///
22/// Does not:
23/// - Contain business logic
24/// - Interpret policies
25/// - Access storage directly
26///
27pub struct ShardingApi;
28
29impl ShardingApi {
30    // ───────────────────────── Queries ─────────────────────────
31
32    /// Lookup the shard assigned to a tenant in a pool, if any.
33    #[must_use]
34    pub fn lookup_tenant(pool: &str, tenant: &str) -> Option<Principal> {
35        ShardingQuery::lookup_tenant(pool, tenant)
36    }
37
38    /// Return the shard for a tenant, or an Error if unassigned.
39    pub fn require_tenant_shard(pool: &str, tenant: impl AsRef<str>) -> Result<Principal, Error> {
40        ShardingQuery::require_tenant_shard(pool, tenant.as_ref()).map_err(Error::from)
41    }
42
43    /// Return a view of the full sharding registry.
44    #[must_use]
45    pub fn registry() -> ShardingRegistryResponse {
46        ShardingQuery::registry()
47    }
48
49    /// Return all tenants currently assigned to a shard.
50    #[must_use]
51    pub fn tenants(pool: &str, shard: Principal) -> ShardingTenantsResponse {
52        ShardingQuery::tenants(pool, shard)
53    }
54
55    // ─────────────────────── Workflows ────────────────────────
56
57    /// Assign a tenant to a shard in the given pool.
58    ///
59    /// This performs validation, selection, and persistence.
60    pub async fn assign_to_pool(pool: &str, tenant: impl AsRef<str>) -> Result<Principal, Error> {
61        ShardingWorkflow::assign_to_pool(pool, tenant)
62            .await
63            .map_err(Error::from)
64    }
65
66    /// Perform a dry-run shard assignment and return the resulting plan.
67    pub fn plan_assign_to_pool(
68        pool: &str,
69        tenant: impl AsRef<str>,
70    ) -> Result<ShardingPlanStateResponse, Error> {
71        ShardingWorkflow::plan_assign_to_pool(pool, tenant).map_err(Error::from)
72    }
73}