From 563a33055b69879fe4e52f4448760b550664a0d7 Mon Sep 17 00:00:00 2001 From: Thomas Legros Date: Tue, 16 Jan 2024 13:46:12 +0100 Subject: [PATCH] Fix the singleton pattern & release conn not working as expect --- src/pytmv1/adapter.py | 3 --- src/pytmv1/caller.py | 39 ++++++++++++++++++------------- tests/integration/test_network.py | 14 +++++++---- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/pytmv1/adapter.py b/src/pytmv1/adapter.py index 5802d20..08c1781 100644 --- a/src/pytmv1/adapter.py +++ b/src/pytmv1/adapter.py @@ -11,13 +11,10 @@ class HTTPConnectionPool(HTTPUrllib): @typing.no_type_check def urlopen(self, method, url, **kwargs): - kwargs.pop("preload_content", "") return super().urlopen( method, url, pool_timeout=5, - release_conn=True, - preload_content=False, **kwargs, ) diff --git a/src/pytmv1/caller.py b/src/pytmv1/caller.py index 6f9307f..17dfba7 100755 --- a/src/pytmv1/caller.py +++ b/src/pytmv1/caller.py @@ -1,9 +1,10 @@ from __future__ import annotations import logging +import threading from functools import lru_cache from logging import Logger -from typing import Callable, List, Optional, Type, Union +from typing import Any, Callable, List, Optional, Type, Union from . import utils from .core import Core @@ -66,9 +67,9 @@ from .results import MultiResult, Result log: Logger = logging.getLogger(__name__) +lock = threading.Lock() -@lru_cache(maxsize=None) def client( name: str, token: str, @@ -78,7 +79,7 @@ def client( connect_timeout: int = 30, read_timeout: int = 30, ) -> Client: - """Helper function to initialize a :class:`Client`. + """Synchronized Helper function to initialize a :class:`Client`. :param name: Identify the application using this library. :type name: str @@ -96,22 +97,28 @@ def client( :type connect_timeout: int :rtype: Client """ + lock.acquire() + client_ = _client( + appname=name, + token=token, + url=url, + pool_connections=pool_connections, + pool_maxsize=pool_maxsize, + connect_timeout=connect_timeout, + read_timeout=read_timeout, + ) + lock.release() + return client_ + + +@lru_cache(maxsize=1) +def _client(**kwargs: Any) -> Client: log.debug( "Initializing new client with [Appname=%s, Token=*****, URL=%s]", - name, - url, - ) - return Client( - Core( - name, - token, - url, - pool_connections, - pool_maxsize, - connect_timeout, - read_timeout, - ) + kwargs["appname"], + kwargs["url"], ) + return Client(Core(**kwargs)) class Client: diff --git a/tests/integration/test_network.py b/tests/integration/test_network.py index aa4d763..db95879 100755 --- a/tests/integration/test_network.py +++ b/tests/integration/test_network.py @@ -4,6 +4,8 @@ import psutil import pytest +import pytmv1 + def test_conn_opened_with_single_call_single_client_is_one(client): client.get_exception_list() @@ -19,7 +21,7 @@ def test_conn_opened_with_multi_call_single_client_is_one( def test_conn_opened_with_multi_processing_single_client_is_one(client): - threads = thread_list(lambda: client.get_exception_list()) + threads = thread_list(lambda: client.add_alert_note("1", "dummy note")) for t in threads: t.start() for t in threads: @@ -27,10 +29,12 @@ def test_conn_opened_with_multi_processing_single_client_is_one(client): assert len(list_tcp_conn()) == 1 -def test_conn_opened_with_multi_processing_multi_client_is_one( - pytestconfig, client -): - threads = thread_list(lambda: client.get_exception_list()) +def test_conn_opened_with_multi_processing_multi_client_is_one(url): + threads = thread_list( + lambda: pytmv1.client( + "appname", "dummyToken", url + ).get_exception_list() + ) for t in threads: t.start() for t in threads: