Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
3.1 kB
2
Indexable
Never
import xmlrpc.server
import xmlrpc.client
import threading
import time
import logging
import functools

class ConnectionPool:
    def __init__(self, host, port, pool_size=10, retry_interval=5, max_retries=5):
        self.host = host
        self.port = port
        self.pool_size = pool_size
        self.retry_interval = retry_interval
        self.max_retries = max_retries
        self.pool = []
        self.current_size = 0
        self.logger = logging.getLogger(__name__)

    def create_connection(self):
        retries = 0
        while True:
            try:
                proxy = xmlrpc.client.ServerProxy(f"http://{self.host}:{self.port}")
                return proxy
            except Exception as e:
                retries += 1
                if retries > self.max_retries:
                    raise e
                time.sleep(self.retry_interval)

    def get_connection(self):
        if self.current_size < self.pool_size:
            self.current_size += 1
            return self.create_connection()
        else:
            while True:
                if self.pool:
                    return self.pool.pop()
                time.sleep(0.1)

    def release_connection(self, connection):
        self.pool.append(connection)

class RPCServer:
    def __init__(self, host, port):
        self.server = xmlrpc.server.SimpleXMLRPCServer((host, port))

    def register_function(self, func, name=None):
        self.server.register_function(func, name)

    def serve_forever(self):
        self.server.serve_forever()

class RPCClient:
    def __init__(self, host, port, pool_size=10, retry_interval=5, max_retries=5):
        self.connection_pool = ConnectionPool(host, port, pool_size, retry_interval, max_retries)

    def call(self, method, *args, **kwargs):
        connection = self.connection_pool.get_connection()
        try:
            return getattr(connection, method)(*args, **kwargs)
        except xmlrpc.client.Fault as e:
            if e.faultCode == -32601:  # method not found
                raise Exception(f"Method not found: {method}") from e
            else:
                raise e
        except Exception as e:
            raise e
        finally:
            self.connection_pool.release_connection(connection)

    def call_async(self, method, *args, **kwargs):
        @functools.wraps(method)
        def wrapper(*args, **kwargs):
            try:
                result = self.call(method, *args, **kwargs)
                self.async_result = (True, result)
            except Exception as e:
                self.async_result = (False, e)

        thread = threading.Thread(target=wrapper, args=args, kwargs=kwargs)
        thread.start()
        return thread
def add(x, y):
    return x + y

server = RPCServer("localhost", 8000)
server.register_function(add)
server.serve_forever()

client = RPCClient("localhost", 8000)
result = client.call("add", 1, 2)
print(result)  # 3

thread = client.call_async("add", 3, 4)
thread.join()
success, result = client.async_result
if success:
    print(result)  # 7
else:
    print(result)  # Exception object