Something went wrong

Thank you for being patient! We're working hard on resolving the issue

The sync-plugin feature - Lona Docs Log in

The sync-plugin feature

sync-plugin is the optional cargo feature that pulls in lona-sync and ships a lona_sync::SyncProvider + lona_sync::SyncExecutor impl alongside your connector module.

What it adds

tento-myprovider/src/sync_plugin/
├── mod.rs
├── provider.rs    # impl lona_sync::SyncProvider
├── executor.rs    # impl lona_sync::SyncExecutor
├── context.rs     # MyProviderApiContext (auth-resolution seam)
├── deps.rs        # MyProviderSyncDeps (state + persistence seam)
└── state.rs       # RowSyncState (per-row sync metadata)

<Provider>SyncProvider declares topology (stages, gating, locking, max-concurrent, alias-key). <Provider>SyncExecutor runs the sync — it walks date ranges and calls into the <Provider>SyncDeps and <Provider>ApiContext seams.

Live examples:

  • tento-garmin/src/sync_plugin/
  • tento-whoop/src/sync_plugin/
  • tento-weather/src/sync_plugin/ (provider only — no executor)

When to ship it

Ship sync-plugin when:

  • Your sync logic is generic enough to live in the SDK crate without leaking host data shapes.
  • Your MyProviderBackendDeps-style trait propagates Send cleanly across async fn returns.
  • Multiple host integrations might want to reuse the same orchestrator wiring.

Skip it when:

  • The executor needs to thread host-specific concrete types whose Send-bounds are hard to express generically. (This is what pushed Google's executor host-side; weather's executor lives host-side too, though the topology Provider stays in tento-weather.)
  • The provider only ships read paths that don't need orchestrator coordination.

What goes where

ResponsibilityLives in
Stage names + topologyprovider.rs
Per-stage date-range overridesprovider.rs::stage_key_range
API calls + cell constructionexecutor.rs
Auth/client resolutioncontext.rs::<Provider>ApiContext (host-impl'd)
Row state lookup + persistencedeps.rs::<Provider>SyncDeps (host-impl'd)
Per-row synced-range trackingstate.rs::RowSyncState

The split between connector::<Provider>BackendDeps and sync_plugin::<Provider>SyncDeps is intentional: connector deps serve every Row method (read + write + sync), sync deps serve only the orchestrator executor. Keeping them separate means a host that doesn't enable sync-plugin doesn't have to implement the sync seams.

Documenting the choice

If you skip sync-plugin, say so in the connector module docs so it doesn't look like an oversight. Mirror the note in tento-google/src/connector/mod.rs:

//! Note: there is no `sync-plugin` feature for Google. The
//! orchestrator-side executor's `Send`-future bounds are difficult
//! to express generically over the Google-API client, so the host
//! supplies the executor wholesale.