git.iko.soy/opencode-android
on a40d3a2 help sign in
opencode-android/app/src/main/java/soy/iko/opencode/di/OpencodeConnection.kt
41 lines 1.7 kB history raw
1package soy.iko.opencode.di
3import soy.iko.opencode.data.model.ServerProfile
4import soy.iko.opencode.data.network.EventStreamClient
5import soy.iko.opencode.data.network.HttpClientFactory
6import soy.iko.opencode.data.network.OpencodeApiClient
7import soy.iko.opencode.data.repo.SessionRepository
8import kotlinx.coroutines.CoroutineScope
9import kotlinx.coroutines.Dispatchers
10import kotlinx.coroutines.SupervisorJob
11import kotlinx.coroutines.cancel
13/**
14 * An active connection to one opencode server. Bundles the Ktor client, REST API,
15 * SSE event stream, and the reducing repository, all sharing a connection-scoped
16 * coroutine scope that is cancelled on [close].
17 */
18open class OpencodeConnection(val profile: ServerProfile) {
20 protected constructor() : this(ServerProfile(id = "", label = "", baseUrl = "http://localhost"))
22 private val scopeJob = SupervisorJob()
23 private val scope by lazy { CoroutineScope(scopeJob + Dispatchers.IO) }
24 private val client by lazy { HttpClientFactory.create(profile) }
26 open val api: OpencodeApiClient by lazy { OpencodeApiClient(client) }
27 open val events: EventStreamClient by lazy { EventStreamClient(client, scope) }
28 open val repository: SessionRepository by lazy { SessionRepository(api, events) }
30 /**
31 * Cancel the coroutine scope and wait for in-flight work (including the SSE reader)
32 * to wind down before closing the HTTP client. Calling client.close() while the SSE
33 * coroutine is still mid-request produces a spurious "stream error, will retry"
34 * warning during normal teardown.
35 */
36 open suspend fun close() {
37 scope.cancel()
38 scopeJob.join()
39 runCatching { client.close() }
40 }