2424import com .mongodb .client .model .ValidationAction ;
2525import com .mongodb .client .model .ValidationLevel ;
2626import com .mongodb .connection .BufferProvider ;
27+ import com .mongodb .internal .ClientSideOperationTimeoutFactories ;
2728import com .mongodb .internal .operation .BatchCursor ;
2829import com .mongodb .internal .operation .CommandReadOperation ;
2930import com .mongodb .internal .operation .CreateCollectionOperation ;
4445import java .util .List ;
4546import java .util .Set ;
4647import java .util .concurrent .ConcurrentHashMap ;
48+ import java .util .concurrent .TimeUnit ;
4749
4850import static com .mongodb .DBCollection .createWriteConcernException ;
4951import static com .mongodb .MongoClientSettings .getDefaultCodecRegistry ;
5052import static com .mongodb .MongoNamespace .checkDatabaseNameValidity ;
5153import static com .mongodb .ReadPreference .primary ;
54+ import static com .mongodb .assertions .Assertions .isTrueArgument ;
5255import static com .mongodb .assertions .Assertions .notNull ;
56+ import static java .util .concurrent .TimeUnit .MILLISECONDS ;
5357
5458/**
5559 * A thread-safe client view of a logical database in a MongoDB cluster. A DB instance can be achieved from a {@link MongoClient} instance
@@ -77,6 +81,8 @@ public class DB {
7781 private volatile ReadPreference readPreference ;
7882 private volatile WriteConcern writeConcern ;
7983 private volatile ReadConcern readConcern ;
84+ @ Nullable
85+ private volatile Long timeoutMS ;
8086
8187 DB (final MongoClient mongo , final String name , final OperationExecutor executor ) {
8288 checkDatabaseNameValidity (name );
@@ -164,6 +170,62 @@ public ReadConcern getReadConcern() {
164170 return readConcern != null ? readConcern : mongo .getReadConcern ();
165171 }
166172
173+ /**
174+ * The time limit for the full execution of an operation.
175+ *
176+ * <p>If set the following deprecated options will be ignored:
177+ * {@code waitQueueTimeoutMS}, {@code socketTimeoutMS}, {@code wTimeoutMS}, {@code maxTimeMS} and {@code maxCommitTimeMS}</p>
178+ *
179+ * <ul>
180+ * <li>{@code null} means that the timeout mechanism for operations will defer to using:
181+ * <ul>
182+ * <li>{@code waitQueueTimeoutMS}: The maximum wait time in milliseconds that a thread may wait for a connection to become
183+ * available</li>
184+ * <li>{@code socketTimeoutMS}: How long a send or receive on a socket can take before timing out.</li>
185+ * <li>{@code wTimeoutMS}: How long the server will wait for the write concern to be fulfilled before timing out.</li>
186+ * <li>{@code maxTimeMS}: The cumulative time limit for processing operations on a cursor.
187+ * See: <a href="https://docs.mongodb.com/manual/reference/method/cursor.maxTimeMS">cursor.maxTimeMS</a>.</li>
188+ * <li>{@code maxCommitTimeMS}: The maximum amount of time to allow a single {@code commitTransaction} command to execute.
189+ * See: {@link TransactionOptions#getMaxCommitTime}.</li>
190+ * </ul>
191+ * </li>
192+ * <li>{@code 0} means infinite timeout.</li>
193+ * <li>{@code > 0} The time limit to use for the full execution of an operation.</li>
194+ * </ul>
195+ *
196+ * @param timeUnit the time unit to return the result in
197+ * @return the time limit for the full execution of an operation or null.
198+ * @since 4.x
199+ */
200+ @ Nullable
201+ public Long getTimeout (final TimeUnit timeUnit ) {
202+ Long localTimeoutMS = timeoutMS ;
203+ if (localTimeoutMS != null ) {
204+ return notNull ("timeUnit" , timeUnit ).convert (localTimeoutMS , MILLISECONDS );
205+ }
206+ return mongo .getMongoClientOptions ().getTimeout (timeUnit );
207+ }
208+
209+ /**
210+ * Sets the time limit for the full execution of an operation.
211+ *
212+ * <ul>
213+ * <li>{@code 0} means infinite timeout.</li>
214+ * <li>{@code > 0} The time limit to use for the full execution of an operation.</li>
215+ * </ul>
216+ *
217+ * @param timeout the timeout, which must be greater than or equal to 0
218+ * @param timeUnit the time unit
219+ * @return this
220+ * @since 4.x
221+ */
222+ public DB setTimeout (final long timeout , final TimeUnit timeUnit ) {
223+ isTrueArgument ("timeout >= 0" , timeout >= 0 );
224+ notNull ("timeUnit" , timeUnit );
225+ timeoutMS = MILLISECONDS .convert (timeout , timeUnit );
226+ return this ;
227+ }
228+
167229 /**
168230 * Gets a collection with a given name.
169231 *
@@ -197,7 +259,9 @@ public DBCollection getCollection(final String name) {
197259 */
198260 public void dropDatabase () {
199261 try {
200- getExecutor ().execute (new DropDatabaseOperation (getName (), getWriteConcern ()), getReadConcern ());
262+ getExecutor ().execute (new DropDatabaseOperation (
263+ ClientSideOperationTimeoutFactories .create (getTimeout (MILLISECONDS )), getName (), getWriteConcern ()),
264+ getReadConcern ());
201265 } catch (MongoWriteConcernException e ) {
202266 throw createWriteConcernException (e );
203267 }
@@ -222,11 +286,11 @@ public String getName() {
222286 public Set <String > getCollectionNames () {
223287 List <String > collectionNames =
224288 new MongoIterableImpl <DBObject >(null , executor , ReadConcern .DEFAULT , primary (),
225- mongo .getMongoClientOptions ().getRetryReads ()) {
289+ mongo .getMongoClientOptions ().getRetryReads (), getTimeout ( MILLISECONDS ) ) {
226290 @ Override
227291 public ReadOperation <BatchCursor <DBObject >> asReadOperation () {
228- return new ListCollectionsOperation <DBObject >(name , commandCodec )
229- .nameOnly (true );
292+ return new ListCollectionsOperation <DBObject >(
293+ ClientSideOperationTimeoutFactories . create ( getTimeoutMS ()), name , commandCodec ) .nameOnly (true );
230294 }
231295 }.map (new Function <DBObject , String >() {
232296 @ Override
@@ -311,8 +375,9 @@ public DBCollection createView(final String viewName, final String viewOn, final
311375 try {
312376 notNull ("options" , options );
313377 DBCollection view = getCollection (viewName );
314- executor .execute (new CreateViewOperation (name , viewName , viewOn , view .preparePipeline (pipeline ), writeConcern )
315- .collation (options .getCollation ()), getReadConcern ());
378+ executor .execute (new CreateViewOperation (ClientSideOperationTimeoutFactories .create (getTimeout (MILLISECONDS )),
379+ name , viewName , viewOn , view .preparePipeline (pipeline ), writeConcern ).collation (options .getCollation ()),
380+ getReadConcern ());
316381 return view ;
317382 } catch (MongoWriteConcernException e ) {
318383 throw createWriteConcernException (e );
@@ -387,7 +452,8 @@ private CreateCollectionOperation getCreateCollectionOperation(final String coll
387452 validationAction = ValidationAction .fromString ((String ) options .get ("validationAction" ));
388453 }
389454 Collation collation = DBObjectCollationHelper .createCollationFromOptions (options );
390- return new CreateCollectionOperation (getName (), collectionName , getWriteConcern ())
455+ return new CreateCollectionOperation (ClientSideOperationTimeoutFactories .create (getTimeout (MILLISECONDS )), getName (),
456+ collectionName , getWriteConcern ())
391457 .capped (capped )
392458 .collation (collation )
393459 .sizeInBytes (sizeInBytes )
@@ -520,9 +586,9 @@ public String toString() {
520586 }
521587
522588 CommandResult executeCommand (final BsonDocument commandDocument , final ReadPreference readPreference ) {
523- return new CommandResult (executor .execute (new CommandReadOperation < BsonDocument >( getName (), commandDocument ,
524- new BsonDocumentCodec ( )),
525- readPreference , getReadConcern ()));
589+ return new CommandResult (executor .execute (
590+ new CommandReadOperation < BsonDocument >( ClientSideOperationTimeoutFactories . create ( getTimeout ( MILLISECONDS )),
591+ getName (), commandDocument , new BsonDocumentCodec ()), readPreference , getReadConcern ()));
526592 }
527593
528594 OperationExecutor getExecutor () {
0 commit comments