Sorta, kinda, working version of actor model and state-dispatch model
This commit is contained in:
parent
b3a44bc9f2
commit
41e75554ed
142
taijitu.py
142
taijitu.py
|
@ -1,91 +1,67 @@
|
||||||
from abots.helpers import generator
|
from abots.helpers import generator, infinitedict
|
||||||
from psutil import Process as PSProcess
|
#from queue import Queue, Empty
|
||||||
from queue import Queue, Empty
|
from time import monotonic as time
|
||||||
from time import sleep, monotonic as time
|
from gevent import Greenlet, sleep, joinall
|
||||||
from os import getloadavg
|
from gevent.queue import Queue, Empty
|
||||||
from collections import deque
|
|
||||||
from multiprocessing import cpu_count
|
|
||||||
|
|
||||||
actions = dict()
|
hooks = dict()
|
||||||
events = Queue()
|
|
||||||
last = time()
|
def reducer(state, action):
|
||||||
ticks = deque()
|
name = action.get("name")
|
||||||
ticks.append(0)
|
data = action.get("data")
|
||||||
max_loadavg = float(cpu_count())
|
if name == "ADD":
|
||||||
threshold = 15.0
|
state["counter"] = state.get("counter", 0) + data
|
||||||
max_cpu = 25.0
|
|
||||||
sleeping = 0.001
|
return state
|
||||||
sleepings = list()
|
|
||||||
stats = list()
|
@generator
|
||||||
magic = 0
|
def dispatcher():
|
||||||
step = 0.0001
|
state, action = (yield)
|
||||||
max_ticks = 0
|
state = state.copy() if state else infinitedict()
|
||||||
loops = 0
|
reducer(state, action)
|
||||||
proc = PSProcess()
|
|
||||||
cpu = proc.cpu_percent()
|
dispatch = dispatcher()
|
||||||
|
|
||||||
def register(func):
|
def register(func):
|
||||||
actions[func.__name__] = generator(func)
|
f = func()
|
||||||
|
f.start()
|
||||||
|
hooks[func.__name__.lower()] = f
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@register
|
def loop():
|
||||||
def push():
|
joinall([func for name, func in hooks.items()])
|
||||||
message = (yield)
|
|
||||||
time1 = round(sleeping, 6)
|
def transmit(hook_name, message):
|
||||||
time2 = round(magic, 6)
|
hook = hooks.get(hook_name)
|
||||||
print("push", message, time1, time2, loops, max_ticks, cpu)
|
inbox = getattr(hook, "inbox", None)
|
||||||
event = "pull", ticks[-1]
|
put = getattr(inbox, "put", None)
|
||||||
events.put_nowait(event)
|
if callable(put):
|
||||||
|
put(message)
|
||||||
|
|
||||||
|
class Actor(Greenlet):
|
||||||
|
def __init__(self):
|
||||||
|
self.inbox = Queue()
|
||||||
|
Greenlet.__init__(self)
|
||||||
|
|
||||||
|
def send(self, message):
|
||||||
|
NotImplemented
|
||||||
|
|
||||||
|
def _run(self):
|
||||||
|
self.running = True
|
||||||
|
while self.running:
|
||||||
|
message = self.inbox.get()
|
||||||
|
self.send(message)
|
||||||
|
|
||||||
@register
|
@register
|
||||||
def pull():
|
class Ping(Actor):
|
||||||
message = (yield)
|
def send(self, message):
|
||||||
time1 = round(sleeping, 6)
|
print(message)
|
||||||
time2 = round(magic, 6)
|
dispatch("pong", "ping")
|
||||||
print("pull", message, time1, time2, loops, max_ticks, cpu)
|
sleep(0)
|
||||||
event = "push", ticks[-1]
|
|
||||||
events.put_nowait(event)
|
|
||||||
|
|
||||||
seed = "push", ticks[-1]
|
@register
|
||||||
events.put_nowait(seed)
|
class Pong(Actor):
|
||||||
done = time() + 60
|
def send(self, message):
|
||||||
prev_cpu = 0
|
print(message)
|
||||||
prev_loadavg = 0
|
dispatch("ping", "pong")
|
||||||
while True: #time() < done:
|
sleep(0)
|
||||||
if time() >= last + 1:
|
|
||||||
ticks.append(0)
|
|
||||||
last = time()
|
|
||||||
loadavg = getloadavg()[0]
|
|
||||||
diff_loadavg = loadavg - prev_loadavg
|
|
||||||
prev_loadavg = loadavg
|
|
||||||
if loadavg >= max_loadavg and diff_loadavg > 0:
|
|
||||||
sleeping = sleeping + step * 10
|
|
||||||
else:
|
|
||||||
cpu = proc.cpu_percent()
|
|
||||||
diff_cpu = cpu - prev_cpu
|
|
||||||
prev_cpu = cpu
|
|
||||||
if cpu >= max_cpu and diff_cpu > 0:
|
|
||||||
sleeping = sleeping + step * 10
|
|
||||||
elif cpu >= threshold and diff_cpu > 0:
|
|
||||||
sleeping = sleeping + step
|
|
||||||
elif sleeping - step >= 0 and diff_cpu < 0:
|
|
||||||
sleeping = sleeping - step
|
|
||||||
|
|
||||||
sleepings.append(sleeping)
|
|
||||||
stat = sum(sleepings) / len(sleepings)
|
|
||||||
stats.append(stat)
|
|
||||||
magic = sum(stats) / len(stats)
|
|
||||||
max_ticks = max(ticks)
|
|
||||||
loops = loops + 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
event = events.get_nowait()
|
|
||||||
source, message = event
|
|
||||||
action = actions.get(source)
|
|
||||||
if action:
|
|
||||||
action().send(message)
|
|
||||||
except Empty:
|
|
||||||
break
|
|
||||||
|
|
||||||
sleep(sleeping)
|
|
||||||
ticks[-1] = ticks[-1] + 1
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user