kotlinx.rpc 0.9.1 Help

Strict mode

Starting with version 0.5.0, the library introduced major changes to the service APIs. The following declarations are now restricted:

StateFlow and SharedFlow

Deprecation level: ERROR

@Rpc interface Service { suspend fun old(): StateFlow<Int> // deprecated suspend fun new(): Flow<Int> // use .stateIn on the client side }

Fields

Deprecation level: ERROR

@Rpc interface Service { val old: Flow<Int> // deprecated suspend fun new(): Flow<Int> // store flow locally }

Nested Flows

Deprecation level: ERROR

@Rpc interface Service { suspend fun old(): Flow<Flow<Int>> // deprecated // no particular alternative, depends on the use case }

Not top-level server flows

Deprecation level: ERROR

data class SpotifyWrapped(val myMusicFlow: Flow<Rap>, val extra: Data) @Rpc interface Service { suspend fun old(): SpotifyWrapped // deprecated // one should consider message delivery order when calling these suspend fun new(): Flow<Rap> suspend fun getData(): Data }

Non-suspending server flows

Deprecation level: ERROR

data class SpotifyWrapped(val extra: Data) @Rpc interface Service { suspend fun old(): Flow<SpotifyWrapped> // deprecated fun new(): Flow<SpotifyWrapped> }

Stream scopes management

Deprecation level: ERROR

The next stream scope management structures are deprecated due to the introduction of non-suspending server flows:

  • StreamScoped class and function

  • streamScoped function

  • invokeOnStreamScopeCompletion function

  • withStreamScope function

Stream collection and completion is now bound to the CoroutineScope in which the flow was collected (server-side flows) or produced (client-side flows).

0.5.x:

@Rpc interface Service { suspend fun oldClient(flow: Flow<Int>) suspend fun oldServer(): Flow<Int> } suspend fun consumer(service: Service) { streamScoped { service.oldClient(flow { /* ... */ }) service.oldServer().collect { // ... } } }

0.6.x:

@Rpc interface Service { suspend fun newClient(flow: Flow<Int>) fun newServer(): Flow<Int> } fun consumer(service: Service, scope: CoroutineScope) { val flow = service.newServer() scope.launch { service.newClient(flow { /* ... */ }) flow.collect { // ... } } } // or suspend fun consumer(service: Service) { service.newClient(flow { /* ... */ }) service.newServer().collect { // ... } }
Last modified: 06 July 2025