canic_core/api/placement/
sharding.rs

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