When is onTransition codes executed, exactly? -- Akka, FSM - scala

I have a doubt whether the code in the "onTransition" block (akka FSM) is executed after the new state is reached? or before the new state is reached.
The articles and book I've read mentions the word "during"... which (to me) suggests "before the new state is reached".
Does it really matter?
I guess so... I mean, changing to a new state implies (in most cases) changing the state data. Usually we would change that state data in the event handler (in the "when-case-event" block).
But what if the new state depends on the outcome of calculations / actions performed in the "onTransition" block? In that case, we will have to move that block into the "when-case-event" block.
So, it's not clear for me now...: is there any rule / guidance: what actions should go into the "when-case-event", and what actions should go into the "onTransition"?
addition: I hope in the next revision of Akka Doc, some kind of clarification / guidance on this topic would be included.
Thanks in advance,
Raka

In onTransition the old state data is available via stateData, and the new state data is available as nextStateData. The new state cannot be changed by onTransition, but you can send a message to self.

Related

Can we edit callback function HAL_UART_TxCpltCallback for our convenience?

I am a newbie to both FreeRTOS and STM32. I want to know how exactly callback function HAL_UART_TxCpltCallback for HAL_UART_Transmit_IT works ?
Can we edit that that callback function for our convenience ?
Thanks in Advance
You call HAL_UART_Transmit_IT to transmit your data in the "interrupt" (non-blocking) mode. This call returns immediately, likely well before your data gets fully trasmitted.
The sequence of events is as follows:
HAL_UART_Transmit_IT stores a pointer and length of the data buffer you provide. It doesn't perform a copy, so your buffer you passed needs to remain valid until callback gets called. For example it cannot be a buffer you'll perform delete [] / free on before callbacks happen or a buffer that's local in a function you're going to return from before a callback call.
It then enables TXE interrupt for this UART, which happens every time the DR (or TDR, depending on STM in use) is empty and can have new data written
At this point interrupt happens immediately. In the IRQ handler (HAL_UART_IRQHandler) a new byte is put in the DR (TDR) register which then gets transmitted - this happens in UART_Transmit_IT.
Once this byte gets transmitted, TXE interrupt gets triggered again and this process repeats until reaching the end of the buffer you've provided.
If any error happens, HAL_UART_ErrorCallback will get called, from IRQ handler
If no errors happened and end of buffer has been reached, HAL_UART_TxCpltCallback is called (from HAL_UART_IRQHandler -> UART_EndTransmit_IT).
On to your second question whether you can edit this callback "for convenience" - I'd say you can do whatever you want, but you'll have to live with the consequences of modifying code what's essentially a library:
Upgrading HAL to newer versions is going to be a nightmare. You'll have to manually re-apply all your changes you've done to that code and test them again. To some extent this can be automated with some form of version control (git / svn) or even patch files, but if the code you've modified gets changed by ST, those patches will likely not apply anymore and you'll have to do it all by hand again. This may require re-discovering how the implementation changed and doing all your work from scratch.
Nobody is going to be able to help you as your library code no longer matches code that everyone else has. If you introduced new bugs by modifying library code, no one will be able to reproduce them. Even if you provided your modifications, I honestly doubt many here will bother to apply your changes and test them in practice.
If I was to express my personal opinion it'd be this: if you think there's bugs in the HAL code - fix them locally and report them to ST. Once they're fixed in future update, fully overwrite your HAL modifications with updated official release. If you think HAL code lacks functionality or flexibility for your needs, you have two options here:
Suggest your changes to ST. You have to keep in mind that HAL aims to serve "general purpose" needs.
Just don't use HAL for this specific peripheral. This "mixed" approach is exactly what I do personally. In some cases functionality provided by HAL for given peripheral is "good enough" to serve my needs (in my case one example is SPI where I fully rely on HAL) while in some other cases - such as UART - I use HAL only for initialization, while handling transmission myself. Even when you decide not to use HAL functions, it can still provide some value - you can for example copy their IRQ handler to your code and call your functions instead. That way you at least skip some parts in development.

akka-persistence (cqrs?) eventsourcing and side effects

