GWT event handling: Fire events for selective instances of listener classes - gwt

Background:
We have an application using GWT and the GWTP framework providing the MVP architecture. We use GWT's EventBus to broadcast events across presenters.
Requirement:
We have an event called RefreshEvent. The class/presenter firing the event is Parent(P) and the presenter listening to this event is Child(C). We are running into a situation in the application where multiple instances of the C (the listener) are active at the same time in the application. Let's say instance A and instance B of presenter C are active and both are listening for the RefreshEvent. But in a given context in the application I want to selectively fire the event. That is a RefreshEvent fired by P should be received only by instance A of Child C and not by instance B of Child C.
Does GWT provide any mechanism to do this? If not, how can I achieve this.
Our application heavily uses events for inter presenter communication.

Typically, EventBus is used to "broadcast" an event to each party that listens to it (in your example, all instances of your Child C).
If you want a single relationship, your parent can simply call the necessary child:
private Child a;
private Child b;
...
public void on onRefresh() {
/*
* If you need to call child a, call a.doSomething();
* If you need to call child b, call b.doSomething();
*/
}

Related

DispatcherTimer in MVVM with Prism?

I'm working on a multi-platform MVVM app, and I want to keep the ViewModel platform-agnostic.
I need to make use of DispatcherTimer or any other timer. Since the DispatcherTimer is not part of .NET Standard/Core, I was wondering if there are better alternatives to use so I can keep the VM clean of plat-specific code (I want it to depend only on .NET Core)?
The way it works is that the ViewModel implements an interface that exposes an event that the View is listening to, and responds to it accordingly.
The timer raises this event upon each tick.
The first option would be to just use classic Timer, which does fire on a non-UI thread and then just use Dispatcher manually in the consuming view. This is however not that convenient.
Other option would be to provide an interface, that consumers of your library could implement, which would have a method like RunOnUiThread(Action action) and which you would just use to make sure the view-specific code runs on the UI thread.
The best solution would probably be to get inspiration in Prism itself. For example the EventAggregator in the library can publish events on the UI thread - it first captures the current thread's synchronization context (see here on GitHub):
var syncContext = SynchronizationContext.Current;
This must be done for example during the View model construction, on the UI thread. And then you can invoke an action on this UI synchronization context even from another thread (see here on GitHub):
syncContext.Post((o) => action(), null);
This way you could just use one of the .NET Standard Timer classes and from their callback then use the SynchronizationContext to run an action on UI thread.
The other way you should know about DispatcherTimer is sometimes we may use DispatcherTimer to do something alternately.
We can use Task.Delay to replace DispatcherTimer sometimes.
Such as we need to run the code A every 5 seconds.
public async void Foo()
{
while (true)
{
// run a every 5 seconds
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(5));
A();
}
}
private void A()
{
}
And the A will run in the main thread if the main thread calls the Foo and I think you
can consider using this method in the framework.

rxjava 2.0 what is the difference between Observable.subscribe and Observable.subscribeActual?

The documentation just says
protected abstract void subscribeActual(Observer<? super T> observer)
Operator implementations (both source and intermediate) should implement this method that performs the necessary business logic.
There is no need to call any of the plugin hooks on the current Observable instance or the Subscriber.
Observable.subscribe comes from the base interface definition in ObservableSource and is the main subscription method for Observables: internal and external components use it to run a flow in a standard way.
However, certain actions may be necessary for all kinds of Observables to be executed before the operator's business logic gains access to the incoming Observer, for example, applying plugin hooks and protecting against crashing subscribe implementations. So instead of requiring every operator to duplicate this preparation logic, they are in a single place and a new abstract method is present to deal with the customization of an Observable.

Pub/sub pattern in Azure Service Fabric

