SignallingMapRef

fs2.concurrent.SignallingMapRef$
See theSignallingMapRef companion trait

Attributes

Companion:
trait
Source:
Signal.scala
Graph
Supertypes
class Object
trait Matchable
class Any
Self type

Members list

Concise view

Value members

Concrete methods

def State.this._1 case1=> State.this._2 case_=> thrownewIndexOutOfBoundsException(n.toString()) } } objectStateextendsAnyRefwithProduct{ overridedeftoString:String="State" typeMirroredMonoType deffromProduct(`x$0₃`:Product):MirroredMonoType=newState(`x$0₃`.productElement(0).$asInstanceOf$[Long],`x$0₃`.productElement(1).$asInstanceOf$[Map[K,KeyState]]) } typeListener=Deferred[F,Tuple2[Option[V],Long]] caseclassKeyState(value:Option[V],`lastUpdate₂`:Long,listeners:LongMap[Listener]){ overridedefhashCode():Int={ var`acc₂`:Int=-889275714 `acc₂`=mix(`acc₂`,KeyState.this.productPrefix.hashCode()) `acc₂`=mix(`acc₂`,anyHash(value)) `acc₂`=mix(`acc₂`,longHash(lastUpdate)) `acc₂`=mix(`acc₂`,anyHash(listeners)) finalizeHash(`acc₂`,3) } overridedefequals(`x$0₄`:Any):Boolean=KeyState.this.eq(`x$0₄`.$asInstanceOf$[Object]).||(`x$0₄`match{ casex$0:KeyState@unchecked=> KeyState.this.lastUpdate.==(`x$0₅`.lastUpdate).&&(KeyState.this.value.==(`x$0₅`.value)).&&(KeyState.this.listeners.==(`x$0₅`.listeners)).&&(`x$0₅`.canEqual(KeyState.this)) case_=> false }) overridedeftoString():String=_toString(KeyState.this) overridedefcanEqual(`that₂`:Any):Boolean=`that₂`.isInstanceOf[KeyState@unchecked] overridedefproductArity:Int=3 overridedefproductPrefix:String="KeyState" overridedefproductElement(`n₂`:Int):Any=`n₂`match{ case0=> KeyState.this._1 case1=> KeyState.this._2 case2=> KeyState.this._3 case_=> thrownewIndexOutOfBoundsException(`n₂`.toString()) } } objectKeyStateextendsAnyRefwithProduct{ overridedeftoString:String="KeyState" typeMirroredMonoType deffromProduct(`x$0₆`:Product):MirroredMonoType=newKeyState(`x$0₆`.productElement(0).$asInstanceOf$[Option[V]],`x$0₆`.productElement(1).$asInstanceOf$[Long],`x$0₆`.productElement(2).$asInstanceOf$[LongMap[Listener]]) } toFunctorOps[F,Tuple2[Ref[F,State],Ref[F,Long]]](catsSyntaxSemigroupal[F,Ref[F,State]](F.ref[State](State.apply(0L,initial.map[K,KeyState](((x$1:Tuple2[K,V])=>x$1match{ caseTuple2(k,v)=> ArrowAssoc[K](k).->[KeyState](KeyState.apply(Some.apply[V](v),0L,LongMap.empty[Deferred[F,Tuple2[Option[V],Long]]])) })))))(F).product[Ref[F,Long]](F.ref[Long](1L)))(F).map[SignallingMapRef[F,K,Option[V]]](((`x$1₂`:Tuple2[Ref[F,State],Ref[F,Long]])=>`x$1₂`match{ caseTuple2(state,ids)=> defnewId:F[Long]=ids.getAndUpdate(((_$32:Long)=>_$32.+(1))) defupdateAndNotify[U](state:State,`k₂`:K,f:Function1[Option[V],Tuple2[Option[V],U]]):Tuple2[State,F[U]]={ valkeyState:Option[KeyState]=state.keys.get(`k₂`) val$7$:Tuple2[Option[V],U]=(f.apply(keyState.flatMap[V](((_$33:KeyState)=>_$33.value))):@unchecked)match{ caseTuple2(newValue,result)=> Tuple2.apply[Option[V],U](newValue,result) } val`newValue₂`:Option[V]=$7$._1 val`result₂`:U=$7$._2 val`lastUpdate₃`:Long={ vallu:Long=state.lastUpdate.+(1) if(lu.==(-1L))0Lelselu } vallastKeyUpdate:Long=if(`newValue₂`.isDefined)`lastUpdate₃`else-1L valnewKeys:Map[K,KeyState]=if(`newValue₂`.isDefined)state.keys.updated[KeyState](`k₂`,KeyState.apply(`newValue₂`,lastKeyUpdate,LongMap.empty[Deferred[F,Tuple2[Option[V],Long]]]))elsestate.keys.-(`k₂`) valnewState:State=State.apply(`lastUpdate₃`,newKeys) valnotifyListeners:F[Unit]=keyState.fold[F[Unit]](F.unit)(((`keyState₂`:KeyState)=>toFoldableOps[Vector,Deferred[F,Tuple2[Option[V],Long]]](`keyState₂`.listeners.values.toVector)(catsTraverseForVector).traverse_[F,Boolean](((listener:Deferred[F,Tuple2[Option[V],Long]])=>listener.complete(ArrowAssoc[Option[V]](`newValue₂`).->[Long](lastKeyUpdate))))(F))) ArrowAssoc[State](newState).->[F[U]](toFunctorOps[F,Unit](notifyListeners)(F).as[U](`result₂`)) } ((`k₃`:K)=>{ finalclass$anon()extendsSignallingRef[F,Option[V]]{ defget:F[Option[V]]=toFunctorOps[F,State](`state₂`.get)(F).map[Option[V]](((_$34:State)=>_$34.keys.get(`k₃`).flatMap[V](((_$35:KeyState)=>_$35.value)))) defcontinuous:Stream[F,Option[V]]=Stream.repeatEval[F,Option[V]]($anon.this.get) defdiscrete:Stream[F,Option[V]]=Stream.resource[F,Tuple2[Option[V],Stream[F,Option[V]]]]($anon.this.getAndDiscreteUpdates(F))(F).flatMap[F,Option[V]](((`x$1₃`:Tuple2[Option[V],Stream[F,Option[V]]])=>`x$1₃`match{ caseTuple2(a,updates)=> Stream.emit[[x>:Nothing<:Any]=>Pure[x],Option[V]](a).++[F,Option[V]](updates) }))(value) overridedefgetAndDiscreteUpdates(implicitev:Concurrent[F]):Resource[F,Tuple2[Option[V],Stream[F,Option[V]]]]=$anon.this.getAndDiscreteUpdatesImpl defgetAndDiscreteUpdatesImpl:Resource[F,Tuple2[Option[V],Stream[[x>:Nothing<:Any]=>F[x],Option[V]]]]={ defgo(id:Long,lastSeen:Long):Stream[F,Option[V]]={ defgetNext:F[Tuple2[Option[V],Long]]=catsSyntaxFlatten[F,Tuple2[Option[V],Long]](toFlatMapOps[F,Deferred[F,Tuple2[Option[V],Long]]](F.deferred[Tuple2[Option[V],Long]])(F).flatMap[F[Tuple2[Option[V],Long]]](((wait:Deferred[F,Tuple2[Option[V],Long]])=>`state₂`.modify[F[Tuple2[Option[V],Long]]](((`state₃`:State)=>{ val`keyState₃`:Option[KeyState]=`state₃`.keys.get(`k₃`) val`value₂`:Option[V]=`keyState₃`.flatMap[V](((_$36:KeyState)=>_$36.value)) val`lastUpdate₄`:Long=`keyState₃`.fold[Long](-1L)(((_$37:KeyState)=>_$37.lastUpdate)) val`listeners₂`:LongMap[Listener]=`keyState₃`.fold[LongMap[Listener]](LongMap.empty[Listener])(((_$38:KeyState)=>_$38.listeners)) if(`lastUpdate₄`.!=(lastSeen))ArrowAssoc[State](`state₃`).->[F[Tuple2[Option[V],Long]]](catsSyntaxApplicativeId[Tuple2[Option[V],Long]](ArrowAssoc[Option[V]](`value₂`).->[Long](`lastUpdate₄`)).pure[F](F))else{ val`newKeys₂`:Map[K,KeyState]=`state₃`.keys.updated[KeyState](`k₃`,KeyState.apply(`value₂`,`lastUpdate₄`,`listeners₂`.updated[Listener](id,wait))) ArrowAssoc[State](`state₃`.copy(`state₃`.copy$default$1,keys=`newKeys₂`)).->[F[Tuple2[Option[V],Long]]](wait.get) } })))))(F).flatten(F) Stream.eval[F,Tuple2[Option[V],Long]](getNext).flatMap[F,Option[V]](((`x$1₄`:Tuple2[Option[V],Long])=>`x$1₄`match{ caseTuple2(v,lastUpdate)=> Stream.emit[[x>:Nothing<:Any]=>Pure[x],Option[V]](`v₂`).++[F,Option[V]](go(id,lastSeen=`lastUpdate₅`)) }))(value) } defcleanup(`id₂`:Long):F[Unit]=`state₂`.update(((`state₄`:State)=>`state₄`.keys.get(`k₃`).fold[State](`state₄`)(((`x$1₅`:KeyState)=>`x$1₅`match{ caseKeyState(value,lastUpdate,listeners)=> valnewListeners:LongMap[Listener]=`listeners₃`.-(`id₂`) val`newKeys₃`:Map[K,KeyState]=if(`value₃`.isEmpty.&&(newListeners.isEmpty))`state₄`.keys.-(`k₃`)else`state₄`.keys.updated[KeyState](`k₃`,KeyState.apply(`value₃`,`lastUpdate₆`,newListeners)) `state₄`.copy(`state₄`.copy$default$1,keys=`newKeys₃`) })))) Resource.eval[F,Tuple2[Option[V],Stream[[x>:Nothing<:Any]=>F[x],Option[V]]]](toFunctorOps[F,State](`state₂`.get)(F).map[Tuple2[Option[V],Stream[[x>:Nothing<:Any]=>F[x],Option[V]]]](((`state₅`:State)=>Tuple2.apply[Option[V],Stream[[x>:Nothing<:Any]=>F[x],Option[V]]](`state₅`.keys.get(`k₃`).flatMap[V](((_$39:KeyState)=>_$39.value)),Stream.bracket[F,Long](newId)(((`id₃`:Long)=>cleanup(`id₃`))).flatMap[[x>:Nothing<:Any]=>F[x],Option[V]](((_$40:Long)=>go(_$40,`state₅`.keys.get(`k₃`).fold[Long](-1L)(((_$41:KeyState)=>_$41.lastUpdate)))))(value))))) } defset(`v₃`:Option[V]):F[Unit]=$anon.this.update(((_$42:Option[V])=>`v₃`)) defupdate(`f₂`:Function1[Option[V],Option[V]]):F[Unit]=$anon.this.modify[Unit](((`v₄`:Option[V])=>Tuple2.apply[Option[V],Unit](`f₂`.apply(`v₄`),()))) defmodify[U](`f₃`:Function1[Option[V],Tuple2[Option[V],U]]):F[U]=`state₂`.flatModify[U](((_$43:State)=>updateAndNotify[U](_$43,`k₃`,`f₃`)))(F) deftryModify[U](`f₄`:Function1[Option[V],Tuple2[Option[V],U]]):F[Option[U]]=monadCancelOps_[F,Option[U]](toFlatMapOps[F,Option[F[U]]](`state₂`.tryModify[F[U]](((_$44:State)=>updateAndNotify[U](_$44,`k₃`,`f₄`))))(F).flatMap[Option[U]](((_$45:Option[F[U]])=>toTraverseOps[Option,F[U]](_$45)(catsTraverseForOption).sequence[F,U](refl[F[U]],F)))).uncancelable(F) deftryUpdate(`f₅`:Function1[Option[V],Option[V]]):F[Boolean]=toFunctorOps[F,Option[Unit]]($anon.this.tryModify[Unit](((`a₂`:Option[V])=>Tuple2.apply[Option[V],Unit](`f₅`.apply(`a₂`),()))))(F).map[Boolean](((_$46:Option[Unit])=>_$46.isDefined)) defaccess:F[Tuple2[Option[V],Function1[Option[V],F[Boolean]]]]=toFunctorOps[F,Tuple2[State,Function1[State,F[Boolean]]]](`state₂`.access)(F).map[Tuple2[Option[V],Function1[Option[V],F[Boolean]]]](((`x$1₆`:Tuple2[State,Function1[State,F[Boolean]]])=>`x$1₆`match{ caseTuple2(state,set)=> valsetter:Function1[Option[V],F[Boolean]]=((`newValue₃`:Option[V])=>{ val$8$:Tuple2[State,F[Unit]]=(updateAndNotify[Unit](`state₆`,`k₃`,((_$47:Option[V])=>Tuple2.apply[Option[V],Unit](`newValue₃`,()))):@unchecked)match{ caseTuple2(newState,notifyListeners)=> Tuple2.apply[State,F[Unit]](`newState₂`,`notifyListeners₂`) } val`newState₃`:State=$8$._1 val`notifyListeners₃`:F[Unit]=$8$._2 toFlatMapOps[F,Boolean](set.apply(`newState₃`))(F).flatTap[Unit](((succeeded:Boolean)=>catsSyntaxApplicativeByName[F,Unit](`notifyListeners₃`).whenA(succeeded)(F))) }) Tuple2.apply[Option[V],Function1[Option[V],F[Boolean]]](`state₆`.keys.get(`k₃`).flatMap[V](((_$48:KeyState)=>_$48.value)),setter) })) deftryModifyState[U](`state₇`:cats.data.State[Option[V],U]):F[Option[U]]={ val`f₆`:Function1[Option[V],Eval[Tuple2[Option[V],U]]]=`state₇`.runF.value $anon.this.tryModify[U](((`v₅`:Option[V])=>`f₆`.apply(`v₅`).value)) } defmodifyState[U](`state₈`:cats.data.State[Option[V],U]):F[U]={ val`f₇`:Function1[Option[V],Eval[Tuple2[Option[V],U]]]=`state₈`.runF.value $anon.this.modify[U](((`v₆`:Option[V])=>`f₇`.apply(`v₆`).value)) } } (new$anon():SignallingRef[F,Option[V]]) }) })) }" t="n"class="documentableName ">ofSingleImmutableMap[F[_], K, V](initial: Map[K, V])(implicit F: Concurrent[F]): F[SignallingMapRef[F, K, Option[V]]]

Builds a SignallingMapRef for effect F, initialized to the supplied value.

Builds a SignallingMapRef for effect F, initialized to the supplied value.

Update semantics for discrete are the same as SignallingRef, with one exception: it cannot distinguish updates that remove a key (by setting its value to None).

More specifically: if you remove a key, this will only notify once per listener i.e. setting it to None again will not trigger another update. Furthermore, if a listener's last pull returned None, and by the time it pulls again the current value is None, then it will not be notified regardless of any non-None updates that may have happened between the pulls. This special semantic for None is necessary to prevent memory leaks at keys with no values and no listeners.

Attributes

Source:
Signal.scala