Added a simple state management system

This commit is contained in:
aewens 2019-08-20 16:28:54 -05:00
parent 41e75554ed
commit b8bb9f8189
2 changed files with 78 additions and 1 deletions

77
state_management.py Normal file
View File

@ -0,0 +1,77 @@
from abots.helpers import generator, infinitedict
from gevent.lock import BoundedSemaphore
from collections import namedtuple
class AtomicDict(object):#dict):
def __init__(self, *args, **kwargs):
#dict.__init__(self, *args, **kwargs)
self._dict = dict()
self._lock = BoundedSemaphore()
def __enter__(self):
self._lock.acquire()
return self._dict
def __exit__(self, _type, value, traceback):
self._lock.release()
def get_state(meta):
state = infinitedict()
with meta as m:
state = m.get("state")
assert state is not None, "'state' is missing"
return state.copy()
def unsubscribe(meta, listener):
with meta as m:
listeners = m.get("listeners")
assert listener in listeners, f"'{listener}' missing from: {listeners}"
listeners.remove(listener)
def subscribe(meta, listener):
with meta as m:
listeners = m.get("listeners")
assert listeners is not None, "'listeners' is missing"
listeners.append(listener)
return lambda: unsubscribe(meta, listener)
@generator
def dispatch(meta):
action = (yield)
with meta as m:
is_dispatching = m.get("is_dispatching")
assert is_dispatching is not None, "'is_dispatching' is missing"
if is_dispatching:
raise Exception("Reducers cannot dispatch actions")
try:
with meta as m:
m["is_dispatching"] = True
reducer = m.get("reducer")
assert reducer is not None, "'reducer' is missing"
m["state"] = reducer(state, action)
finally:
with meta as m:
m["is_dispatching"] = False
with meta as m:
listeners = m.get("listeners")
assert listeners is not None, "'listeners' is missing"
for listener in listeners[:]:
listener()
def manager(reducer, initial_state=infinitedict()):
meta = AtomicDict()
with meta as m:
m["listeners"] = list()
m["is_dispatching"] = False
m["reducer"] = reducer
m["state"] = initial_state
return meta, dispatch(meta)
Action = namedtuple("Action", ["type", "payload"])
meta, actions = manager(reducer, {"init": False})

View File

@ -1,5 +1,5 @@
from state_management =
from abots.helpers import generator, infinitedict
#from queue import Queue, Empty
from time import monotonic as time
from gevent import Greenlet, sleep, joinall
from gevent.queue import Queue, Empty