I'm working on an Azure Service Fabric application here where I have certain actors that need to receive pings/hooks from other services on demand. The application is a sort of event distribution engine that is intended to work something like this:
An event router actor that can take an event in and then take care of distributing that event to all subscribers of that event type.
0..N event subscription actors that somehow need to inform the router what type of events they wish to subscribe to and how they want them delivered (sync or async).
When the event router actor receives an event of the type MyEvent, it will identify what subscribers are listening and how they want the event delivered. For asynchronous delivery, a message will be popped in an Azure Service Bus topic. For synchronous delivery though, the router actor will invoke the subscription method on the subscribing actors directly, awaiting their response.
Most of this is fairly straight forward, but I'm not entirely sure how I'm going to pull off synchronous delivery of these events. I don't want the event router actor to in any way be aware of any internals in the actors subscribing to events - yet with the current ActorProxy implementations and similar, having access to the interfaces are required to invoke methods on other actors.
Say I subscribe to an event type, informing the event router that my address is fabric:/MyApp/MyEventSubscriberActor and that I want to subscribe to MyEvent. Is there any sensible way within the Service Fabric APIs I can programatically invoke a method on that actor without (for instance OnEventAsync(MyEvent ev) using the ActorProxy.Create<IMyEventSubscriberActor>() method? The source code of these APIs doesn't seem to be publicly available, so I have no direct way of checking how this is done under the hood.
The event subscription actor can implement an event subscription interface that contains an "event-available" method. It can pass that interface to an "subscribe-to-event" method on the event router actor interface.
The event router actor interface can keep a reference to the subscription interface as part of its state. When the event of interest to the subscriber occurs, it can call the "event-available" method on the interface that it received and saved earlier. All of this can be done without explicitly creating an actor proxy to communicate with the event subscription actor (the actors serialization infrastructure does this under the hood).
Here's a very basic example that omits the event type, assumes just one subscriber etc., but should give you an idea of the technique.
Interfaces:
interface IEventRouter : IActor
{
void Subscribe(IEventSubscriber subscriber);
}
interface IEventSubscriber : IActor
{
void EventAvailable();
}
Event subscriber code:
class EventSubscriber : Actor, IEventSubscriber
{
void SubscribeToEvent()
{
IEventRouter router = ActorProxy.Create<IEventRouter>("fabric:/MyApp/MyEventRouterActor");
router.Subscribe(this);
}
public void EventAvailable()
{
// Process the event
}
}
Event router code:
// Define actor state
[DataContract]
class RouterState
{
[DataMember]
public IEventSubscriber Subscriber;
}
// Define actor
class EventRouter : Actor<RouterState>, IEventRouter
{
public void Subscribe(IEventSubscriber subscriber)
{
this.State.Subscriber = subscriber;
}
void OnEventAvailable()
{
this.State.Subscriber.EventAvailable();
}
}

How to write tests for tracking event flows in eventbus?

Long description:
In our gwt with mvp4g app we have pretty complicated flow of events in eventbus. One event like LOGIN produces multiple others as a reaction from presenters/handlers. Currently we have great difficulties with understanding how events interrelated i.e. which events must follow this particular one.
We have tests for presenters and views, but we are lacking tests which would clearly show/model event flows, preferably without usage of real views and services.
Short description:
New tests on eventBus(?) should be developed which should clearly describe and test event flows.
I have few rud ideas but they all sounds not satisfactory:
Write custom implementation(could be ugly) of mvp4g eventbus and:
use real presenters
use mock(?) views
mock services
verify all produced service calls
Why not cool: (a) In this case test would not verify produced events directly but only that ones which have services. (b)
EventBus implementation would look rather scarry - it must create each presenter with mocked services and views
Find a way to use some magical mvp4g mechanism to create eventBus in test and mock vies, services.
Why not cool : same as prev - only indirect verification through services is possible, and I cannot find how to create eventBus manually and solve all problems with GIN, inter GWT module dependencies and so. I guess there is no simple way to do it.
Is there any general solution for problem of tracking event tree in tests? Guess I'm not the first person to stare at complicated eventbus event flows.
Do you want to test the eventBus? Or do you want to track all event which are fired?
If you want to track your events, maybe some kind of EventMonitor could help you? A class that implements all necessary EventHandler and log every event that occurs.
Something like that? Just instance that class before your tests starts.
import java.util.logging.Logger;
import com.google.gwt.event.shared.GwtEvent;
import com.google.web.bindery.event.shared.EventBus;
public class EventMonitor implements AEventHandler, BEventHandler /* , ... */{
private static int event_count = 1;
private final Logger logger = Logger.getLogger(this.getClass().getName());
public EventMonitor(EventBus eventBus) {
eventBus.addHandler(AEvent.getType(), this);
eventBus.addHandler(BEvent.getType(), this);
// [...]
}
private void logEvent(GwtEvent<?> event) {
logger.info(event_count + " useful information");
event_count++;
}
#Override
public void onAEvent(AEvent event) {
logEvent(event);
}
#Override
public void onBEvent(BEvent event) {
logEvent(event);
}
}

Gin injecting in a shared (client server) object - "IsTreeItem"

I have an object that implements "IsTreeItem". The Object is displayed as a two level tree item. Each tree item is built with a check box.
I need to know when a check box is changing value - so i am listening to ValueChangedEvents.
The first problem is that the Tree built with such items only fires SelectionEvents. If selection is changing the check box the ValueChanged event is fired afterwards - so there is no way to listen to events inside "IsTreeItem" from Tree.
So i let my "IsTreeItem" fire its own element. So i (field)injected an EventBus and used it to fire the event if "ValueChanged".
The Problem is that my "IsTreeItem" is an Object sent from server (it is in shared package and serializable). The object is instantiated on server (EventBus is not ionjected) and "asTreeItem" is called on client.
Is there a way to inject the EventBus in the Method TreeItem asTreeItem() in some way? Or are there any other means to let some one outside know if a check box has changed its value.
GIN can do member injection on already created instances.
You have to create a method in your Ginjector interface that takes such an instance as argument, with a return type of void.
Note that because no reflection is done on the client, GIN will only inject fields and methods from the class used as the argument type (and its super-classes).
#GinModules(MyGinModule.class)
interface MyGinjector extends Ginjector {
…
void injectIsTreeItemMembers(IsTreeItem item);
}