I'm trying to figure out how to model the state of a remote "IoT" device with a persistent-actor, for example:
The user wants to turn on a light so we do the most logical.
User sends OnCommand
the persistent actor receives the command, generates a LightTurnedOnEvent and updates its state to on
So that makes sense but the problem here is the light is actually never turned on. Ok so then we build a LightControlActor that knows low level hardware-controll voodoo. This actor listen for LightTurnedOnEvent and when it gets it it does it thing and turnes on the light.
Awsome now we have a light turned on! But not happy. LightTurnedOnEvent is kind of lying here, the light is not turned on yet. Following this logic LightTurnedOnEvent should be generated by the LightControlActor and my persistent actor should generate some SentRequestToTurnOnLight but now this gets complicated for me with all the different semantics.
User sends OnCommand
Persistent actor recivecs OnCommand generate RequestedLightTurnOnEvent and set state to pending.
LightController picks up on the RequestedLightTurnOnEvent and tries to turn on the light on the external system.
So then what? Now how do I update the state of the persistent actor? Have the LightController send some veird command SetStateToOnCommand?
So how do I update the persistent state when the light is actually turned on?
One idea is to go with something like "saga" for your events.
LightController: State idle
lightController ! OnCommand
persist(LightTurnOnAttempted)
lightControl ! LightTurnOnCommand
become(pending)
LightControl:
lightControl ! LightTurnOnCommand
performLightTurnOnAsyncFunction.map(_ => TurnOnLightCommand) pipeTo lightController
LightController: State pending
lightController ! TurnOnLightCommand
persist(LightTurnedOn)
become(initialized)
This gives you fine grained control. In case of crash and during the process of recovery, you can check whether the light was turned on or the LightController was in pending state. If it was in pending state, you can resend the LightTurnOnCommand.
But you never know for sure that the light turned on, even if the HW controller says so, i.e. the bulb could be damaged.
The idea with events is the implications that they have in their bounded context. In your case, LightTurnedOnEvent is owned by the persistent actor and it has a strict meaning only in its context. From the owner actor's POV the light should be ON and a future TurnOnCommand would not change this state, a new event would not be emitted (it's idempotent).
If you want this event to have other implications, you need a Saga (or whatever you want to call it) that would react to this event and will send another command to another actor, in another context, i.e. in the HW context. This HW actor would emit its own events, relevant only in its context, i.e. LightBulbCoupledToPowerSource or something like this; it could even be named LightTurnedOnEvent, like the other, but in a separate namespace, very likely with other properties.
To better see this separation of concerns/contexts, we can imagine a situation in which a Saga, in reaction to LightTurnedOnEvent would send 3 commands to 3 different Light bulbs, in a big room for example.

Why I should use context.become() to store internal state in Actor?

