Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-2091

Exception: Interrupted acquiring a permit to retrieve an item from the pool

    XMLWordPrintable

Details

    • Bug
    • Status: Closed
    • Major - P3
    • Resolution: Works as Designed
    • 3.2.0
    • None
    • Connection Management
    • None
    • Ubuntu, connecting to single instance of Mongo DB 3.0.6 on localhost

    Description

      We recently upgraded from a older version of the MongoDB driver to 3.2 and are see multiple exceptions being thrown.

      Our application runs OK for a day or so but then we're seeing this exception being thrown frequently...

      Error message
      com.mongodb.MongoInterruptedException: Interrupted acquiring a permit to retrieve an item from the pool
       
      Sample stack trace
      …ngodb.internal.connection.ConcurrentPool.acquirePermit (ConcurrentPool.java:186)
       
           com.mongodb.internal.connection.ConcurrentPool.get (ConcurrentPool.java:126)
       
      …b.connection.DefaultConnectionPool.getPooledConnection (DefaultConnectionPool.java:250)
       
             com.mongodb.connection.DefaultConnectionPool.get (DefaultConnectionPool.java:91)
       
             com.mongodb.connection.DefaultConnectionPool.get (DefaultConnectionPool.java:80)
      com.mongodb.connection.DefaultConnectionPool.get
       
           com.mongodb.connection.DefaultServer.getConnection (DefaultServer.java:72)
       
      …erBinding$ClusterBindingConnectionSource.getConnection (ClusterBinding.java:86)
       
      …mongodb.operation.OperationHelper.withConnectionSource (OperationHelper.java:228)
       
         com.mongodb.operation.OperationHelper.withConnection (OperationHelper.java:221)
       
        com.mongodb.operation.MixedBulkWriteOperation.execute (MixedBulkWriteOperation.java:168)
       
        com.mongodb.operation.MixedBulkWriteOperation.execute (MixedBulkWriteOperation.java:74)
       
                                    com.mongodb.Mongo.execute (Mongo.java:782)
       
                                  com.mongodb.Mongo$2.execute (Mongo.java:765)
       
      ….mongodb.MongoCollectionImpl.executeSingleWriteRequest (MongoCollectionImpl.java:515)
       
                   com.mongodb.MongoCollectionImpl.replaceOne (MongoCollectionImpl.java:344)
       
       com.mapov.availability.AvailabilityCache.cacheResponse (AvailabilityCache.java:62)
       
       com.mapov.availability.AvailabilityCache.cacheResponse (AvailabilityCache.java:45)
       
      ….availability.AvailabilityRequestHandler.cacheResponse (AvailabilityRequestHandler.java:146)
       
      …apov.availability.AvailabilityRequestHandler.sendError (AvailabilityRequestHandler.java:204)
       
           com.mapov.availability.agoda.AgodaAvailability.run (AgodaAvailability.java:93)
       
            java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
       
           java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
       
                                         java.lang.Thread.run (Thread.java:745)
       
       
      caused by java.lang.InterruptedException
      …locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos (AbstractQueuedSynchronizer.java:1326)
       
                    java.util.concurrent.Semaphore.tryAcquire (Semaphore.java:409)
       
      …ngodb.internal.connection.ConcurrentPool.acquirePermit (ConcurrentPool.java:180)
       
           com.mongodb.internal.connection.ConcurrentPool.get (ConcurrentPool.java:126)
       
      …b.connection.DefaultConnectionPool.getPooledConnection (DefaultConnectionPool.java:250)
       
             com.mongodb.connection.DefaultConnectionPool.get (DefaultConnectionPool.java:91)
       
             com.mongodb.connection.DefaultConnectionPool.get (DefaultConnectionPool.java:80)
       
           com.mongodb.connection.DefaultServer.getConnection (DefaultServer.java:72)
       
      …erBinding$ClusterBindingConnectionSource.getConnection (ClusterBinding.java:86)
       
      …mongodb.operation.OperationHelper.withConnectionSource (OperationHelper.java:228)
       
         com.mongodb.operation.OperationHelper.withConnection (OperationHelper.java:221)
       
        com.mongodb.operation.MixedBulkWriteOperation.execute (MixedBulkWriteOperation.java:168)
       
        com.mongodb.operation.MixedBulkWriteOperation.execute (MixedBulkWriteOperation.java:74)
       
                                    com.mongodb.Mongo.execute (Mongo.java:782)
       
                                  com.mongodb.Mongo$2.execute (Mongo.java:765)
       
      ….mongodb.MongoCollectionImpl.executeSingleWriteRequest (MongoCollectionImpl.java:515)
       
                   com.mongodb.MongoCollectionImpl.replaceOne (MongoCollectionImpl.java:344)
       
       com.mapov.availability.AvailabilityCache.cacheResponse (AvailabilityCache.java:62)
       
       com.mapov.availability.AvailabilityCache.cacheResponse (AvailabilityCache.java:45)
       
      ….availability.AvailabilityRequestHandler.cacheResponse (AvailabilityRequestHandler.java:146)
       
      …apov.availability.AvailabilityRequestHandler.sendError (AvailabilityRequestHandler.java:204)
       
           com.mapov.availability.agoda.AgodaAvailability.run (AgodaAvailability.java:93)
       
            java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
       
           java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
       
                                         java.lang.Thread.run (Thread.java:745)
      

      We have a single MongoClient instance:

      package com.mapov.availability;
       
      import com.mongodb.MongoClient;
      import com.mongodb.client.MongoDatabase;
       
      /**
       *
       * @author Justin
       */
      public class MongoConnection {
        private static MongoClient mongoClient = null;
        
        private MongoConnection() {
          // Private constructor
        }
        
        public static MongoDatabase getMapovDB() {
          if( mongoClient == null) {
            mongoClient = new MongoClient();
          }
          return mongoClient.getDatabase("mapov");
        }
      }
      
      

      This is the cache code, called from multiple threads:

      package com.mapov.availability;
       
      import com.mapov.util.Util;
      import com.mongodb.BasicDBObject;
      import com.mongodb.client.MongoCollection;
      import com.mongodb.client.MongoDatabase;
      import com.mongodb.client.model.Filters;
      import com.mongodb.client.model.UpdateOptions;
      import java.util.logging.Logger;
      import org.bson.Document;
      import org.bson.conversions.Bson;
      import org.joda.time.DateTime;
      import static com.mongodb.client.model.Filters.*;
      import static com.mongodb.client.model.Sorts.*;
       
      /**
       *
       * @author Justin
       */
      public class AvailabilityCache {
       
        private static final Logger logger = Logger.getLogger(AvailabilityCache.class.getName());
        private static final int cacheExpirySeconds = 3600; // Default cache time is 1 hour
        private final MongoCollection<Document> cacheCollection;
       
        public AvailabilityCache() {
          MongoDatabase mapovDB = MongoConnection.getMapovDB();
          this.cacheCollection = mapovDB.getCollection("availability");
        }
       
        private BasicDBObject buildKey(AvailabilityRequest request, AvailabilityResponse response) {
          BasicDBObject key = new BasicDBObject("startDate", request.startDate);
          key.append("endDate", request.endDate);
          key.append("locale", request.locale);
          key.append("rooms", Util.implode(request.rooms, ","));
          key.append("children", Util.implode(request.children, ","));
          key.append("cpID", response.cpID);
          key.append("providerPropertyID", response.providerPropertyID);
          key.append("currency", request.currencyCode);
       
          return key;
        }
       
        public void cacheResponse(AvailabilityRequest request, AvailabilityResponse response) {
          cacheResponse(request, response, cacheExpirySeconds);
        }
       
        public void cacheResponse(AvailabilityRequest request, AvailabilityResponse response, int cacheExpirySeconds) {
          BasicDBObject key = buildKey(request, response);
       
          Document doc = new Document();
          doc.append("_id", key);
          doc.append("rate", (int)response.rate*100);
          doc.append("deepLink", response.deepLink);
          doc.append("availableRooms", response.availableRooms);
          doc.append("error", response.error);
          doc.append("errorMsg", response.errorMsg);
          DateTime expiry = DateTime.now().plusSeconds(cacheExpirySeconds);
          doc.append("expireAt", expiry.toDate());
          UpdateOptions uo = new UpdateOptions();
          uo.upsert(true);
          cacheCollection.replaceOne(Filters.eq("_id", key),doc, uo);//Upserts
        }
       
        public boolean checkCache(AvailabilityRequest request, AvailabilityResponse response) {
          boolean found = false;
          
          BasicDBObject key = buildKey(request, response);
          Bson query = eq("_id", key);
          Bson orderBy = descending("expireAt");
       
          Document result = (Document)cacheCollection.find(query).sort(orderBy).first();
          if( result!=null) {
            response.rate = (Integer)result.get("rate")/100;
            response.deepLink = (String)result.get("deepLink");
            response.error = (Integer)result.get("error");
            response.errorMsg = (String)result.get("errorMsg");
            if( result.containsKey("availableRooms")) {
              response.availableRooms = (Integer)result.get("availableRooms");
            }
            found = true;
            //logger.log(Level.INFO, "Cache match: {0}", response);
          }
       
          return found;
        }
      }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            justinknight Justin Knight
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: