lazy results with with-open #233
Replies: 3 comments
-
It does not but eventually something triggers the evaluation of such lazy collections. Even basic tutorials usually print results out, integration tests perform assertions on collections, data is passed somewhere where evaluation will be forced. It's a philosophical question whether libraries should force the evaluation. Given that a result set can contain many thousands of documents, it can have dire operational consequences. |
Beta Was this translation helpful? Give feedback.
-
Consider using discussions for questions. They have been around for a good couple of years now. |
Beta Was this translation helpful? Give feedback.
-
Good point, I always forget these exists.
Sure, usually something eventually at least partially evaluates the results. But my question was more about closing the cursor(s): should I be worried that mapping over the cursor creates a new cursor which is never closed? |
Beta Was this translation helpful? Give feedback.
-
I'm very much a beginner in
monger
(and mongo) so apologies if I'm asking something obvious: how doesmonger
close cursor(s) when returning lazy results from queries? Or does it?I originally found this issue (or rather question) when reviewing some code, but a similar pattern can be found right here in
monger
. For example, in monger.query/exec, we can see that the function wraps the cursor withwith-open
and yet it returns a lazy seq operating on said cursor. To my untrained eye this looks a lot like a typical "I accidentally closed a resource before evaluating the lazy sequence and got an Exception later" situation, yet that does not occur here.As far as I can tell, what happens is that
map
calls(seq cursor)
seq
(inclojure.lang.RT
) callsseqFrom
which callschunkIteratorSeq(((Iterable) coll).iterator())
.iterator()
invokes/iscom.mongodb.DBCursor.iterator()
, which returnsthis.copy
(link) ("Creates a copy of this cursor object that can be iterated")chunkIteratorSeq
returns a lazy seq, which pulls data from the iterator, which pulls data from the copied cursorwith-open
closes the outer cursorAlso note that the docstring for
.iterator()
inDBCursor
says "Note that use of this method does not let you call close the underlying cursor in the case of either an exception or an early break. The preferred method of iteration is to use DBCursor as an Iterator, so that you can call close() on it in a finally block."Note that if one writes
(map some-fn (iterator-seq cursor))
then we will skip the.iterator()
call and iterate on the original cursor and end up IIRC with a "cursor has already been closed" error.Beta Was this translation helpful? Give feedback.
All reactions