title: PyMongo connections not being released: Error as no more connections to MongoDB available
body: <p>I have a script which uses up all available connections of the locally running MongoDB and then exists with this error message:</p>
  
  <pre><code>pymongo.errors.AutoReconnect: [Errno 4] Interrupted system call
  </code></pre>
  
  <p>The error message in /var/log/mongodb/mongod.log is:</p>
  
  <pre><code>[initandlisten] connection refused because too many open connections: 819
  </code></pre>
  
  <p>The Mongo-Shell gives this output when the script is being invoked:</p>
  
  <pre><code>&gt; db.serverStatus().connections
  { "current" : 1, "available" : 818 }  // Script not yet started
  &gt; db.serverStatus().connections
  { "current" : 400, "available" : 419 }  // Losing connections
  &gt; db.serverStatus().connections
  { "current" : 638, "available" : 181 }
  &gt; db.serverStatus().connections
  { "current" : 804, "available" : 15 }
  &gt; db.serverStatus().connections
  { "current" : 819, "available" : 0 }  // Script terminates
  &gt; db.serverStatus().connections
  { "current" : 1, "available" : 818 }  // Script terminated
  </code></pre>
  
  <p>I am not able to post the original script, but the following "sanitized" snippet hopefully gives an idea. Basically, I am running all sorts of different queries and updates across several collections.</p>
  
  <p>Most importantly only 5 of 11 database statements will <em>sometimes</em> not release their connection. The other 6 statements will <em>always</em> leave as many free connections as there were before the statement.</p>
  
  <pre><code>mc = pymongo.Connection()
  db = mc.database
  
  def available():
      """ Return the number of available connections """
      return db.command("serverStatus")['connections']['available']
  
  def process():
      while True:
          # ...
          # Connections lost:
          conns = available()
          coll_a = db.coll_a.find_and_modify(
                  query={'x': x},
                  update={'$pop': {'x': -1}},
                  fields={'x': 1})
          if conns &gt; available():
              print('Fewer connections')
          # ...
          # No connections lost:
          db.coll_a.update({'x': x}, {'$pullAll': {'x': [x]}})
          # ...
          # No connections lost:
          coll_d = db.coll_d.find_and_modify(
                  query={'x': x,},
                  update={'$set': {'x': x}},
                  fields={'x': 1})
          # ...
          # No connections lost:
          coll_b_cursor = db.coll_b.find({'x': x}, {'x': 1})
          # ...
          # No connections lost:
          coll_e_cursor = db.coll_e.find({'$or': [{'x': x}, {'x': x}]})
          # ...
          for item in coll_e_cursor:
              # No connections lost:
              coll_b = db.coll_b.find({'x': x}).count()
          # ...
          # No connections lost:
          coll_b_cursor = db.coll_b.find({'x': x}, {'x': x})
          # ...
          for x in y:
              if x:
                  # Connections lost:
                  conns = available()
                  db.coll_b.update({'x': x}, {'$unset': {'x': 1}})
                  if conns &gt; available():
                      print('Fewer connections')
              # ...
              # Connections lost:
              conns = available()
              coll_b = db.coll_b.find_and_modify(
                      query={'x': x},
                      update={'$set': {'x': x}},
                      fields={'x': 1},
                      upsert=True)
              if conns &gt; available():
                  print('Fewer connections')
              # ...
              # Connections lost:
              conns = available()
              coll_c_1 = db.coll_c.find_one({'x': x})
              coll_c_2 = db.coll_c.find_one({'x': x})
              if conns &gt; available():
                  print('Fewer connections')
          # ...
          # Connections lost:
          conns = available()
          db.coll_b.update({'x': x}, {'$unset': {'x': 1}})
          if conns &gt; available():
              print('Fewer connections')
  </code></pre>
  
  <ul>
  <li>What is the difference between the statements that do not release their connections and those that do?</li>
  <li>Should PyMongo or MongoDB not free connections under all circumstances?</li>
  </ul>
  
  <p>PyMongo: 2.2.1</p>
  
  <p>MongoDB: 2.0.6</p>