@@ -236,6 +236,7 @@ def __init__(
236236 self ,
237237 fn : EffectFunction ,
238238 * ,
239+ suspended : bool = False ,
239240 priority : int = 0 ,
240241 session : Union [MISSING_TYPE , "Session" , None ] = MISSING ,
241242 ) -> None :
@@ -249,6 +250,8 @@ def __init__(
249250 self ._is_async : bool = False
250251
251252 self ._priority : int = priority
253+ self ._suspended = suspended
254+ self ._on_resume : Callable [[], None ] = lambda : None
252255
253256 self ._invalidate_callbacks : list [Callable [[], None ]] = []
254257 self ._destroyed : bool = False
@@ -286,8 +289,16 @@ def on_invalidate_cb() -> None:
286289 for cb in self ._invalidate_callbacks :
287290 cb ()
288291
289- # TODO: Wrap this stuff up in a continue callback, depending on if suspended?
290- ctx .add_pending_flush (self ._priority )
292+ if self ._destroyed :
293+ return
294+
295+ def _continue () -> None :
296+ ctx .add_pending_flush (self ._priority )
297+
298+ if self ._suspended :
299+ self ._on_resume = _continue
300+ else :
301+ _continue ()
291302
292303 async def on_flush_cb () -> None :
293304 if not self ._destroyed :
@@ -325,6 +336,35 @@ def destroy(self) -> None:
325336 if self ._ctx is not None :
326337 self ._ctx .invalidate ()
327338
339+ def suspend (self ) -> None :
340+ """
341+ Causes this observer to stop scheduling flushes (re-executions) in response to
342+ invalidations. If the observer was invalidated prior to this call but it has not
343+ re-executed yet (because it waits until on_flush is called) then that
344+ re-execution will still occur, because the flush is already scheduled.
345+ """
346+ self ._suspended = True
347+
348+ def resume (self ) -> None :
349+ """
350+ Causes this observer to start re-executing in response to invalidations. If the
351+ observer was invalidated while suspended, then it will schedule itself for
352+ re-execution (pending flush).
353+ """
354+ if self ._suspended :
355+ self ._suspended = False
356+ self ._on_resume ()
357+ self ._on_resume = lambda : None
358+
359+ def set_priority (self , priority : int = 0 ) -> None :
360+ """
361+ Change this observer's priority. Note that if the observer is currently
362+ invalidated, then the change in priority will not take effect until the next
363+ invalidation--unless the observer is also currently suspended, in which case the
364+ priority change will be effective upon resume.
365+ """
366+ self ._priority = priority
367+
328368 def _on_session_ended_cb (self ) -> None :
329369 self .destroy ()
330370
@@ -334,18 +374,27 @@ def __init__(
334374 self ,
335375 fn : EffectFunctionAsync ,
336376 * ,
377+ suspended : bool = False ,
337378 priority : int = 0 ,
338379 session : Union [MISSING_TYPE , "Session" , None ] = MISSING ,
339380 ) -> None :
340381 if not utils .is_async_callable (fn ):
341382 raise TypeError (self .__class__ .__name__ + " requires an async function" )
342383
343- super ().__init__ (cast (EffectFunction , fn ), session = session , priority = priority )
384+ super ().__init__ (
385+ cast (EffectFunction , fn ),
386+ suspended = suspended ,
387+ session = session ,
388+ priority = priority ,
389+ )
344390 self ._is_async = True
345391
346392
347393def effect (
348- * , priority : int = 0 , session : Union [MISSING_TYPE , "Session" , None ] = MISSING
394+ * ,
395+ suspended : bool = False ,
396+ priority : int = 0 ,
397+ session : Union [MISSING_TYPE , "Session" , None ] = MISSING ,
349398) -> Callable [[Union [EffectFunction , EffectFunctionAsync ]], Effect ]:
350399 """[summary]
351400
@@ -360,10 +409,12 @@ def effect(
360409 def create_effect (fn : Union [EffectFunction , EffectFunctionAsync ]) -> Effect :
361410 if utils .is_async_callable (fn ):
362411 fn = cast (EffectFunctionAsync , fn )
363- return EffectAsync (fn , priority = priority , session = session )
412+ return EffectAsync (
413+ fn , suspended = suspended , priority = priority , session = session
414+ )
364415 else :
365416 fn = cast (EffectFunction , fn )
366- return Effect (fn , priority = priority , session = session )
417+ return Effect (fn , suspended = suspended , priority = priority , session = session )
367418
368419 return create_effect
369420
0 commit comments