Reputation: 51
I'm using the Java mongodb driver version 3.8.0 and mongodb 3.6.3.
I created a watch on a collection with this:
MongoCursor<ChangeStreamDocument<Document>> cursor = collection.watch().maxAwaitTime(500, TimeUnit.MILLISECONDS).iterator();
The documentation here states about maxAwaitTime:
The maximum amount of time for the server to wait on new documents to satisfy a change stream query.
However, what I'm seeing is that cursor.hasNext() returns only if there is a change on the collection, not when the time passed to maxAwaitTime has elapsed.
When I turn on mongodb's verbose logging I see maxWaitTime set as expected in the getMore command.
How do I cause my watch to timeout when there are no changes? It seems as though maxAwaitTime should do this. Why doesn't it work?
Upvotes: 5
Views: 2141
Reputation: 18835
MongoDB drivers implement change stream as an abstraction of a TAILABLE_AWAIT cursor, and maxAwaitTimeMS
is to specify a time limit for a getMore command on on TAILABLE_AWAIT cursor.
The way it works, MongoCursor continues to send getMore
command to the server in a loop until either:
Only when any of the event above happens, the cursor's method next() or hasNext() will return.
While none of the event above happens, the server's getMore
command will continue to be called by the Iterator
interface. The maxAwaitTime
specifies how long to wait before the getMore
command timed out while waiting for documents and returns even if there there are no documents found.
How do I cause my watch to timeout when there are no changes?
If your application requires a time out after maxAwaitTime
, the mongo-java-driver offers the tryNext() method on MongoCursor
. This method will return null
after maxAwaitTime if no documents were found, and can be called repeatedly by the application. See also JAVA-2965.
Upvotes: 6