@@ -99,12 +99,13 @@ def create_fake_ssl_context(
99
99
100
100
101
101
_global_connection_managers = {}
102
+ _global_key_by_socketpool = {}
102
103
_global_socketpools = {}
103
104
_global_ssl_contexts = {}
104
105
105
106
106
107
def get_radio_socketpool (radio ):
107
- """Helper to get a socket pool for common boards
108
+ """Helper to get a socket pool for common boards.
108
109
109
110
Currently supported:
110
111
@@ -151,14 +152,15 @@ def get_radio_socketpool(radio):
151
152
else :
152
153
raise AttributeError (f"Unsupported radio class: { class_name } " )
153
154
155
+ _global_key_by_socketpool [pool ] = class_name
154
156
_global_socketpools [class_name ] = pool
155
157
_global_ssl_contexts [class_name ] = ssl_context
156
158
157
159
return _global_socketpools [class_name ]
158
160
159
161
160
162
def get_radio_ssl_context (radio ):
161
- """Helper to get ssl_contexts for common boards
163
+ """Helper to get ssl_contexts for common boards.
162
164
163
165
Currently supported:
164
166
@@ -175,7 +177,7 @@ def get_radio_ssl_context(radio):
175
177
176
178
177
179
class ConnectionManager :
178
- """Connection manager for sharing open sockets (aka connections) ."""
180
+ """A library for managing sockets accross libraries ."""
179
181
180
182
def __init__ (
181
183
self ,
@@ -228,16 +230,20 @@ def _get_connected_socket( # pylint: disable=too-many-arguments
228
230
229
231
@property
230
232
def available_socket_count (self ) -> int :
231
- """Get the count of freeable open sockets"""
233
+ """Get the count of available (freed) managed sockets. """
232
234
return len (self ._available_sockets )
233
235
234
236
@property
235
237
def managed_socket_count (self ) -> int :
236
- """Get the count of open sockets"""
238
+ """Get the count of managed sockets. """
237
239
return len (self ._managed_socket_by_key )
238
240
239
241
def close_socket (self , socket : SocketType ) -> None :
240
- """Close a previously opened socket."""
242
+ """
243
+ Close a previously managed and connected socket.
244
+
245
+ - **socket_pool** *(SocketType)* – The socket you want to close
246
+ """
241
247
if socket not in self ._managed_socket_by_key .values ():
242
248
raise RuntimeError ("Socket not managed" )
243
249
socket .close ()
@@ -247,7 +253,7 @@ def close_socket(self, socket: SocketType) -> None:
247
253
self ._available_sockets .remove (socket )
248
254
249
255
def free_socket (self , socket : SocketType ) -> None :
250
- """Mark a previously opened socket as available so it can be reused if needed ."""
256
+ """Mark a managed socket as available so it can be reused."""
251
257
if socket not in self ._managed_socket_by_key .values ():
252
258
raise RuntimeError ("Socket not managed" )
253
259
self ._available_sockets .add (socket )
@@ -263,7 +269,20 @@ def get_socket(
263
269
is_ssl : bool = False ,
264
270
ssl_context : Optional [SSLContextType ] = None ,
265
271
) -> CircuitPythonSocketType :
266
- """Get a new socket and connect"""
272
+ """
273
+ Get a new socket and connect.
274
+
275
+ - **host** *(str)* – The host you are want to connect to: "www.adaftuit.com"
276
+ - **port** *(int)* – The port you want to connect to: 80
277
+ - **proto** *(str)* – The protocal you want to use: "http:"
278
+ - **session_id** *(Optional[str])* – A unique Session ID, when wanting to have multiple open
279
+ connections to the same host
280
+ - **timeout** *(float)* – Time timeout used for connecting
281
+ - **is_ssl** *(bool)* – If the connection is to be over SSL (auto set when proto is
282
+ "https:")
283
+ - **ssl_context** *(Optional[SSLContextType])* – The SSL context to use when making SSL
284
+ requests
285
+ """
267
286
if session_id :
268
287
session_id = str (session_id )
269
288
key = (host , port , proto , session_id )
@@ -315,7 +334,14 @@ def get_socket(
315
334
def connection_manager_close_all (
316
335
socket_pool : Optional [SocketpoolModuleType ] = None , release_references : bool = False
317
336
) -> None :
318
- """Close all open sockets for pool"""
337
+ """
338
+ Close all open sockets for pool, optionally release references.
339
+
340
+ - **socket_pool** *(Optional[SocketpoolModuleType])* – A specifc SocketPool you want to close
341
+ sockets for, leave blank for all SocketPools
342
+ - **release_references** *(bool)* – Set to True if you want to also clear stored references to
343
+ the SocketPool and SSL contexts
344
+ """
319
345
if socket_pool :
320
346
socket_pools = [socket_pool ]
321
347
else :
@@ -328,26 +354,24 @@ def connection_manager_close_all(
328
354
329
355
connection_manager ._free_sockets (force = True ) # pylint: disable=protected-access
330
356
331
- if release_references :
332
- radio_key = None
333
- for radio_check , pool_check in _global_socketpools .items ():
334
- if pool == pool_check :
335
- radio_key = radio_check
336
- break
357
+ if not release_references :
358
+ continue
337
359
338
- if radio_key :
339
- if radio_key in _global_socketpools :
340
- del _global_socketpools [radio_key ]
360
+ key = _global_key_by_socketpool .pop (pool )
361
+ if key :
362
+ _global_socketpools .pop (key , None )
363
+ _global_ssl_contexts .pop (key , None )
341
364
342
- if radio_key in _global_ssl_contexts :
343
- del _global_ssl_contexts [radio_key ]
344
-
345
- if pool in _global_connection_managers :
346
- del _global_connection_managers [pool ]
365
+ _global_connection_managers .pop (pool , None )
347
366
348
367
349
368
def get_connection_manager (socket_pool : SocketpoolModuleType ) -> ConnectionManager :
350
- """Get the ConnectionManager singleton for the given pool"""
369
+ """
370
+ Get the ConnectionManager singleton for the given pool.
371
+
372
+ - **socket_pool** *(Optional[SocketpoolModuleType])* – The SocketPool you want the
373
+ ConnectionManager for
374
+ """
351
375
if socket_pool not in _global_connection_managers :
352
376
_global_connection_managers [socket_pool ] = ConnectionManager (socket_pool )
353
377
return _global_connection_managers [socket_pool ]
0 commit comments