Made socket server more ambiguous and added prefix version
This commit is contained in:
parent
52489a4ac9
commit
ec16929aad
|
@ -73,7 +73,7 @@ class ThreadPool:
|
|||
try:
|
||||
method(*args, **kwargs)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
eprint(e)
|
||||
finally:
|
||||
# print(f"[worker:{worker_id}]: Task complete")
|
||||
self._exec_controls(controls)
|
||||
|
|
|
@ -4,5 +4,5 @@ from abots.helpers.numbers import clamp, randfloat, isnumeric
|
|||
from abots.helpers.general import eprint, deduce, noop, cast, get_digit, obtain
|
||||
from abots.helpers.general import utc_now, utc_now_timestamp
|
||||
from abots.helpers.logging import Logger
|
||||
from abots.helpers.black_magic import infinitedict, debugger
|
||||
from abots.helpers.black_magic import infinitedict, debugger, singleton, curry
|
||||
from abots.helpers.black_magic import coroutine, generator
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from abots.events import CoroEvent
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
|
||||
|
@ -14,8 +13,8 @@ def debugger(func):
|
|||
signature = ", ".join(args_repr + kwargs_repr)
|
||||
print(f"[DEBUGGER]: Calling {func.__name__}({signature})")
|
||||
result = func(*args, **kwargs)
|
||||
print(f"[DEBUGGER]: {func.__name__!r} returned {value!r}")
|
||||
return value
|
||||
print(f"[DEBUGGER]: {func.__name__!r} returned {result!r}")
|
||||
return result
|
||||
return wrapper_debug
|
||||
|
||||
def coroutine(func):
|
||||
|
@ -28,13 +27,31 @@ def coroutine(func):
|
|||
|
||||
def generator(func):
|
||||
@wraps(func)
|
||||
@coroutine
|
||||
def wrapper_generator(*args, **kwargs):
|
||||
event = CoroEvent()
|
||||
try:
|
||||
while True:
|
||||
yield from func(event, *args, **kwargs)
|
||||
yield from func(*args, **kwargs)
|
||||
except GeneratorExit:
|
||||
pass
|
||||
return wrapper_generator
|
||||
return coroutine(wrapper_generator)
|
||||
|
||||
def singleton(cls):
|
||||
@wraps(cls)
|
||||
def wrapper_singleton(*args, **kwargs):
|
||||
if not wrapper_singleton.instance:
|
||||
wrapper_singleton.instance = cls(*args, **kwargs)
|
||||
return wrapper_singleton.instance
|
||||
wrapper_singleton.instance = None
|
||||
return wrapper_singleton
|
||||
|
||||
def curry(func, argc=None):
|
||||
if argc is None:
|
||||
argc = func.func_code.co_argcount
|
||||
@wraps(func)
|
||||
def wrapper_curry(*args):
|
||||
if len(args) == argc:
|
||||
return func(*args)
|
||||
def curried(*c_args):
|
||||
return func(*(args + c_args))
|
||||
return curry(curried, argc - len(args))
|
||||
return wrapper_curry
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
"""
|
||||
|
||||
net/PrefixSocketServer
|
||||
================
|
||||
|
||||
TODO:
|
||||
* Add logging to broken pipe exceptions
|
||||
|
||||
"""
|
||||
|
||||
from abots.net import SocketServer
|
||||
|
||||
class PrefixSocketServer(SocketServer):
|
||||
def __init__(self, host, port, listeners=5, buffer_size=4096,
|
||||
secure=False, timeout=None, daemon=False):
|
||||
args = host, port, listeners, buffer_size, secure, timeout, daemon
|
||||
super().__init__(*args)
|
||||
|
||||
def _package_message(self, message, *args):
|
||||
if len(args) > 0:
|
||||
formatted = message.format(*args)
|
||||
else:
|
||||
formatted = message
|
||||
packaged = pack(">I", len(formatted)) + formatted.encode()
|
||||
return packaged
|
||||
|
||||
# Packages a message and sends it to socket
|
||||
def send_message(self, uuid, message, *args):
|
||||
sock = self._sock_from_uuid(uuid)
|
||||
if sock is None:
|
||||
return None
|
||||
formatted = self._package_message(message)
|
||||
try:
|
||||
sock.send(formatted)
|
||||
# The socket can either be broken or no longer open at all
|
||||
except (BrokenPipeError, OSError) as e:
|
||||
return
|
|
@ -149,13 +149,18 @@ class SocketClient(Thread):
|
|||
def recv(self):
|
||||
yield from self._obtain("outbox")
|
||||
|
||||
def check(self):
|
||||
for letter in self.recv():
|
||||
if letter is not None and len(letter) > 0:
|
||||
print(letter)
|
||||
|
||||
def send(self, message):
|
||||
self._inbox.put(message)
|
||||
cast(self._bridge, "send", ("inbox", message))
|
||||
|
||||
def connect(self, bridge):
|
||||
self._bridge = bridge()
|
||||
|
||||
|
||||
@coroutine
|
||||
def bridge(self, inbox, outbox, events):
|
||||
try:
|
||||
|
|
|
@ -56,7 +56,7 @@ class SocketServer(Thread):
|
|||
if self.secure:
|
||||
# Note: kwargs is used here to specify any SSL parameters desired
|
||||
self.sock = wrap_socket(self.sock, **kwargs)
|
||||
|
||||
|
||||
# List of all sockets involved (both client and server)
|
||||
self.sockets = list()
|
||||
self.clients = list()
|
||||
|
@ -151,14 +151,6 @@ class SocketServer(Thread):
|
|||
def _sock_from_uuid(self, uuid):
|
||||
return self.uuids.get(uuid, dict()).get("sock", None)
|
||||
|
||||
def _package_message(self, message, *args):
|
||||
if len(args) > 0:
|
||||
formatted = message.format(*args)
|
||||
else:
|
||||
formatted = message
|
||||
packaged = pack(">I", len(formatted)) + formatted.encode()
|
||||
return packaged
|
||||
|
||||
# Closes a connected socket and removes it from the sockets list
|
||||
def close_sock(self, uuid):
|
||||
event = dict()
|
||||
|
@ -217,9 +209,8 @@ class SocketServer(Thread):
|
|||
sock = self._sock_from_uuid(uuid)
|
||||
if sock is None:
|
||||
return None
|
||||
formatted = self._package_message(message)
|
||||
try:
|
||||
sock.send(formatted)
|
||||
sock.send(message)
|
||||
# The socket can either be broken or no longer open at all
|
||||
except (BrokenPipeError, OSError) as e:
|
||||
return
|
||||
|
|
|
@ -1,14 +1,57 @@
|
|||
#!env/bin/python3
|
||||
|
||||
from abots.net import SocketServer, SocketClient
|
||||
#from abots.net import SocketServer, SocketClient
|
||||
#
|
||||
#host = "localhost"
|
||||
#port = 10401
|
||||
#timeout = 3
|
||||
#
|
||||
#server = SocketServer(host, port, timeout=timeout)
|
||||
#client = SocketClient(host, port, timeout=timeout)
|
||||
#
|
||||
#server.start()
|
||||
#server.ready.wait()
|
||||
#client.start()
|
||||
from abots.events import ThreadMarshal
|
||||
from abots.helpers import generator
|
||||
from queue import Queue, Empty
|
||||
from threading import Thread, Event
|
||||
|
||||
host = "localhost"
|
||||
port = 10401
|
||||
timeout = 3
|
||||
def worker(queue, event, timeout):
|
||||
while not event.is_set():
|
||||
try:
|
||||
job = queue.get(timeout=timeout)
|
||||
except Empty:
|
||||
continue
|
||||
assert len(job) == 2, "Expected two parameters"
|
||||
done, task = job
|
||||
assert hasattr(done, "set"), "Expected event"
|
||||
assert len(task) == 3, "Expected three parameters"
|
||||
method, args, kwargs = task
|
||||
assert callable(method), "Expected function"
|
||||
assert isinstance(args, tuple), "Expected tuple"
|
||||
assert isinstance(kwargs, dict), "Expected dict"
|
||||
try:
|
||||
result = method(*args, **kwargs)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
done.set()
|
||||
queue.task_done()
|
||||
|
||||
server = SocketServer(host, port, timeout=timeout)
|
||||
client = SocketClient(host, port, timeout=timeout)
|
||||
def manager(queue, event, timeout):
|
||||
workers = list()
|
||||
current = 0
|
||||
while not event.is_set():
|
||||
try:
|
||||
task = queue.get(timeout=timeout)
|
||||
except Empty:
|
||||
continue
|
||||
assert len(task) == 2, "Expected two parameters"
|
||||
action, payload = task
|
||||
assert isinstance(action, str), "Expected str"
|
||||
if action == "new":
|
||||
assert callable(payload), "Expected function"
|
||||
workers.append((payload))
|
||||
elif action == "reserve" and len(workers) > 0:
|
||||
worker = workers[current]
|
||||
|
||||
server.start()
|
||||
server.ready.wait()
|
||||
client.start()
|
Loading…
Reference in New Issue