Using a Flow inside a ViewModel and observing its state in a Compose function.
The ViewModel keeps listening to flow events even when compose screens are changed. (For Activities and Fragments we have lifecycle events to handle this).
One interesting point while using NavControllerHost for navigating to another compose screen, the state changed is not invoked inside the Composable function but in the ViewModel, the state is getting changed, whereas, when navigation is done without NavControllerHost, the state change callback is received in compose too.
Any suggestion to handle this gracefully?
Related
I'm working on a standalone countdown App for Apple Watch. When the timer is over, the watch rings or vibrate.
There are three different situations where this can happen:
The app screen is active on the user's wrist: that's the easiest part; when the timer is over, the app runs a sound/haptic feedback, no need for anything running in the background. No problem with that.
The app is in the background: Using notifications seems to be the obvious choice, and it already works very well.
The app is in the foreground, but the screen turns off either because it reached the maximum wake duration (15 or 70 seconds) or because the user rotated his wrist back in rest position, which automatically turns the apple watch's screen off.
This third and last situation is where I'm confused. Neither the first nor the second situation works here: when the app is active, but the screen turns off, the app stops running, but the notifications are still not triggered since the app is technically not in the background.
Are there any straightforward ways around this problem?
Use Extended Runtime Sessions to create smart alarms
like this:
func notifyUser(hapticType type: WKHapticType,
repeatHandler: ((UnsafeMutablePointer<WKHapticType>) -> Time
Interval)? = nil)
Apple Documentation
For schedulable sessions such as smart alarms, call this method during the session to alert the user. When you call the method, the system plays repeating haptic feedback. If the app isn’t active, the system also displays a system alarm alert on the watch.
The haptic feedback repeats at the interval specified by the repeatHandler, and continues to repeat until the application or system alert invalidates the session.
If the app isn’t active, the user can tap the Stop button to invalidate the session or tap the Open button to activate the app.
If the app is active, the app must invalidate the session by calling its invalidate method.
Only call this method on a schedulable session that’s running: you must schedule the session using the startAtDate: method, and the session’s state must equal WKExtendedRuntimeSessionStateRunning. During a smart alarm session, your app must call this method before the session expires.
Also you should check out the life cycle of watchOS app
So I have a background in working with event sourcing and microservices. And usually the best way to enforce bounded context yet be able to make your aggregate communicate is to have either some kind of Choreography or some kind of Orchestration.
In a Choreography Aggregate A will raise eventA that Aggregate B will listen to and handle and then after doing whatever needed to be done, it will raise eventB and A will listen and handle it and proceed. It's effective, respects event-sourcing and DDD rules.
In an Orchestration, Aggregate A will raise eventA that the orchestrator O will listen and handle and then issue a command B to Aggregate B which in return will run what's needed and raise Event B, orchestrator O will handle that event and issue a command A and so on... It adds a level of complexity but it's great for an added level of segregation, also this way Aggregate A and B are not listening/handling each other events.
Obvs these 2 methods have their own pros and cons, but both work perfectly in a microservice context.
The issue I'm facing is that for me there is no context. I'm working with AWS lambdas, whenever an event is pushed to the store I will have a lambda listening to db(event store) changes and then do something. It was working perfectly until I needed to add a second aggregate.
And now to achieve a choreography or an orchestration, I either need a context(which is not a thing for lambdas) and an event bus, or I need to add a lambda for every event, that would lead for total chaos.
Like if Aggregate A needs something from Agg B before continuing its flow it will push an event to the event store and I will have to handle the event with a new lambda so for every type of interaction between Agg A and Agg B, I will need 2 lambdas.
Maybe I'm missing something, after all I'm new in AWS lambdas and more used to working with microservices.
Perhaps what you're after is a Process Manager:
(…) a process manager is a class that coordinates the behavior of the aggregates in the domain. A process manager subscribes to the events that the aggregates raise, and then follow a simple set of rules to determine which command or commands to send. The process manager does not contain any business logic; it simply contains logic to determine the next command to send. The process manager is implemented as a state machine, so when it responds to an event, it can change its internal state in addition to sending a new command.
The above definition can be found in Microsoft's Exploring CQRS and Event Sourcing. This is a way of having orchestration in an event-driven system. The original definition, AFAIK, can be found in Gregor Hohpe's Enterprise Integration Patterns.
In AWS land, you'd have your lambda(s) reacting to those events and firing off commands (either via a command bus, if you have such concept in your system, or by directly invoking other lambdas).
I want to send a reply after I have persisted and updated the state of the actor using persistAll. Unfortunately I have not found a callback or onSucces handler to send back a reply after the last event has been persisted.
This is a shortcoming of the API, there is no built in way to react on all persistAll completing, you will have to keep a counter or a set of completed persists yourself and only trigger your logic when the last persist completes.
As far as I remember this cannot be easily fixed because it would break binary and source compatibility.
In the "next generation" persistent actors (in Akka typed) this works more as you would expect and the side effect you want to execute on successful persist of the events will only execute once, when all the events are complete.
I understand how to bind an action in a Backbone View to an event trigger but, how can you fire an action watching the condition that two precise envets have been triggered?
For that you can use jquery functionality like:
$.when(func1, func2).then(func3);
It acts like deffered and promise here.
I am working with the MVC architecture. I have my GUI all set up, and I have my controller using the model for data access. My question is: how do I set up bidirectional data flow between the controller and the GUI(view). I am using Qt, so When I hit a button, it will fire off an action. In order to make that Action fire off to the controller, I need an instance of it. Then from the controller side, I need an instance of the view so I can tell it how to behave. So, how can achieve this communication? Am I even on the right track? please let me know what you guys think.
Thanks
The view doesn't need to be explicitly aware of the controller. The controller can connect to any of the view's signals and the signals can relay relevant data or they can be empty. When the controller handles them in a slot, it can call methods on the view to fetch data if it isn't already included in the signal. The controller can also call any view method at any time.
I usually connect widget(button) signals directly to slots in the view class and expose custom aggregate signals that a controller can connect to instead of exposing all the widgets themselves.