Skip to content

Commit abbb5eb

Browse files
committed
fix(model-client): use streaming for large responses
According to what is discussed in https://youtrack.jetbrains.com/issue/KTOR-5286/, use prepareGet instead of Get for all GET requests from model-client that potentially stream the whole model to avoid running into memory issues and NegativeArraySize exceptions. I was not able to come up with a working tests for this while avoiding to actually use as much memory as MAX_INT bytes.
1 parent ba47a21 commit abbb5eb

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

model-client/src/commonMain/kotlin/org/modelix/model/client2/ModelClientV2.kt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import io.ktor.client.plugins.expectSuccess
2424
import io.ktor.client.request.HttpRequestBuilder
2525
import io.ktor.client.request.get
2626
import io.ktor.client.request.post
27+
import io.ktor.client.request.prepareGet
2728
import io.ktor.client.request.put
2829
import io.ktor.client.request.setBody
2930
import io.ktor.client.statement.HttpResponse
@@ -240,7 +241,7 @@ class ModelClientV2(
240241

241242
override suspend fun pull(branch: BranchReference, lastKnownVersion: IVersion?): IVersion {
242243
require(lastKnownVersion is CLVersion?)
243-
val response = httpClient.get {
244+
return httpClient.prepareGet {
244245
url {
245246
takeFrom(baseUrl)
246247
appendPathSegmentsEncodingSlash("repositories", branch.repositoryId.id, "branches", branch.branchName)
@@ -249,29 +250,30 @@ class ModelClientV2(
249250
}
250251
}
251252
useVersionStreamFormat()
253+
}.execute { response ->
254+
val receivedVersion = createVersion(lastKnownVersion, response.readVersionDelta())
255+
LOG.debug { "${clientId.toString(16)}.pull($branch, $lastKnownVersion) -> $receivedVersion" }
256+
receivedVersion
252257
}
253-
val receivedVersion = createVersion(lastKnownVersion, response.readVersionDelta())
254-
LOG.debug { "${clientId.toString(16)}.pull($branch, $lastKnownVersion) -> $receivedVersion" }
255-
return receivedVersion
256258
}
257259

258260
override suspend fun pullIfExists(branch: BranchReference): IVersion? {
259-
val response = httpClient.get {
261+
return httpClient.prepareGet {
260262
expectSuccess = false
261263
url {
262264
takeFrom(baseUrl)
263265
appendPathSegmentsEncodingSlash("repositories", branch.repositoryId.id, "branches", branch.branchName)
264266
}
265267
useVersionStreamFormat()
268+
}.execute { response ->
269+
val receivedVersion = when (response.status) {
270+
HttpStatusCode.NotFound -> null
271+
HttpStatusCode.OK -> createVersion(null, response.readVersionDelta())
272+
else -> throw ResponseException(response, response.bodyAsText())
273+
}
274+
LOG.debug { "${clientId.toString(16)}.pullIfExists($branch) -> $receivedVersion" }
275+
receivedVersion
266276
}
267-
268-
val receivedVersion = when (response.status) {
269-
HttpStatusCode.NotFound -> null
270-
HttpStatusCode.OK -> createVersion(null, response.readVersionDelta())
271-
else -> throw ResponseException(response, response.bodyAsText())
272-
}
273-
LOG.debug { "${clientId.toString(16)}.pullIfExists($branch) -> $receivedVersion" }
274-
return receivedVersion
275277
}
276278

277279
override suspend fun pullHash(branch: BranchReference): String {
@@ -302,7 +304,7 @@ class ModelClientV2(
302304
override suspend fun poll(branch: BranchReference, lastKnownVersion: IVersion?): IVersion {
303305
require(lastKnownVersion is CLVersion?)
304306
LOG.debug { "${clientId.toString(16)}.poll($branch, $lastKnownVersion)" }
305-
val response = httpClient.get {
307+
return httpClient.prepareGet {
306308
url {
307309
takeFrom(baseUrl)
308310
appendPathSegmentsEncodingSlash("repositories", branch.repositoryId.id, "branches", branch.branchName, "poll")
@@ -311,10 +313,11 @@ class ModelClientV2(
311313
}
312314
}
313315
useVersionStreamFormat()
316+
}.execute { response ->
317+
val receivedVersion = createVersion(lastKnownVersion, response.readVersionDelta())
318+
LOG.debug { "${clientId.toString(16)}.poll($branch, $lastKnownVersion) -> $receivedVersion" }
319+
receivedVersion
314320
}
315-
val receivedVersion = createVersion(lastKnownVersion, response.readVersionDelta())
316-
LOG.debug { "${clientId.toString(16)}.poll($branch, $lastKnownVersion) -> $receivedVersion" }
317-
return receivedVersion
318321
}
319322

320323
override suspend fun <R> query(branch: BranchReference, body: (IMonoStep<INode>) -> IMonoStep<R>): R {

0 commit comments

Comments
 (0)