class Mongo::Session::SessionPool

A pool of server sessions.

@api private

@since 2.5.0

Public Class Methods

create(cluster) click to toggle source

Create a SessionPool.

@example

SessionPool.create(cluster)

@param [ Mongo::Cluster ] cluster The cluster that will be associated with this

session pool.

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 38
def self.create(cluster)
  pool = new(cluster)
  cluster.instance_variable_set(:@session_pool, pool)
end
new(cluster) click to toggle source

Initialize a SessionPool.

@example

SessionPool.new(cluster)

@param [ Mongo::Cluster ] cluster The cluster that will be associated with this

session pool.

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 52
def initialize(cluster)
  @queue = []
  @mutex = Mutex.new
  @cluster = cluster
end

Public Instance Methods

checkin(session) click to toggle source

Checkin a server session to the pool.

@example Checkin a session.

pool.checkin(session)

@param [ Session::ServerSession ] session The session to checkin.

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 101
def checkin(session)
  @mutex.synchronize do
    prune!
    unless about_to_expire?(session)
      @queue.unshift(session)
    end
  end
end
checkout() click to toggle source

Check out a server session from the pool.

@example Check out a session.

pool.checkout

@return [ ServerSession ] The server session.

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 78
def checkout
  @mutex.synchronize do
    loop do
      if @queue.empty?
        return ServerSession.new
      else
        session = @queue.shift
        unless about_to_expire?(session)
          return session
        end
      end
    end
  end
end
end_sessions() click to toggle source

End all sessions in the pool by sending the endSessions command to the server.

@example End all sessions.

pool.end_sessions

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 116
def end_sessions
  while !@queue.empty?
    server = ServerSelector.get(mode: :primary_preferred).select_server(@cluster)
    op = Operation::Command.new(
      selector: {
        endSessions: @queue.shift(10_000).map(&:session_id),
      },
      db_name: Database::ADMIN,
    )
    context = Operation::Context.new(options: {
      server_api: server.options[:server_api],
    })
    op.execute(server, context: context)
  end
rescue Mongo::Error, Error::AuthError
end
inspect() click to toggle source

Get a formatted string for use in inspection.

@example Inspect the session pool object.

session_pool.inspect

@return [ String ] The session pool inspection.

@since 2.5.0

# File lib/mongo/session/session_pool.rb, line 66
def inspect
  "#<Mongo::Session::SessionPool:0x#{object_id} current_size=#{@queue.size}>"
end

Private Instance Methods

about_to_expire?(session) click to toggle source
# File lib/mongo/session/session_pool.rb, line 135
def about_to_expire?(session)
  # Load balancers spec explicitly requires to ignore the logical session
  # timeout value.
  # No rationale is provided as of the time of this writing.
  if @cluster.load_balanced?
    return false
  end

  logical_session_timeout = @cluster.logical_session_timeout

  if logical_session_timeout
    idle_time_minutes = (Time.now - session.last_use) / 60
    (idle_time_minutes + 1) >= logical_session_timeout
  end
end
prune!() click to toggle source
# File lib/mongo/session/session_pool.rb, line 151
def prune!
  # Load balancers spec explicitly requires not to prune sessions.
  # No rationale is provided as of the time of this writing.
  return if @cluster.load_balanced?

  while !@queue.empty?
    if about_to_expire?(@queue[-1])
      @queue.pop
    else
      break
    end
  end
end