Add Kotlin Multiplatform SDK (JVM + iOS)#4471
Open
AndroidPoet wants to merge 4 commits intoclockworklabs:masterfrom
Open
Add Kotlin Multiplatform SDK (JVM + iOS)#4471AndroidPoet wants to merge 4 commits intoclockworklabs:masterfrom
AndroidPoet wants to merge 4 commits intoclockworklabs:masterfrom
Conversation
Kotlin/Multiplatform client SDK targeting JVM and iOS (arm64, simulator-arm64, x64) with full v2.bsatn.spacetimedb protocol support. Includes: - BSATN binary serialization/deserialization - WebSocket transport with Gzip/Brotli decompression - Client-side row cache with ref-counted rows - SQL subscriptions and one-off queries - Reducer invocation with result callbacks - Automatic reconnection with exponential backoff - Ping/pong keep-alive (30s idle timeout) - Comprehensive test suite (47 tests across 6 test files)
- Fix race in subscribe()/callReducer() where map registration happened in a launched coroutine but the message was sent immediately, allowing the server to respond before the callback was registered - Fix orphaned reducer callbacks on disconnect (failPendingOperations now clears reducerCallbacks) - Fix potential ConcurrentModificationException in TableHandle fire methods by iterating a snapshot of callback values - Add performance benchmarks, live integration tests, and edge case coverage (57 tests total, 0 failures)
Add CompressionMode enum (None/Gzip/Brotli) to allow callers to control server-to-client compression negotiation. Previously hardcoded to Gzip; now defaults to Gzip but can be overridden via DbConnectionBuilder.withCompression(). Add Keynote2BenchmarkTest that replicates the reference Rust benchmark client from templates/keynote-2: 10 connections, 16384 max in-flight reducers, Zipf-distributed account selection (alpha=0.5, 100k accounts), batched pipelining with 5s warmup + 5s measurement. Set test JVM heap to 1g to support the 10M pre-computed transfer pairs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Kotlin Multiplatform client SDK for SpacetimeDB, targeting JVM and iOS (arm64, simulator-arm64, x64). This brings first-class Kotlin/Java/Swift (via KMP interop) support to the SpacetimeDB ecosystem.
Why
There's currently no way to build native Android/JVM or iOS clients without going through the C# or Rust SDKs. The Kotlin SDK fills this gap and opens up the entire JVM and Apple platform ecosystem — Android apps, backend services, iOS apps, and any Kotlin target.
Architecture
v2.bsatn.spacetimedbsupport with BSATN binary serializationMutex-serialized message handling,atomicfufor transport flagswithCompression(). Gzip on both platforms viaexpect/actual, Brotli on JVM viaorg.brotli:decFeatures
subscribe,unsubscribe,subscribeToAllTables)suspendand callback variants)ReconnectPolicy)DbConnectionBuilder)File layout
Test coverage
57+ tests across 11 test files, all passing:
Performance
Micro-benchmarks (JVM, Apple M-series)
Keynote-2 TPS benchmark
Tested against the same benchmark methodology as
templates/keynote-2/spacetimedb-rust-client: 10 WebSocket connections, 16384 max in-flight reducers, Zipf-distributed account selection (alpha=0.5, 100k accounts), batched pipelining with 5s warmup + 5s measurement.Both clients running with
compression=Noneagainst SpacetimeDB 2.0.1 on localhost (Apple M-series):The Kotlin SDK achieves ~22% higher throughput on Apple Silicon. On x86 Linux the gap is expected to be narrower — both clients are firmly in the same performance tier. The Kotlin SDK adds no meaningful overhead over the raw Rust benchmark client.
Note: The two clients use different protocol versions (Rust: v1.bsatn, Kotlin: v2.bsatn) and different concurrency models (Rust: tokio threads, Kotlin: coroutines + Ktor OkHttp). This is not a language benchmark — it's a validation that the Kotlin SDK's architecture can fully saturate the server.
Live integration tested against
SpacetimeDB 2.0.1 local server with a Rust test module containing
playerandmessagetables + 4 reducers. Verified: WebSocket connect, identity/token exchange, SQL subscriptions, reducer calls with cache updates, one-off queries, error handling for invalid SQL/modules/reducers, token reuse across connections.Bug fixes included
callReducer()andsubscribe()now register callbacks synchronously before sending the message, preventing a race where the server response could arrive before the callback was registeredfailPendingOperations()now clears the reducer callback map alongside one-off query deferredsTableHandle.fireInsert/fireDelete/fireUpdatenow snapshot the callback map before iteration, preventingConcurrentModificationExceptionif a callback registers or removes other callbacksDependencies
Build
Future work