Added a simple state management system
This commit is contained in:
parent
41e75554ed
commit
b8bb9f8189
|
@ -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})
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue