Skip to content

Commit ef59be1

Browse files
Merge branches 'master' and 'master' of github.com:mongodb/mongo-java-driver
Conflicts: src/main/com/mongodb/DBCursor.java
2 parents 237bf6c + fe6b133 commit ef59be1

File tree

5 files changed

+109
-64
lines changed

5 files changed

+109
-64
lines changed

src/main/com/mongodb/DBCursor.java

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525

2626
/** An iterator over database results.
27-
* Doing a <code>find()</code> query on a collection returns a
27+
* Doing a <code>find()</code> query on a collection returns a
2828
* <code>DBCursor</code> thus
2929
*
3030
* <blockquote><pre>
@@ -34,13 +34,13 @@
3434
* </pre></blockquote>
3535
*
3636
* <p><b>Warning:</b> Calling <code>toArray</code> or <code>length</code> on
37-
* a DBCursor will irrevocably turn it into an array. This
37+
* a DBCursor will irrevocably turn it into an array. This
3838
* means that, if the cursor was iterating over ten million results
3939
* (which it was lazily fetching from the database), suddenly there will
4040
* be a ten-million element array in memory. Before converting to an array,
41-
* make sure that there are a reasonable number of results using
41+
* make sure that there are a reasonable number of results using
4242
* <code>skip()</code> and <code>limit()</code>.
43-
* <p>For example, to get an array of the 1000-1100th elements of a cursor, use
43+
* <p>For example, to get an array of the 1000-1100th elements of a cursor, use
4444
*
4545
* <blockquote><pre>
4646
* List<DBObject> obj = collection.find( query ).skip( 1000 ).limit( 100 ).toArray();
@@ -72,7 +72,7 @@ static enum CursorType { ITERATOR , ARRAY };
7272

7373
/**
7474
* Creates a copy of an existing database cursor.
75-
* The new cursor is an iterator, even if the original
75+
* The new cursor is an iterator, even if the original
7676
* was an array.
7777
*
7878
* @return the new cursor
@@ -86,6 +86,8 @@ public DBCursor copy() {
8686
c._skip = _skip;
8787
c._options = _options;
8888
c._batchSize = _batchSize;
89+
c._snapshot = _snapshot;
90+
c._explain = _explain;
8991
if ( _specialFields != null )
9092
c._specialFields = new BasicDBObject( _specialFields.toMap() );
9193
return c;
@@ -162,9 +164,9 @@ public DBCursor hint( String indexName ){
162164
}
163165

164166
/**
165-
* Use snapshot mode for the query. Snapshot mode assures no duplicates are
166-
* returned, or objects missed, which were present at both the start and end
167-
* of the query's execution (if an object is new during the query, or deleted
167+
* Use snapshot mode for the query. Snapshot mode assures no duplicates are
168+
* returned, or objects missed, which were present at both the start and end
169+
* of the query's execution (if an object is new during the query, or deleted
168170
* during the query, it may or may not be returned, even with snapshot mode).
169171
* Note that short query responses (less than 1MB) are always effectively snapshotted.
170172
* Currently, snapshot mode may not be used with sorting or explicit hints.
@@ -223,14 +225,14 @@ else if (n < 0)
223225
/**
224226
* Limits the number of elements returned in one batch.
225227
* A cursor typically fetches a batch of result objects and store them locally.
226-
*
228+
*
227229
* If <tt>batchSize</tt> is positive, it represents the size of each batch of objects retrieved.
228230
* It can be adjusted to optimize performance and limit data transfer.
229-
*
231+
*
230232
* If <tt>batchSize</tt> is negative, it will limit of number objects returned, that fit within the max batch size limit (usually 4MB), and cursor will be closed.
231233
* For example if <tt>batchSize</tt> is -10, then the server will return a maximum of 10 documents and as many as can fit in 4MB, then close the cursor.
232234
* Note that this feature is different from limit() in that documents must fit within a maximum size, and it removes the need to send a request to close the cursor server-side.
233-
*
235+
*
234236
* The batch size can be changed even after a cursor is iterated, in which case the setting will apply on the next batch retrieval.
235237
*
236238
* @param n the number of elements to return in a batch
@@ -240,7 +242,7 @@ public DBCursor batchSize( int n ){
240242
// check for special case, used to have server bug with 1
241243
if ( n == 1 )
242244
n = 2;
243-
245+
244246
if ( _it != null ) {
245247
if (_it instanceof DBApiLayer.Result)
246248
((DBApiLayer.Result)_it).setBatchSize(n);
@@ -270,18 +272,18 @@ public DBCursor skip( int n ){
270272
public long getCursorId() {
271273
if ( _it instanceof Result )
272274
return ((Result)_it).getCursorId();
273-
275+
274276
return 0;
275277
}
276-
278+
277279
/**
278280
* kills the current cursor on the server.
279281
*/
280282
public void close() {
281283
if ( _it instanceof Result )
282284
((Result)_it).close();
283285
}
284-
286+
285287
/**
286288
* makes this query ok to run on a slave node
287289
* @return
@@ -329,15 +331,15 @@ private void _check()
329331
throws MongoException {
330332
if ( _it != null )
331333
return;
332-
334+
333335
if ( _collection != null && _query != null ){
334336

335337
_lookForHints();
336338

337339
DBObject foo = _query;
338340
if ( hasSpecialQueryFields() ){
339341
foo = _specialFields == null ? new BasicDBObject() : _specialFields;
340-
342+
341343
_addToQueryObject( foo , "query" , _query , true );
342344
_addToQueryObject( foo , "orderby" , _orderBy , false );
343345
if(_hint != null)
@@ -359,12 +361,12 @@ private void _check()
359361
_fake = true;
360362
}
361363
}
362-
364+
363365
/**
364366
* if there is a hint to use, use it
365367
*/
366368
private void _lookForHints(){
367-
369+
368370
if ( _hint != null ) // if someone set a hint, then don't do this
369371
return;
370372

@@ -374,7 +376,7 @@ private void _lookForHints(){
374376
Set<String> mykeys = _query.keySet();
375377

376378
for ( DBObject o : _collection._hintFields ){
377-
379+
378380
Set<String> hintKeys = o.keySet();
379381

380382
if ( ! mykeys.containsAll( hintKeys ) )
@@ -394,25 +396,25 @@ boolean hasSpecialQueryFields(){
394396

395397
if ( _hint != null || _hintDBObj != null || _snapshot )
396398
return true;
397-
399+
398400
return _explain;
399401
}
400402

401403
void _addToQueryObject( DBObject query , String field , DBObject thing , boolean sendEmpty ){
402404
if ( thing == null )
403405
return;
404-
406+
405407
if ( ! sendEmpty && thing.keySet().size() == 0 )
406408
return;
407-
409+
408410
_addToQueryObject( query , field , thing );
409411
}
410412

411413
void _addToQueryObject( DBObject query , String field , Object thing ){
412414

413415
if ( thing == null )
414416
return;
415-
417+
416418
query.put( field , thing );
417419
}
418420

@@ -478,7 +480,7 @@ public List<Integer> getSizes(){
478480

479481
throw new IllegalArgumentException("_it not a real result" );
480482
}
481-
483+
482484
private boolean _hasNext()
483485
throws MongoException {
484486
_check();
@@ -508,7 +510,7 @@ public boolean hasNext() throws MongoException {
508510
_checkType( CursorType.ITERATOR );
509511
return _hasNext();
510512
}
511-
513+
512514
/**
513515
* Returns the object the cursor is at and moves the cursor ahead by one.
514516
* @return the next element
@@ -545,7 +547,7 @@ void _fill( int n )
545547
_next();
546548
}
547549

548-
/**
550+
/**
549551
* pulls back all items into an array and returns the number of objects.
550552
* Note: this can be resource intensive
551553
* @see #count()
@@ -569,7 +571,7 @@ public List<DBObject> toArray()
569571
throws MongoException {
570572
return toArray( Integer.MAX_VALUE );
571573
}
572-
574+
573575
/**
574576
* Converts this cursor to an array.
575577
* @param max the maximum number of objects to return
@@ -582,7 +584,7 @@ public List<DBObject> toArray( int max )
582584
_fill( max );
583585
return _all;
584586
}
585-
587+
586588
/**
587589
* for testing only!
588590
* Iterates cursor and counts objects
@@ -605,13 +607,13 @@ public int itcount(){
605607
* @return the number of objects
606608
* @throws MongoException
607609
*/
608-
public int count()
610+
public int count()
609611
throws MongoException {
610612
if ( _collection == null )
611613
throw new IllegalArgumentException( "why is _collection null" );
612614
if ( _collection._db == null )
613615
throw new IllegalArgumentException( "why is _collection._db null" );
614-
616+
615617
return (int)_collection.getCount(this._query, this._keysWanted);
616618
}
617619

@@ -622,25 +624,25 @@ public int count()
622624
* @return the number of objects
623625
* @throws MongoException
624626
*/
625-
public int size()
627+
public int size()
626628
throws MongoException {
627629
if ( _collection == null )
628630
throw new IllegalArgumentException( "why is _collection null" );
629631
if ( _collection._db == null )
630632
throw new IllegalArgumentException( "why is _collection._db null" );
631-
633+
632634
return (int)_collection.getCount(this._query, this._keysWanted, this._limit, this._skip );
633635
}
634636

635-
637+
636638
/**
637639
* gets the fields to be returned
638640
* @return
639641
*/
640642
public DBObject getKeysWanted(){
641643
return _keysWanted;
642644
}
643-
645+
644646
/**
645647
* gets the query
646648
* @return
@@ -697,7 +699,7 @@ public String toString() {
697699
private final DBCollection _collection;
698700
private final DBObject _query;
699701
private final DBObject _keysWanted;
700-
702+
701703
private DBObject _orderBy = null;
702704
private String _hint = null;
703705
private DBObject _hintDBObj = null;

src/main/com/mongodb/DBTCPConnector.java

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package com.mongodb;
2020

2121
import java.io.IOException;
22+
import java.net.SocketTimeoutException;
2223
import java.util.*;
2324
import java.util.logging.Level;
2425
import java.util.logging.Logger;
@@ -204,7 +205,8 @@ public Response call( DB db , DBCollection coll , OutMessage m , ServerAddress h
204205
}
205206
catch ( IOException ioe ){
206207
mp.error( port , ioe );
207-
retry = _error( ioe, slaveOk ) && ! coll._name.equals( "$cmd" ) && retries > 0;
208+
retry = retries > 0 && !coll._name.equals( "$cmd" )
209+
&& !(ioe instanceof SocketTimeoutException) && _error( ioe, slaveOk );
208210
if ( !retry ){
209211
throw new MongoException.Network( "can't call something" , ioe );
210212
}
@@ -277,11 +279,11 @@ public String getConnectPoint(){
277279

278280
boolean _error( Throwable t, boolean slaveOk )
279281
throws MongoException {
280-
if ( _allHosts != null ){
281-
_logger.log( Level.WARNING , "replica set mode, switching master" , t );
282+
if ( _rsStatus.hasServerUp() ){
283+
// the replset has at least 1 server up, try to see if should switch master
282284
checkMaster( true , !slaveOk );
283285
}
284-
return true;
286+
return _rsStatus.hasServerUp();
285287
}
286288

287289
class MyPort {
@@ -346,7 +348,7 @@ void done( DBPort p ){
346348
void error( DBPort p , Exception e ){
347349
p.close();
348350
_requestPort = null;
349-
_logger.log( Level.SEVERE , "MyPort.error called" , e );
351+
// _logger.log( Level.SEVERE , "MyPort.error called" , e );
350352
}
351353

352354
void requestEnsureConnection(){
@@ -437,7 +439,12 @@ void testMaster()
437439
}
438440

439441
private boolean _set( ServerAddress addr ){
440-
_masterPortPool = _portHolder.get( addr );
442+
DBPortPool newPool = _portHolder.get( addr );
443+
if (newPool == _masterPortPool)
444+
return false;
445+
446+
_logger.log(Level.WARNING, "Master switching from " + (_masterPortPool != null ? _masterPortPool.getServerAddress() : "null") + " to " + addr);
447+
_masterPortPool = newPool;
441448
return true;
442449
}
443450

@@ -455,11 +462,18 @@ public String debugString(){
455462

456463
public void close(){
457464
_closed = true;
458-
if ( _portHolder != null )
465+
if ( _portHolder != null ) {
459466
_portHolder.close();
460-
if ( _rsStatus != null )
467+
_portHolder = null;
468+
}
469+
if ( _rsStatus != null ) {
461470
_rsStatus.close();
462-
_myPort = null;
471+
_rsStatus = null;
472+
}
473+
474+
// below this will remove the myport for this thread only
475+
// client using thread pool in web framework may need to call close() from all threads
476+
_myPort.remove();
463477
}
464478

465479
/**
@@ -500,7 +514,7 @@ public int getMaxBsonObjectSize() {
500514
private DBPortPool _masterPortPool;
501515
private DBPortPool.Holder _portHolder;
502516
private final List<ServerAddress> _allHosts;
503-
private final ReplicaSetStatus _rsStatus;
517+
private ReplicaSetStatus _rsStatus;
504518
private boolean _closed = false;
505519
private int maxBsonObjectSize = 0;
506520

0 commit comments

Comments
 (0)