Skip to content

Update docs #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 48 additions & 24 deletions adafruit_connection_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,13 @@ def create_fake_ssl_context(


_global_connection_managers = {}
_global_key_by_socketpool = {}
_global_socketpools = {}
_global_ssl_contexts = {}


def get_radio_socketpool(radio):
"""Helper to get a socket pool for common boards
"""Helper to get a socket pool for common boards.

Currently supported:

Expand Down Expand Up @@ -151,14 +152,15 @@ def get_radio_socketpool(radio):
else:
raise AttributeError(f"Unsupported radio class: {class_name}")

_global_key_by_socketpool[pool] = class_name
_global_socketpools[class_name] = pool
_global_ssl_contexts[class_name] = ssl_context

return _global_socketpools[class_name]


def get_radio_ssl_context(radio):
"""Helper to get ssl_contexts for common boards
"""Helper to get ssl_contexts for common boards.

Currently supported:

Expand All @@ -175,7 +177,7 @@ def get_radio_ssl_context(radio):


class ConnectionManager:
"""Connection manager for sharing open sockets (aka connections)."""
"""A library for managing sockets accross libraries."""

def __init__(
self,
Expand Down Expand Up @@ -228,16 +230,20 @@ def _get_connected_socket( # pylint: disable=too-many-arguments

@property
def available_socket_count(self) -> int:
"""Get the count of freeable open sockets"""
"""Get the count of available (freed) managed sockets."""
return len(self._available_sockets)

@property
def managed_socket_count(self) -> int:
"""Get the count of open sockets"""
"""Get the count of managed sockets."""
return len(self._managed_socket_by_key)

def close_socket(self, socket: SocketType) -> None:
"""Close a previously opened socket."""
"""
Close a previously managed and connected socket.

- **socket_pool** *(SocketType)* – The socket you want to close
"""
if socket not in self._managed_socket_by_key.values():
raise RuntimeError("Socket not managed")
socket.close()
Expand All @@ -247,7 +253,7 @@ def close_socket(self, socket: SocketType) -> None:
self._available_sockets.remove(socket)

def free_socket(self, socket: SocketType) -> None:
"""Mark a previously opened socket as available so it can be reused if needed."""
"""Mark a managed socket as available so it can be reused."""
if socket not in self._managed_socket_by_key.values():
raise RuntimeError("Socket not managed")
self._available_sockets.add(socket)
Expand All @@ -263,7 +269,20 @@ def get_socket(
is_ssl: bool = False,
ssl_context: Optional[SSLContextType] = None,
) -> CircuitPythonSocketType:
"""Get a new socket and connect"""
"""
Get a new socket and connect.

- **host** *(str)* – The host you are want to connect to: "www.adaftuit.com"
- **port** *(int)* – The port you want to connect to: 80
- **proto** *(str)* – The protocal you want to use: "http:"
- **session_id** *(Optional[str])* – A unique Session ID, when wanting to have multiple open
connections to the same host
- **timeout** *(float)* – Time timeout used for connecting
- **is_ssl** *(bool)* – If the connection is to be over SSL (auto set when proto is
"https:")
- **ssl_context** *(Optional[SSLContextType])* – The SSL context to use when making SSL
requests
"""
if session_id:
session_id = str(session_id)
key = (host, port, proto, session_id)
Expand Down Expand Up @@ -315,7 +334,14 @@ def get_socket(
def connection_manager_close_all(
socket_pool: Optional[SocketpoolModuleType] = None, release_references: bool = False
) -> None:
"""Close all open sockets for pool"""
"""
Close all open sockets for pool, optionally release references.

- **socket_pool** *(Optional[SocketpoolModuleType])* – A specifc SocketPool you want to close
sockets for, leave blank for all SocketPools
- **release_references** *(bool)* – Set to True if you want to also clear stored references to
the SocketPool and SSL contexts
"""
if socket_pool:
socket_pools = [socket_pool]
else:
Expand All @@ -328,26 +354,24 @@ def connection_manager_close_all(

connection_manager._free_sockets(force=True) # pylint: disable=protected-access

if release_references:
radio_key = None
for radio_check, pool_check in _global_socketpools.items():
if pool == pool_check:
radio_key = radio_check
break
if not release_references:
continue

if radio_key:
if radio_key in _global_socketpools:
del _global_socketpools[radio_key]
key = _global_key_by_socketpool.pop(pool)
if key:
_global_socketpools.pop(key, None)
_global_ssl_contexts.pop(key, None)

if radio_key in _global_ssl_contexts:
del _global_ssl_contexts[radio_key]

if pool in _global_connection_managers:
del _global_connection_managers[pool]
_global_connection_managers.pop(pool, None)


def get_connection_manager(socket_pool: SocketpoolModuleType) -> ConnectionManager:
"""Get the ConnectionManager singleton for the given pool"""
"""
Get the ConnectionManager singleton for the given pool.

- **socket_pool** *(Optional[SocketpoolModuleType])* – The SocketPool you want the
ConnectionManager for
"""
if socket_pool not in _global_connection_managers:
_global_connection_managers[socket_pool] = ConnectionManager(socket_pool)
return _global_connection_managers[socket_pool]
20 changes: 10 additions & 10 deletions examples/connectionmanager_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
connection_manager = adafruit_connection_manager.get_connection_manager(pool)
print("-" * 40)
print("Nothing yet opened")
print(f"Open Sockets: {connection_manager.managed_socket_count}")
print(f"Freeable Open Sockets: {connection_manager.available_socket_count}")
print(f"Managed Sockets: {connection_manager.managed_socket_count}")
print(f"Available Managed Sockets: {connection_manager.available_socket_count}")

# make request
print("-" * 40)
Expand All @@ -38,24 +38,24 @@
print(f"Text Response {response_text}")

print("-" * 40)
print("1 request, opened and freed")
print(f"Open Sockets: {connection_manager.managed_socket_count}")
print(f"Freeable Open Sockets: {connection_manager.available_socket_count}")
print("1 request, opened and closed")
print(f"Managed Sockets: {connection_manager.managed_socket_count}")
print(f"Available Managed Sockets: {connection_manager.available_socket_count}")

print("-" * 40)
print(f"Fetching from {TEXT_URL} not in a context handler")
response = requests.get(TEXT_URL)

print("-" * 40)
print("1 request, opened but not freed")
print(f"Open Sockets: {connection_manager.managed_socket_count}")
print(f"Freeable Open Sockets: {connection_manager.available_socket_count}")
print("1 request, opened but not closed")
print(f"Managed Sockets: {connection_manager.managed_socket_count}")
print(f"Available Managed Sockets: {connection_manager.available_socket_count}")

print("-" * 40)
print("Closing everything in the pool")
adafruit_connection_manager.connection_manager_close_all(pool)

print("-" * 40)
print("Everything closed")
print(f"Open Sockets: {connection_manager.managed_socket_count}")
print(f"Freeable Open Sockets: {connection_manager.available_socket_count}")
print(f"Managed Sockets: {connection_manager.managed_socket_count}")
print(f"Available Managed Sockets: {connection_manager.available_socket_count}")
Loading