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 abots.helpers import generator, infinitedict
#from queue import Queue, Empty
from time import monotonic as time from time import monotonic as time
from gevent import Greenlet, sleep, joinall from gevent import Greenlet, sleep, joinall
from gevent.queue import Queue, Empty from gevent.queue import Queue, Empty