Class: ActiveMatrix::ClientPool::HomeserverPool

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/active_matrix/client_pool.rb

Overview

Pool for a specific homeserver

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, #logger, #logger=

Constructor Details

#initialize(homeserver, max_size:, timeout:) ⇒ HomeserverPool

Returns a new instance of HomeserverPool.



84
85
86
87
88
89
90
91
92
# File 'lib/active_matrix/client_pool.rb', line 84

def initialize(homeserver, max_size:, timeout:)
  @homeserver = homeserver
  @max_size = max_size
  @timeout = timeout
  @available = []
  @in_use = {}
  @mutex = Mutex.new
  @semaphore = Async::Semaphore.new(max_size)
end

Instance Attribute Details

#homeserverObject (readonly)

Returns the value of attribute homeserver.



82
83
84
# File 'lib/active_matrix/client_pool.rb', line 82

def homeserver
  @homeserver
end

#max_sizeObject (readonly)

Returns the value of attribute max_size.



82
83
84
# File 'lib/active_matrix/client_pool.rb', line 82

def max_size
  @max_size
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



82
83
84
# File 'lib/active_matrix/client_pool.rb', line 82

def timeout
  @timeout
end

Instance Method Details

#available_countObject



142
143
144
# File 'lib/active_matrix/client_pool.rb', line 142

def available_count
  @mutex.synchronize { @available.size }
end

#checkin(client) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/active_matrix/client_pool.rb', line 124

def checkin(client)
  @mutex.synchronize do
    entry = @in_use.delete(client.object_id)
    return unless entry

    # Add back to available pool if still valid
    if client_valid?(client)
      @available << client
    else
      logger.debug "Discarding invalid client for #{@homeserver}"
    end
  end
end

#checkoutObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/active_matrix/client_pool.rb', line 94

def checkout(**)
  # Acquire semaphore temporarily to rate-limit client creation
  @semaphore.acquire

  client = @mutex.synchronize do
    # Try to find an available client
    existing = find_available_client

    if existing
      @available.delete(existing)
      existing
    else
      create_client(**)
    end
  end

  # Track as in use
  @mutex.synchronize do
    @in_use[client.object_id] = {
      client: client,
      checked_out_at: Time.current
    }
  end

  client
ensure
  # Release immediately - semaphore only rate-limits creation, not usage
  @semaphore.release
end

#clear!Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/active_matrix/client_pool.rb', line 150

def clear!
  @mutex.synchronize do
    # Stop all clients
    (@available + @in_use.values.map { |e| e[:client] }).each do |client|
      client.stop_listener if client.listening?
      client.logout if client.logged_in?
    rescue StandardError => e
      logger.error "Error cleaning up client: #{e.message}"
    end

    @available.clear
    @in_use.clear
  end
end

#in_use_countObject



146
147
148
# File 'lib/active_matrix/client_pool.rb', line 146

def in_use_count
  @mutex.synchronize { @in_use.size }
end

#sizeObject



138
139
140
# File 'lib/active_matrix/client_pool.rb', line 138

def size
  @mutex.synchronize { @available.size + @in_use.size }
end