v0.16.0 - Phase 2 (cloud, CSOT, load balancers)
Phase 2 of the roadmap is done.
CI tests covering standalone, replica set, sharded, and load-balanced topologies.
Test matrix (GitHub, 766 examples, 0 failures)
| Topology | Time | Pending |
|---|---|---|
| standalone | 23.86s | 219 |
| replica set | 3:36 | 104 |
| sharded | 7:05 | 112 |
| load-balanced | 2:58 | 137 |
Added
- auth: SASLprep (RFC 4013) for SCRAM-SHA-256 passwords. Printable ASCII is unchanged (no extra allocation). Usernames are not prepared.
- uri:
timeoutMS(CSOT deadline),srvMaxHosts,srvServiceName.mongodb+srvURI validation forloadBalanced,replicaSet, anddirectConnection.timeoutMS=0means infinite. NegativetimeoutMSis rejected. - sdam: SRV polling fiber for
mongodb+srv://on Sharded or Unknown. Adds and removes mongos hosts. Does not run in load-balanced mode. Monitor hellos keep the last 10 RTT samples for CSOT min RTT. - csot: Remaining
timeoutMSminus min RTT is sent asmaxTimeMS. Server code 50 (MaxTimeMSExpired) becomesError::Timeout.timeoutMSon the client, database, collection, CRUD, indexes, GridFS,commit_transaction, andabort_transaction.timeoutMode(cursorLifetime/iteration) on find, aggregate, listCollections, and listIndexes. Tailable awaitData sendsmaxTimeMSon find and caps getMore withmaxAwaitTimeMS. Change streams use iteration timeouts and resume in the samenextcall. GridFS uses one deadline for the whole upload/download (includinglistIndexesbefore the first write). Retryable reads/writes retry untiltimeoutMS(or forever iftimeoutMS=0). Wait-queue timeout isError::TimeoutwhentimeoutMSis set.wTimeoutMSis omitted whentimeoutMSis set. Official CSOT UTF is 28 files. - run command:
Database#run_commandand#run_cursor_command. The caller's document is copied. Not retryable. Database read/write concern is not applied.timeoutModeandcursorTypefollow CSOT.batch_size,comment, andmax_time_msgo on getMore only. Official run-command UTF is copied. - load balancer: Do not pre-create
minPoolSizesockets. RequireserviceIdon hello. Pin the TCP socket for a transaction and for an open cursor. Unpin returns the socket to the pool. Pool generation is perserviceId. Wait-queue timeout lists cursor / transaction / other in-use counts.poolClearedEventincludesserviceId. Command events includeserviceId. CMAPconnectionReadyEventandconnectionClosedEventwith a reason. UTFassertNumberConnectionsCheckedOut. Official load-balancer UTF runs (except the JSONskipReasonfile and one per-serviceIdtest that needs two mongos from HAProxy). - testing: UTF ops
iterateUntilDocumentOrError,iterateOnce,createFindCursor,runCursorCommand,createCommandCursor, GridFSupload/delete/rename,dropIndex/dropIndexes,assertNumberConnectionsCheckedOut. Official GridFS, collection-management, index-management, run-command, and CSOT JSON. CLAMredacted-commands.jsonand CRUDcreate-null-ids.jsonnow run. GitHub uploadstmp/utf-timing.log. GitHub load-balanced runs fullcrystal spec(HAProxy viaspec/support/run-load-balancer.sh). - change streams:
watchsendscommenton aggregate and getMore (string or document).showExpandedEventsandfullDocumentBeforeChangego on$changeStream. A labeled getMore error resumes with a new aggregate (getMore is not a retryable read).maxAwaitTimeMSmust be less thantimeoutMSwhen both are set.
Changed
- Cursor
finalizeno longer sendskillCursorsor touches the pool (GC thread). Call#close,#each, or a blockfind. - Load-balanced topology does not start monitor sockets. Sessions are always supported in that mode. LoadBalancer always allows retryable reads and writes (hello fields stay unset without monitors).
getMoreis not retried as a retryable read. Overload retry still runs.timeoutModeiteration starts a freshtimeoutMSon eachnext/try_next(change streams still own the deadline for resume).- HAProxy multi-mongos uses roundrobin and health-checks the normal mongos ports (not the PROXY v2 ports).
Fixed
- Upsert reply with
_id: nulldeserializes. Duplicate-key write errors exposecode. - GridFS
renameerrors when the file id is missing. UTFdownloadByNamehonorsrevision. - UTF matcher:
$datecanonical vs relaxed,$$typeint/long with$numberInt. - Find omits
tailableandawaitDataunless they are true. Sendingtailable: falsebroke Versioned API strict (crud-api-version-1-strict.json). - A
runCommandreply with a cursor id pins the load-balanced socket (the raw BSON is scanned forcursor.id). - UTF
createCollectionstores the collection entity and sendscapped/size/max. runCommanddoes not send$readPreferenceto a standalone, even when the caller asked for a non-primary mode.getMoreandkillCursorsdo not getreadConcern/afterClusterTime(explicit causal sessions).
Test info
Sharded takes more time than replica set because change-stream iterate on mongos often waits about 2 seconds. Load-balanced 2:58 is a full crystal spec (not the old official-LB-UTF-only job). It has more pending files, so it is faster than replica set and sharded.