-
Type: Bug
-
Resolution: Unresolved
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Kotlin, Reactive Streams
-
None
-
Java Drivers
Summary
When using find in the Kotlin driver, something in the conversion from Reactive Streams to Kotlin Flow implicitly sets the batchSize for both the find and getMore calls, ending up not respecting the server defaults as described in the docs.
Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).
The version used is
org.mongodb:mongodb-driver-kotlin-coroutine:5.2.1 but I expect the issue to be present in other versions too.
How to Reproduce
I put together a simple test that assumes a running Mongo server on port 27017.
import com.mongodb.ConnectionString import com.mongodb.MongoClientSettings import com.mongodb.client.model.Filters import com.mongodb.event.CommandListener import com.mongodb.event.CommandStartedEvent import com.mongodb.event.CommandSucceededEvent import com.mongodb.kotlin.client.coroutine.MongoClient import kotlinx.coroutines.flow.toList import kotlinx.coroutines.test.runTest import org.bson.BsonInt64 import org.bson.Document import org.junit.jupiter.api.Assertions.assertAll import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import java.util.UUID class MongoTest() { @Test fun `should run only one getMore`() = runTest { val randomDatabase = UUID.randomUUID().toString() val listener = Listener(mutableListOf(), mutableListOf()) val clientSettings = MongoClientSettings.builder() .applyConnectionString(ConnectionString("mongodb://127.0.0.1:27017")) .commandListenerList(listOf(listener)) .build() val database = MongoClient.create(clientSettings).getDatabase(databaseName = randomDatabase) database.runCommand(Document("ping", BsonInt64(1))) val collection = database.getCollection<Document>("test-collection") assertTrue(collection.insertMany(List(200) { Document() }).wasAcknowledged()) assertEquals(200, collection.find(Filters.empty()).toList().size) // first find should return 101 documents, the getMore should return the remaining ones assertAll( { assertEquals(listOf("ping", "insert", "find", "getMore"), listener.commands) }, { assertEquals(listOf("find" to 101, "getMore" to -1), listener.batchSizes) }, ) } class Listener( val commands: MutableList<String>, val batchSizes: MutableList<Pair<String, Int>>, ) : CommandListener { override fun commandStarted(event: CommandStartedEvent) { if (event.commandName in setOf("find", "getMore")) { val batchSize = event.command["batchSize"]?.asInt32()?.value ?: -1 batchSizes.add(event.commandName to batchSize) } } override fun commandSucceeded(event: CommandSucceededEvent) { commands.add(event.commandName) } } }
On a MacBook Pro 16 M1, the assertions fail as below, but I expect that batchSize to change depending on the machine it runs on.
org.opentest4j.AssertionFailedError: Expected :[ping, insert, find, getMore] Actual :[ping, insert, find, getMore, getMore, getMore] ... org.opentest4j.AssertionFailedError: Expected :[(find, 101), (getMore, -1)] Actual :[(find, 64), (getMore, 64), (getMore, 64), (getMore, 64)]
Additional Background
Please provide any additional background information that may be helpful in diagnosing the bug.