Skip to content

Commit

Permalink
reload credentials when invalidated
Browse files Browse the repository at this point in the history
  • Loading branch information
stevensJourney committed Apr 5, 2024
1 parent 7b3878e commit c43f93b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ abstract class PowerSyncBackendConnector {
* These credentials may have expired already.
*/
suspend fun getCredentialsCached(): PowerSyncCredentials? {
cachedCredentials?.let { return it }
if (cachedCredentials != null) {
return cachedCredentials
}
return prefetchCredentials()
}

Expand All @@ -51,6 +53,7 @@ abstract class PowerSyncBackendConnector {
fetchRequest = fetchRequest ?: GlobalScope.async {
fetchCredentials().also { value ->
cachedCredentials = value
fetchRequest = null
}
}

Expand Down
32 changes: 23 additions & 9 deletions core/src/commonMain/kotlin/com/powersync/sync/SyncStream.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import io.ktor.client.request.get
import io.ktor.client.request.headers
import io.ktor.client.request.preparePost
import io.ktor.client.request.setBody
import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import io.ktor.utils.io.*
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -84,15 +86,21 @@ class SyncStream(
connector.invalidateCredentials()
invalidCredentials = false
}
streamingSyncIteration()
val state = streamingSyncIteration()
if (!state.retry) {
break;
}
} catch (e: Exception) {
println("SyncStream::streamingSync Error: $e")
invalidCredentials = true
updateStatus(
downloadError = e
)
} finally {
updateStatus(
connected = false,
connecting = true,
downloading = false,
downloadError = e
)
delay(retryDelay)
}
Expand Down Expand Up @@ -180,6 +188,14 @@ class SyncStream(
}

request.execute { httpResponse ->
if (httpResponse.status.value == 401) {
connector.invalidateCredentials()
}

if (httpResponse.status != HttpStatusCode.OK) {
throw RuntimeException("Received error when connecting to sync stream: ${httpResponse.bodyAsText()}")
}

val channel: ByteReadChannel = httpResponse.body()

while (!channel.isClosedForRead) {
Expand All @@ -191,7 +207,7 @@ class SyncStream(
}
}

private suspend fun streamingSyncIteration() {
private suspend fun streamingSyncIteration(): SyncStreamState {
val bucketEntries = bucketStorage.getBucketStates()
val initialBuckets = mutableMapOf<String, String>()

Expand All @@ -211,14 +227,11 @@ class SyncStream(
buckets = initialBuckets.map { (bucket, after) -> BucketRequest(bucket, after) },
)

streamingSyncRequest(req).retryWhen { cause, attempt ->
println("SyncStream::streamingSyncIteration Error: $cause")
delay(retryDelay)
println("SyncStream::streamingSyncIteration Retrying attempt: $attempt")
true
}.collect { value ->
streamingSyncRequest(req).collect { value ->
handleInstruction(value, state)
}

return state;
}

private suspend fun handleInstruction(
Expand Down Expand Up @@ -368,6 +381,7 @@ class SyncStream(
if (tokenExpiresIn <= 0) {
// Connection would be closed automatically right after this
println("Token expiring reconnect")
connector.invalidateCredentials()
state.retry = true
return state
}
Expand Down
2 changes: 1 addition & 1 deletion demos/hello-powersync/iosApp/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 4680f51fbb293d1385fb2467ada435cc1f16ab3d

COCOAPODS: 1.14.3
COCOAPODS: 1.13.0

0 comments on commit c43f93b

Please sign in to comment.