Skip to content

Commit f0dd60a

Browse files
authored
Switch RequestOption to accept long timeout only (#6289)
The `RequestOptions` class only customizable paramter, `timeout`, is now called `timeoutInMillis` and it's type is `Long`. Using `kotlin.time.Duration` in our public API, while convenient, introduces an issue with Java code. In short, `Duration` is exposed as `long` in the JVM, and that long can represent time in milliseconds, or nanoseconds. For clarity, we've fallback to long.
1 parent 5fccb61 commit f0dd60a

File tree

8 files changed

+27
-69
lines changed

8 files changed

+27
-69
lines changed

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/GenerativeModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ internal constructor(
8383
APIController(
8484
apiKey,
8585
modelName,
86-
requestOptions.toInternal(),
86+
requestOptions,
8787
"gl-kotlin/${KotlinVersion.CURRENT} fire/${BuildConfig.VERSION_NAME}",
8888
object : HeaderProvider {
8989
override val timeout: Duration

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/common/APIController.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.annotation.VisibleForTesting
2121
import com.google.firebase.vertexai.common.server.FinishReason
2222
import com.google.firebase.vertexai.common.util.decodeToFlow
2323
import com.google.firebase.vertexai.common.util.fullModelName
24+
import com.google.firebase.vertexai.type.RequestOptions
2425
import io.ktor.client.HttpClient
2526
import io.ktor.client.call.body
2627
import io.ktor.client.engine.HttpClientEngine
@@ -44,7 +45,9 @@ import io.ktor.http.contentType
4445
import io.ktor.http.headersOf
4546
import io.ktor.serialization.kotlinx.json.json
4647
import io.ktor.utils.io.ByteChannel
48+
import kotlin.math.max
4749
import kotlin.time.Duration
50+
import kotlin.time.Duration.Companion.seconds
4851
import kotlinx.coroutines.CoroutineName
4952
import kotlinx.coroutines.TimeoutCancellationException
5053
import kotlinx.coroutines.flow.Flow
@@ -115,7 +118,8 @@ internal constructor(
115118
HttpClient(httpEngine) {
116119
install(HttpTimeout) {
117120
requestTimeoutMillis = requestOptions.timeout.inWholeMilliseconds
118-
socketTimeoutMillis = 80_000
121+
socketTimeoutMillis =
122+
max(180.seconds.inWholeMilliseconds, requestOptions.timeout.inWholeMilliseconds)
119123
}
120124
install(ContentNegotiation) { json(JSON) }
121125
}

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/common/RequestOptions.kt

Lines changed: 0 additions & 46 deletions
This file was deleted.

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/internal/util/conversions.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import com.google.firebase.vertexai.type.HarmSeverity
4747
import com.google.firebase.vertexai.type.ImagePart
4848
import com.google.firebase.vertexai.type.Part
4949
import com.google.firebase.vertexai.type.PromptFeedback
50-
import com.google.firebase.vertexai.type.RequestOptions
5150
import com.google.firebase.vertexai.type.SafetyRating
5251
import com.google.firebase.vertexai.type.SafetySetting
5352
import com.google.firebase.vertexai.type.SerializationException
@@ -63,9 +62,6 @@ import org.json.JSONObject
6362

6463
private const val BASE_64_FLAGS = Base64.NO_WRAP
6564

66-
internal fun RequestOptions.toInternal() =
67-
com.google.firebase.vertexai.common.RequestOptions(timeout, apiVersion, endpoint)
68-
6965
internal fun Content.toInternal() =
7066
com.google.firebase.vertexai.common.shared.Content(
7167
this.role ?: "user",

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/type/RequestOptions.kt

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,26 @@
1717
package com.google.firebase.vertexai.type
1818

1919
import kotlin.time.Duration
20+
import kotlin.time.Duration.Companion.seconds
2021
import kotlin.time.DurationUnit
2122
import kotlin.time.toDuration
2223

23-
/**
24-
* Configurable options unique to how requests to the backend are performed.
25-
*
26-
* @property timeout the maximum amount of time for a request to take, from the first request to
27-
* first response.
28-
* @property apiVersion the api endpoint to call.
29-
*/
30-
class RequestOptions(val timeout: Duration) {
31-
32-
internal val endpoint = "https://firebaseml.googleapis.com"
33-
internal val apiVersion = "v2beta"
24+
/** Configurable options unique to how requests to the backend are performed. */
25+
class RequestOptions
26+
internal constructor(
27+
internal val timeout: Duration,
28+
internal val endpoint: String = "https://firebaseml.googleapis.com",
29+
internal val apiVersion: String = "v2beta",
30+
) {
3431

32+
/**
33+
* Constructor for RequestOptions.
34+
*
35+
* @param timeoutInMillis the maximum amount of time, in milliseconds, for a request to take, from
36+
* the first request to first response.
37+
*/
3538
@JvmOverloads
3639
constructor(
37-
timeout: Long? = Long.MAX_VALUE,
38-
) : this((timeout ?: Long.MAX_VALUE).toDuration(DurationUnit.MILLISECONDS))
40+
timeoutInMillis: Long = 180.seconds.inWholeMilliseconds
41+
) : this(timeout = timeoutInMillis.toDuration(DurationUnit.MILLISECONDS))
3942
}

firebase-vertexai/src/test/java/com/google/firebase/vertexai/common/APIControllerTests.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.google.firebase.vertexai.common.util.commonTest
2626
import com.google.firebase.vertexai.common.util.createResponses
2727
import com.google.firebase.vertexai.common.util.doBlocking
2828
import com.google.firebase.vertexai.common.util.prepareStreamingResponse
29+
import com.google.firebase.vertexai.type.RequestOptions
2930
import io.kotest.assertions.json.shouldContainJsonKey
3031
import io.kotest.assertions.throwables.shouldThrow
3132
import io.kotest.matchers.shouldBe
@@ -107,7 +108,7 @@ internal class RequestFormatTests {
107108
}
108109
}
109110

110-
mockEngine.requestHistory.first().url.host shouldBe "generativelanguage.googleapis.com"
111+
mockEngine.requestHistory.first().url.host shouldBe "firebaseml.googleapis.com"
111112
}
112113

113114
@Test
@@ -121,7 +122,7 @@ internal class RequestFormatTests {
121122
APIController(
122123
"super_cool_test_key",
123124
"gemini-pro-1.5",
124-
RequestOptions(endpoint = "https://my.custom.endpoint"),
125+
RequestOptions(timeout = 5.seconds, endpoint = "https://my.custom.endpoint"),
125126
mockEngine,
126127
TEST_CLIENT_ID,
127128
null,

firebase-vertexai/src/test/java/com/google/firebase/vertexai/common/util/tests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import com.google.firebase.vertexai.common.APIController
2222
import com.google.firebase.vertexai.common.GenerateContentRequest
2323
import com.google.firebase.vertexai.common.GenerateContentResponse
2424
import com.google.firebase.vertexai.common.JSON
25-
import com.google.firebase.vertexai.common.RequestOptions
2625
import com.google.firebase.vertexai.common.server.Candidate
2726
import com.google.firebase.vertexai.common.shared.Content
2827
import com.google.firebase.vertexai.common.shared.TextPart
28+
import com.google.firebase.vertexai.type.RequestOptions
2929
import io.kotest.matchers.collections.shouldNotBeEmpty
3030
import io.kotest.matchers.nulls.shouldNotBeNull
3131
import io.ktor.http.HttpStatusCode

firebase-vertexai/src/test/java/com/google/firebase/vertexai/util/tests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.google.firebase.vertexai.util
1818

1919
import com.google.firebase.vertexai.GenerativeModel
2020
import com.google.firebase.vertexai.common.APIController
21-
import com.google.firebase.vertexai.common.RequestOptions
21+
import com.google.firebase.vertexai.type.RequestOptions
2222
import io.kotest.matchers.collections.shouldNotBeEmpty
2323
import io.kotest.matchers.nulls.shouldNotBeNull
2424
import io.ktor.http.HttpStatusCode

0 commit comments

Comments
 (0)