From 4fbf12455d1d8ce78cf2a8b4d55d00d5ab2f9a70 Mon Sep 17 00:00:00 2001 From: "marcin.cebo" <marcin.cebo@pubnub.com> Date: Mon, 20 Jan 2025 12:45:47 +0100 Subject: [PATCH] Added fileRequestTimeout config property. --- kotlin-js-store/yarn.lock | 8 ++--- .../com/pubnub/api/java/v2/PNConfiguration.kt | 24 ++++++++++++++ .../internal/java/v2/PNConfigurationImpl.kt | 10 ++++++ .../java/v2/PNConfigurationImplTest.kt | 3 ++ .../com/pubnub/api/v2/PNConfiguration.kt | 33 +++++++++++++++++++ .../internal/managers/RetrofitManager.kt | 25 ++++++++------ .../pubnub/internal/v2/PNConfigurationImpl.kt | 5 +++ .../com/pubnub/api/legacy/PubNubImplTest.kt | 2 ++ .../internal/managers/RetrofitManagerTest.kt | 16 ++++++--- .../internal/v2/PNConfigurationImplTest.kt | 3 ++ 10 files changed, 111 insertions(+), 18 deletions(-) diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index ba1a895d3..1f3427e84 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -659,10 +659,10 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pubnub@8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.4.0.tgz#8a5fdd3af9783abb1de44ea4145107e296c8394d" - integrity sha512-HvkFhn4XcfR1wdJv4paX94I0TT4UBHW/vIuYnS+6XuoSx0AunJMCk5wbKnSesmdbzYUZa8Ag3H1mJQZKuyRy8Q== +pubnub@8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.4.1.tgz#5f6f19e84d3187dc8aee0a458bd6b05e90d43e6a" + integrity sha512-mPlwVoHJDWPasZx52UfSMiPX5TATm5A+ficSogyqDqTQ4w5EQnwxH+PJdsWc0mPnlT051jM1vIISMeM0fQ30CQ== dependencies: agentkeepalive "^3.5.2" buffer "^6.0.3" diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt index 7330321ce..12b046557 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt @@ -163,6 +163,17 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration { */ val nonSubscribeReadTimeout: Int + /** + * Timeout for file-related operations (e.g. sendFile, listChannelFiles, deleteFile, etc.) + * This timeout applies to the entire call which includes: resolving DNS, connecting, writing the request body, + * server processing and reading the response body. + * + * The value is in seconds. + * + * Defaults to 300 seconds + */ + val fileRequestTimeout: Int + /** * If operating behind a misbehaving proxy, allow the client to shuffle the subdomains. * @@ -394,6 +405,8 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration { override fun nonSubscribeReadTimeout(nonSubscribeReadTimeout: Int): Builder + override fun fileRequestTimeout(fileRequestTimeout: Int): Builder + /** * If operating behind a misbehaving proxy, allow the client to shuffle the subdomains. * @@ -624,6 +637,17 @@ interface PNConfigurationOverride : com.pubnub.api.v2.PNConfigurationOverride { */ fun nonSubscribeReadTimeout(nonSubscribeReadTimeout: Int): Builder + /** + * Timeout for file-related operations (e.g. sendFile, listChannelFiles, deleteFile, etc.) + * This timeout applies to the entire call which includes: resolving DNS, connecting, writing the request body, + * server processing and reading the response body. + * + * The value is in seconds. + * + * Defaults to 300 seconds + */ + fun fileRequestTimeout(fileRequestTimeout: Int): Builder + /** * Create a [PNConfiguration] object with values from this builder. */ diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt index c75f9bf0c..33b920bc7 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt @@ -36,6 +36,7 @@ class PNConfigurationImpl( override val subscribeTimeout: Int = SUBSCRIBE_TIMEOUT, override val connectTimeout: Int = CONNECT_TIMEOUT, override val nonSubscribeReadTimeout: Int = NON_SUBSCRIBE_REQUEST_TIMEOUT, + override val fileRequestTimeout: Int = FILE_REQUEST_TIMEOUT, override val cacheBusting: Boolean = false, override val suppressLeaveEvents: Boolean = false, override val maintainPresenceState: Boolean = true, @@ -79,6 +80,7 @@ class PNConfigurationImpl( const val NON_SUBSCRIBE_REQUEST_TIMEOUT = 10 const val SUBSCRIBE_TIMEOUT = 310 const val CONNECT_TIMEOUT = 5 + const val FILE_REQUEST_TIMEOUT = 300 } class Builder internal constructor(defaultConfiguration: com.pubnub.api.v2.PNConfiguration) : @@ -207,6 +209,13 @@ class PNConfigurationImpl( override var nonSubscribeReadTimeout: Int = defaultConfiguration.nonSubscribeReadTimeout + override fun fileRequestTimeout(fileRequestTimeout: Int): Builder { + this.fileRequestTimeout = fileRequestTimeout + return this + } + + override var fileRequestTimeout: Int = defaultConfiguration.fileRequestTimeout + override fun cacheBusting(cacheBusting: Boolean): Builder { this.cacheBusting = cacheBusting return this @@ -385,6 +394,7 @@ class PNConfigurationImpl( subscribeTimeout = subscribeTimeout, connectTimeout = connectTimeout, nonSubscribeReadTimeout = nonSubscribeReadTimeout, + fileRequestTimeout = fileRequestTimeout, cacheBusting = cacheBusting, suppressLeaveEvents = suppressLeaveEvents, maintainPresenceState = maintainPresenceState, diff --git a/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/PNConfigurationImplTest.kt b/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/PNConfigurationImplTest.kt index eb820b40e..e63f313c6 100644 --- a/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/PNConfigurationImplTest.kt +++ b/pubnub-gson/pubnub-gson-impl/src/test/kotlin/com/pubnub/internal/java/v2/PNConfigurationImplTest.kt @@ -84,6 +84,7 @@ class PNConfigurationImplTest { .subscribeTimeout(3) .connectTimeout(4) .nonSubscribeReadTimeout(5) + .fileRequestTimeout(10) .cacheBusting(true) .suppressLeaveEvents(true) .maintainPresenceState(false) @@ -124,6 +125,7 @@ class PNConfigurationImplTest { assertEquals(3, configuration.subscribeTimeout) assertEquals(4, configuration.connectTimeout) assertEquals(5, configuration.nonSubscribeReadTimeout) + assertEquals(10, configuration.fileRequestTimeout) assertEquals(true, configuration.cacheBusting) assertEquals(true, configuration.suppressLeaveEvents) assertEquals(false, configuration.maintainPresenceState) @@ -170,6 +172,7 @@ class PNConfigurationImplTest { assertEquals(expectedDefaults.subscribeTimeout, builder.subscribeTimeout) assertEquals(expectedDefaults.connectTimeout, builder.connectTimeout) assertEquals(expectedDefaults.nonSubscribeReadTimeout, builder.nonSubscribeReadTimeout) + assertEquals(expectedDefaults.fileRequestTimeout, builder.fileRequestTimeout) assertEquals(expectedDefaults.cacheBusting, builder.cacheBusting) assertEquals(expectedDefaults.suppressLeaveEvents, builder.suppressLeaveEvents) assertEquals(expectedDefaults.maintainPresenceState, builder.maintainPresenceState) diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt index af2d5c353..52962063f 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt @@ -149,6 +149,17 @@ actual interface PNConfiguration { */ val nonSubscribeReadTimeout: Int + /** + * Timeout for file-related operations (e.g. sendFile, listChannelFiles, deleteFile, etc.) + * This timeout applies to the entire call which includes: resolving DNS, connecting, writing the request body, + * server processing and reading the response body. + * + * The value is in seconds. + * + * Defaults to 300 seconds + */ + val fileRequestTimeout: Int + /** * If operating behind a misbehaving proxy, allow the client to shuffle the subdomains. * @@ -456,6 +467,17 @@ actual interface PNConfiguration { */ var nonSubscribeReadTimeout: Int + /** + * Timeout for file-related operations (e.g. sendFile, listChannelFiles, deleteFile, etc.) + * This timeout applies to the entire call which includes: resolving DNS, connecting, writing the request body, + * server processing and reading the response body. + * + * The value is in seconds. + * + * Defaults to 300 seconds + */ + var fileRequestTimeout: Int + /** * If operating behind a misbehaving proxy, allow the client to shuffle the subdomains. * @@ -701,6 +723,17 @@ interface PNConfigurationOverride { */ var nonSubscribeReadTimeout: Int + /** + * Timeout for file-related operations (e.g. sendFile, listChannelFiles, deleteFile, etc.) + * This timeout applies to the entire call which includes: resolving DNS, connecting, writing the request body, + * server processing and reading the response body. + * + * The value is in seconds. + * + * Defaults to 300 seconds + */ + val fileRequestTimeout: Int + /** * Create a [PNConfiguration] object with values from this builder. */ diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt index 93a78e190..e36fcc0b0 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/RetrofitManager.kt @@ -31,7 +31,8 @@ class RetrofitManager( private val configuration: PNConfiguration, @get:TestOnly internal var transactionClientInstance: OkHttpClient? = null, @get:TestOnly internal var subscriptionClientInstance: OkHttpClient? = null, - @get:TestOnly internal var noSignatureClientInstance: OkHttpClient? = null, + @get:TestOnly internal var noSignatureClientInstanceForFiles: OkHttpClient? = null, + @get:TestOnly internal var signatureClientInstanceForFiles: OkHttpClient? = null ) { private var signatureInterceptor: SignatureInterceptor = SignatureInterceptor(configuration) @@ -58,20 +59,21 @@ class RetrofitManager( configuration, retrofitManager.transactionClientInstance, retrofitManager.subscriptionClientInstance, - retrofitManager.noSignatureClientInstance, + retrofitManager.noSignatureClientInstanceForFiles, + retrofitManager.signatureClientInstanceForFiles ) init { if (!configuration.googleAppEngineNetworking) { - transactionClientInstance = createOkHttpClient(configuration.nonSubscribeReadTimeout, parentOkHttpClient = transactionClientInstance) - subscriptionClientInstance = createOkHttpClient(configuration.subscribeTimeout, parentOkHttpClient = subscriptionClientInstance) - noSignatureClientInstance = - createOkHttpClient(configuration.nonSubscribeReadTimeout, withSignature = false, parentOkHttpClient = noSignatureClientInstance) + transactionClientInstance = createOkHttpClient(readTimeout = configuration.nonSubscribeReadTimeout, parentOkHttpClient = transactionClientInstance) + subscriptionClientInstance = createOkHttpClient(readTimeout = configuration.subscribeTimeout, parentOkHttpClient = subscriptionClientInstance) + noSignatureClientInstanceForFiles = createOkHttpClient(callTimeout = configuration.fileRequestTimeout, withSignature = false, parentOkHttpClient = noSignatureClientInstanceForFiles) + signatureClientInstanceForFiles = createOkHttpClient(callTimeout = configuration.fileRequestTimeout, parentOkHttpClient = signatureClientInstanceForFiles) } val transactionInstance = createRetrofit(transactionClientInstance) val subscriptionInstance = createRetrofit(subscriptionClientInstance) - val noSignatureInstance = createRetrofit(noSignatureClientInstance) + val noSignatureInstance = createRetrofit(noSignatureClientInstanceForFiles) timeService = transactionInstance.create(TimeService::class.java) publishService = transactionInstance.create(PublishService::class.java) @@ -94,9 +96,10 @@ class RetrofitManager( } private fun createOkHttpClient( - readTimeout: Int, + readTimeout: Int = 0, // 0 means no timeout, + callTimeout: Int = 0, // 0 means no timeout, withSignature: Boolean = true, - parentOkHttpClient: OkHttpClient? = null, + parentOkHttpClient: OkHttpClient? = null ): OkHttpClient { val okHttpBuilder = parentOkHttpClient?.newBuilder() ?: OkHttpClient.Builder() @@ -104,6 +107,7 @@ class RetrofitManager( .retryOnConnectionFailure(false) .readTimeout(readTimeout.toLong(), TimeUnit.SECONDS) .connectTimeout(configuration.connectTimeout.toLong(), TimeUnit.SECONDS) + .callTimeout(callTimeout.toLong(), TimeUnit.SECONDS) with(configuration) { if (logVerbosity == PNLogVerbosity.BODY) { @@ -163,7 +167,8 @@ class RetrofitManager( fun destroy(force: Boolean = false) { closeExecutor(transactionClientInstance, force) closeExecutor(subscriptionClientInstance, force) - closeExecutor(noSignatureClientInstance, force) + closeExecutor(noSignatureClientInstanceForFiles, force) + closeExecutor(signatureClientInstanceForFiles, force) } private fun closeExecutor( diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt index c4c135a27..cb714e589 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt @@ -36,6 +36,7 @@ class PNConfigurationImpl( override val subscribeTimeout: Int = SUBSCRIBE_TIMEOUT, override val connectTimeout: Int = CONNECT_TIMEOUT, override val nonSubscribeReadTimeout: Int = NON_SUBSCRIBE_REQUEST_TIMEOUT, + override val fileRequestTimeout: Int = FILE_REQUEST_TIMEOUT, override val cacheBusting: Boolean = false, override val suppressLeaveEvents: Boolean = false, override val maintainPresenceState: Boolean = true, @@ -79,6 +80,7 @@ class PNConfigurationImpl( const val NON_SUBSCRIBE_REQUEST_TIMEOUT = 10 const val SUBSCRIBE_TIMEOUT = 310 const val CONNECT_TIMEOUT = 5 + const val FILE_REQUEST_TIMEOUT = 300 } class Builder(defaultConfiguration: PNConfiguration) : @@ -140,6 +142,8 @@ class PNConfigurationImpl( override var nonSubscribeReadTimeout: Int = defaultConfiguration.nonSubscribeReadTimeout + override var fileRequestTimeout: Int = defaultConfiguration.fileRequestTimeout + override var cacheBusting: Boolean = defaultConfiguration.cacheBusting override var suppressLeaveEvents: Boolean = defaultConfiguration.suppressLeaveEvents @@ -201,6 +205,7 @@ class PNConfigurationImpl( subscribeTimeout = subscribeTimeout, connectTimeout = connectTimeout, nonSubscribeReadTimeout = nonSubscribeReadTimeout, + fileRequestTimeout = fileRequestTimeout, cacheBusting = cacheBusting, suppressLeaveEvents = suppressLeaveEvents, maintainPresenceState = maintainPresenceState, diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt index 1fec4de8b..7f2277955 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/PubNubImplTest.kt @@ -44,12 +44,14 @@ class PubNubImplTest : BaseTest() { config.connectTimeout = 4000 config.nonSubscribeRequestTimeout = 5000 config.retryConfiguration = RetryConfiguration.None + config.fileRequestTimeout = 400 // initPubNub() assertEquals("https://ps.pndsn.com", pubnub.baseUrl()) assertEquals(3000, config.subscribeTimeout) assertEquals(4000, config.connectTimeout) assertEquals(5000, config.nonSubscribeRequestTimeout) + assertEquals(400, config.fileRequestTimeout) } @Test diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/managers/RetrofitManagerTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/managers/RetrofitManagerTest.kt index 5775057fc..69abb74d9 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/managers/RetrofitManagerTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/managers/RetrofitManagerTest.kt @@ -21,8 +21,12 @@ class RetrofitManagerTest : BaseTest() { clonedRetrofitManager.transactionClientInstance!!.dispatcher, ) Assert.assertEquals( - retrofitManager.noSignatureClientInstance!!.dispatcher, - clonedRetrofitManager.noSignatureClientInstance!!.dispatcher, + retrofitManager.noSignatureClientInstanceForFiles!!.dispatcher, + clonedRetrofitManager.noSignatureClientInstanceForFiles!!.dispatcher, + ) + Assert.assertEquals( + retrofitManager.signatureClientInstanceForFiles!!.dispatcher, + clonedRetrofitManager.signatureClientInstanceForFiles!!.dispatcher ) Assert.assertEquals( @@ -34,8 +38,12 @@ class RetrofitManagerTest : BaseTest() { clonedRetrofitManager.transactionClientInstance!!.connectionPool, ) Assert.assertEquals( - retrofitManager.noSignatureClientInstance!!.connectionPool, - clonedRetrofitManager.noSignatureClientInstance!!.connectionPool, + retrofitManager.noSignatureClientInstanceForFiles!!.connectionPool, + clonedRetrofitManager.noSignatureClientInstanceForFiles!!.connectionPool, + ) + Assert.assertEquals( + retrofitManager.signatureClientInstanceForFiles!!.connectionPool, + clonedRetrofitManager.signatureClientInstanceForFiles!!.connectionPool ) } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/v2/PNConfigurationImplTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/v2/PNConfigurationImplTest.kt index 857ddd20e..7d32d245a 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/v2/PNConfigurationImplTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/v2/PNConfigurationImplTest.kt @@ -115,6 +115,7 @@ class PNConfigurationImplTest { subscribeTimeout = 3 connectTimeout = 4 nonSubscribeRequestTimeout = 5 + fileRequestTimeout = 10 cacheBusting = true suppressLeaveEvents = true maintainPresenceState = false @@ -156,6 +157,7 @@ class PNConfigurationImplTest { assertEquals(3, configuration.subscribeTimeout) assertEquals(4, configuration.connectTimeout) assertEquals(5, configuration.nonSubscribeRequestTimeout) + assertEquals(10, configuration.fileRequestTimeout) assertEquals(true, configuration.cacheBusting) assertEquals(true, configuration.suppressLeaveEvents) assertEquals(false, configuration.maintainPresenceState) @@ -202,6 +204,7 @@ class PNConfigurationImplTest { assertEquals(expectedDefaults.subscribeTimeout, builder.subscribeTimeout) assertEquals(expectedDefaults.connectTimeout, builder.connectTimeout) assertEquals(expectedDefaults.nonSubscribeRequestTimeout, builder.nonSubscribeRequestTimeout) + assertEquals(expectedDefaults.fileRequestTimeout, builder.fileRequestTimeout) assertEquals(expectedDefaults.cacheBusting, builder.cacheBusting) assertEquals(expectedDefaults.suppressLeaveEvents, builder.suppressLeaveEvents) assertEquals(expectedDefaults.maintainPresenceState, builder.maintainPresenceState)