@@ -50,6 +50,7 @@ def __init__(
5050 options : CreateStoreOptions [Action , Event ] | None = None ,
5151 ) -> None :
5252 """Create a new store."""
53+ self .finished = False
5354 self .store_options = options or CreateStoreOptions ()
5455 self .reducer = reducer
5556 self ._create_task = self .store_options .task_creator
@@ -95,35 +96,37 @@ def __init__(
9596 if self .store_options .scheduler :
9697 self .store_options .scheduler (self .run , interval = True )
9798
99+ def _call_listeners (self : Store [State , Action , Event ], state : State ) -> None :
100+ for listener_ in self ._listeners .copy ():
101+ if isinstance (listener_ , weakref .ref ):
102+ listener = listener_ ()
103+ if listener is None :
104+ self ._listeners .discard (listener_ )
105+ continue
106+ else :
107+ listener = listener_
108+ result = listener (state )
109+ if asyncio .iscoroutine (result ) and self ._create_task :
110+ self ._create_task (result )
111+
98112 def _run_actions (self : Store [State , Action , Event ]) -> None :
99113 action = self ._actions .pop (0 )
100114 result = self .reducer (self ._state , action )
101115 if is_complete_reducer_result (result ):
102116 self ._state = result .state
117+ self ._call_listeners (self ._state )
103118 self .dispatch ([* (result .actions or []), * (result .events or [])])
104119 elif is_state_reducer_result (result ):
105120 self ._state = result
121+ self ._call_listeners (self ._state )
106122
107123 if isinstance (action , FinishAction ):
108124 self .dispatch (cast (Event , FinishEvent ()))
109125
110- if len (self ._actions ) == 0 and self ._state :
111- for listener_ in self ._listeners .copy ():
112- if isinstance (listener_ , weakref .ref ):
113- listener = listener_ ()
114- if listener is None :
115- self ._listeners .discard (listener_ )
116- continue
117- else :
118- listener = listener_
119- result = listener (self ._state )
120- if asyncio .iscoroutine (result ) and self ._create_task :
121- self ._create_task (result )
122-
123126 def _run_event_handlers (self : Store [State , Action , Event ]) -> None :
124127 event = self ._events .pop (0 )
125128 for event_handler_ in self ._event_handlers [type (event )].copy ():
126- self ._event_handlers_queue .put ((event_handler_ , event ))
129+ self ._event_handlers_queue .put_nowait ((event_handler_ , event ))
127130
128131 def run (self : Store [State , Action , Event ]) -> None :
129132 """Run the store."""
@@ -134,7 +137,12 @@ def run(self: Store[State, Action, Event]) -> None:
134137
135138 if len (self ._events ) > 0 :
136139 self ._run_event_handlers ()
137- if not any (worker .is_alive () for worker in self ._workers ):
140+ if (
141+ self .finished
142+ and self ._actions == []
143+ and self ._events == []
144+ and not any (worker .is_alive () for worker in self ._workers )
145+ ):
138146 self .clean_up ()
139147
140148 def clean_up (self : Store [State , Action , Event ]) -> None :
@@ -219,7 +227,8 @@ def unsubscribe() -> None:
219227
220228 def _handle_finish_event (self : Store [State , Action , Event ]) -> None :
221229 for _ in range (self .store_options .threads ):
222- self ._event_handlers_queue .put (None )
230+ self ._event_handlers_queue .put_nowait (None )
231+ self .finished = True
223232
224233 def autorun (
225234 self : Store [State , Action , Event ],
0 commit comments