I've read scala-best-practices and have a question about "5.2. SHOULD mutate state in actors only with context.become". I don't understand why it is so bad to store internal state using var. If actor executes all messages sequentially I just can't see any source of problems. What do I miss?
Consider the first example in the article that you referenced:
class MyActor extends Actor {
val isInSet = mutable.Set.empty[String]
def receive = {
case Add(key) =>
isInSet += key
case Contains(key) =>
sender() ! isInSet(key)
}
}
There's nothing inherently incorrect with this example, so there isn't some vital understanding that you're missing. As you know, an actor processes the messages in its mailbox sequentially, so it is safe to represent its state in an internal variable and to mutate this state, as long as the actor doesn't expose that state1.
become is often used to dynamically switch an actor's behavior (e.g., changing the kind of messages that the actor handles) and/or its state. In the second example in the article, the actor's state is encoded in its behavior as a parameter. This is an elegant alternative to the first example, but in this simple case it's a matter of preference.
One scenario in which become can really shine, however, is an actor that has many state transitions. Without the use of become, the actor's logic in its receive block can grow unmanageably large or turn into a jungle of if-else statements. As an example of using become to model state transitions, check out this sample project that models the "Dining Philosophers" problem.
1A potential issue is that while isInSet is a val, it's a mutable Set, so weird things can happen if the actor exposes this state to something outside of the actor itself (which it is not doing in the example). For example, if the actor sends this Set in a message to another actor, then the external actor can change this state, causing unexpected behavior or race conditions. One can mitigate this issue by changing the val to a var, and the mutable Set to an immutable Set.
I don't think there's necessarily anything wrong with using vars in actors, for exactly the reasons you mentioned (Keep in mind though, that this is only for code executed in the context of the receive(...), i.e., if you start a thread, or use a Future, even if it's from within the receive, that code is no longer executed sequentially).
However, I personally prefer to use context.become(...) for controlling state, mainly because it clearly shows me the states in the actor that can change (vars can be scattered all over).
I also prefer to limit it to 0 or 1 call to context.become(...) per message handled, so it's clear where this state transition is happening.
That said, you can get the same benefits by using a convention where you define all your vars in one place, and make sure to re-assign them in one place (say towards the end) in your message handling.

Reactive observable that captures onrendered state changes (in scalajs / js)

I am working with a library (ScalaJS and react specifically) where I have an interesting situation that I assume is pretty routine for an experienced reactive-programmer. I have a Component with State and a callback shouldComponentUpdate(State). The basic idea here is that certainly if the callback is triggered but the State has not changed from the last render, returnfalse. Otherwise, perhaps return true if the State change matters.
I am using a library monix but it seems identical to other reactive libraries so I would imagine this is a fairly context-independent question.
I would like to do something like: have some state that reflects the deltas of State since the last render. On each render, clear the buffer. Or, have a renderedState subject that reflects all rendered states as a sequence, a receivedState subject that reflects all received State updates, and a needsUpdate subject that reflects whether the latest receivedState matches the latest renderedState. I am having trouble actually executing these ideas, though. Here is where I am stuck at:
Here is what I've done for other callbacks:
lazy val channel_componentWillUpdate = channel_create[ComponentWillUpdate[Props, State, ResponsiveLayoutContainerBackend, TopNode]]
def componentWillUpdate(cwupd: ComponentWillUpdate[Props, State, ResponsiveLayoutContainerBackend, TopNode]) =
Callback {
channel_componentWillUpdate.onNext(cwupd)
}
So when then componentWillUpdate callback is triggered, the handler fires onNext on the channel (subject).
The shouldComponentUpdate is different though. It returns a value, so it needs to be structured differently. I am having trouble thinking of the right adjustment.
To summarize a bit:
react has callbacks at different stages of the view lifecycle, like componentDidMount, componentDidUpdate, etc.
I am handling all but one stage the same way - the shape of the callback is State -> Callback<Void> so alls I have to do is use a Subject for each type of lifecycle event and submit its onNext when the callback is triggered.
But one type of event has shape either State -> Boolean or State -> Callback<Boolean>.
I feel like I should be able to model this with a subject representing the delta between the last state rendered/received.
However, I don't know how this fits into the reactive style.

What do the various ISubject implementations do and when would they be used?

I have a fairly good idea of what the Subject class does and when to use it, but I've just been looking through the language reference on msdn and see there are various other ISubject implementations such as:
AsyncSubject
BehaviorSubject
ReplaySubject
As the documentation is pretty thin on the ground, whats the point of each of these types and under what situations would you use them?
These subjects all share a common property - they take some (or all) of what gets posted to them via OnNext and record it and play it back to you - i.e. they take a Hot Observable and make it Cold. This means, that if you Subscribe to any of these more than once (i.e. Subscribe => Unsubscribe => Subscribe again), you'll see at least one of the same value again.
ReplaySubject: Every time you subscribe to the Subject, you get the entire history of what has been posted replayed back to you, as fast as possible (or a subset, like the last n items)
AsyncSubject: Always plays back the last item posted and completes, but only after the source has completed. This Subject is awesome for async functions, since you can write them without worrying about race conditions: even if someone Subscribes after the async method completes, they get the result.
BehaviorSubject: Kind of like ReplaySubject but with a buffer of one, so you always get the last thing that was posted. You also can provide an initial value. Always provides one item instantly on Subscribe.
In light of the latest version (v1.0.2856.0) and to keep this question up to date, there has been a new set of subject classes:
FastSubject, FastBehaviorSubject, FastAsyncSubject and FastReplaySubject
As per the release notes they
are much faster than regular subjects
but:
don’t decouple producer and consumer by an IScheduler
(effectively limiting them to
ImmediateScheduler);
don’t protect against stack overflow;
don’t synchronize input messages.
Fast subjects are used by Publish and
Prune operators if no scheduler is
specified.
In regards to AsyncSubject
This code:
var s = new AsyncSubject<int>();
s.OnNext(1);
s.Subscribe(Console.WriteLine);
s.OnNext(2);
s.OnNext(3);
s.OnCompleted();
prints a single value 3. And it prints same if subscription is moved to after completion. So it plays back not the first, but the last item, plays it after completion (until complete, it does not produce values), and it does not work like Subject before completion.
See this Prune discussion for more info (AsyncSubject is basically the same as Prune)
Paul's answer pretty much nails it. There's a few things worth adding, though:
AsyncSubject works as Paul says, but only after the source completes. Before that, it works like Subject (where "live" values are received by subscribers)
AsyncSubject has changed since I last ran tests against it. It no longer acts as a live subject before completion, but waits for completion before it emits a value. And, as Sergey mentions, it returns the last value, not the first (though I should have caught that as that's always been the case)
AsyncSubject is used by Prune, FromAsyncPattern, ToAsync and probably a few others
BehaviorSubject is used by overloads of Publish that accept an initial value
ReplaySubject is used by Replay
NOTE: All operator references above refer to the publishing set of operators as they were before they were replaced with generalised publish operators in rev 2838 (Christmas '10) as it has been mentioned that the original operators will be re-added