Employing GWT's RequestFactory within Activities - gwt

My CustomerActivity class happens also to be a presenter in the MVP sense. In response to actions by the user, the following code is called:
context.update(customer).fire(new Receiver<CustomerProxy>() {
public void onSuccess(CustomerProxy response) {
// set the view according to the response
}
});
When the above code executes, two things happen:
I receive an updated copy of the Customer, with which I can refresh the state of the view
An EntityProxyChange event is fired
The CustomerActivity listens for EntityProxyChange events because other Activities also make changes to customer records, and I want to keep the CustomerActivity up-to-date.
EntityProxyChange.registerForProxyType(eventBus, CustomerProxy.class,
new EntityProxyChange.Handler<CustomerProxy>() {
public void onProxyChange(EntityProxyChange<CustomerProxy> event) {
fetchCustomer(event.getProxyId());
// ...but what if it was me that made the change?
}
});
Since theupdate method already returns an up-to-date Customer, I don't need to fetch the customer again during processing of the EntityProxyChange; and I don't want to incur the cost of another call to the server if I can avoid it.
I was hoping that the EntityProxyChange class would provide me with the entity's version number, which I could compare with the version of the customer I have cached. No dice.
I suppose I can set some kind of inTheMiddleOfAnUpdateOperation flag, and check it before fetching the customer. Is that what people are doing? The idea makes me gag just a little bit. Can you suggest a better way to write an activity that listens for changes and makes changes to the same entity types?

I'm not sure this would work, but you could try to create another event bus :
final EventBus customerActivityEventBus = new SimpleEventBus();
Initialize a new RequestFactory with this eventBus and use it in the CustomerActivity.
customerActivityRequestFactory = GWT.create(CustomerRequestFactory.class);
customerActivityRequestFactory.initialize(customeActivityEventBus);
CustomerRequest context = customerActivityRequestFactory.customerRequest();
Your CustomerActivity will still listen to change events from the main eventBus but will not see the events it fired.
In your other activities, listen to events either only from the customerActivityEventBus or from both, depending on what you want.
Of course, keep only one main eventBus to use for events that are not from a Request Factory (ie. ActivityManager, PlaceHistoryHandler, etc ..)

Related

What is the EventBus in SAPUI5 for?

Can anybody explain for what and when we are going to use EventBus methods? Also what kind the activities of the same.
EventBus in UI5 is a tool with which we can leverage publish-subscribe pattern in our app.
How do we get EventBus?
Currently, there are two APIs which return their own instance of EventBus:
Globally: sap.ui.getCore().getEventBus(); for
Standalone apps.
Component apps and their container app where developers have control over both.
Component-based: this.getOwnerComponent().getEventBus(); // this == controller. Especially for apps targeting Fiori Launchpad (FLP) where SAP explicitly warns not to get the EventBus from the core but from the component:
If you need an event bus, use the event bus of the component. By this, you avoid conflicting event names and make sure that your listeners are automatically removed when the component is unloaded. Do not use the global event bus.
Note
FLP destroys the component every time when the user navigates back Home.
Make sure to have the module sap/ui/core/EventBus required before calling getEventBus() to properly declare the dependency and to avoid possible sync XHR when requiring it.
sap.ui.define([ // or sap.ui.require
// ...,
"sap/ui/core/EventBus",
], function(/*...,*/ EventBus) { /*...*/ });
What is it for?
With EventBus, we can fire (via publish()), and listen (via subscribe()) to our own custom events freely:
Without having to use or extend any Control / ManagedObject / EventProvider classes,
Without knowing the existence of other involved listeners (if any),
Without accessing the object that fires the event (publisher). E.g.: No need to call thatManagedObj.attach*().
Publishers and subscribers stay ignorant to each other which makes loose coupling possible.
Analogous to the real world, EventBus is like a radio station. Once it starts to broadcast about all sorts of things on various channels, those, who are interested, can listen to a particular channel, get notified about a certain event, and do something productive with the given data. Here is an image that illustrates the basic behavior of an EventBus:
Sample code
Subscribe
{ // Controller A
onInit: function() {
const bus = this.getOwnerComponent().getEventBus();
bus.subscribe("channelABC", "awesomeEvent", this.shouldDoSomething, this);
},
shouldDoSomething: function(channelId, eventId, parametersMap) {
// Get notified when e.g. "doSomething" from Controller B is called.
},
}
Publish
{ // Controller B
doSomething: function(myData) {
const bus = this.getOwnerComponent().getEventBus();
bus.publish("channelABC", "awesomeEvent", { myData }); // broadcast the event
},
}
See API reference: sap/ui/core/EventBus

When using MDA, should you differentiate between idempotent and non-idempotent event handlers?

The question assumes the use of Event Sourcing.
When rebuilding current state by replaying events, event handlers should be idempotent. For example, when a user successfully updates their username, a UsernameUpdated event might be emitted, the event containing a newUsername string property. When rebuilding current state, the appropriate event handler receives the UsernameUpdated event and sets the username property on the User object to the newUsername property of the UsernameUpdated event object. In other words, the handling of the same message multiple times always yields the same result.
However, how does such an event handler work when integrating with external services? For example, if the user wants to reset their password, the User object might emit a PasswordResetRequested event, which is handled by a portion of code that issues a 3rd party with a command to send an SMS. Now when the application is rebuilt, we do NOT want to re-send this SMS. How is this situation best avoided?
There are two messages involved in the interaction: commands and events.
I do not regard the system messages in a messaging infrastructure the same as domain events. Command message handling should be idempotent. Event handlers typically would not need to be.
In your scenario I could tell the aggregate root 100 times to update the user name:
public UserNameChanged ChangeUserName(string username, IServiceBus serviceBus)
{
if (_username.Equals(username))
{
return null;
}
serviceBus.Send(new SendEMailCommand(*data*));
return On(new UserNameChanged{ Username = userName});
}
public UserNameChanged On(UserNameChanged #event)
{
_username = #event.UserName;
return #event;
}
The above code would result in a single event so reconstituting it would not produce any duplicate processing. Even if we had 100 UserNameChanged events the result would still be the same as the On method does not perform any processing. I guess the point to remember is that the command side does all the real work and the event side is used only to change the state of the object.
The above isn't necessarily how I would implement the messaging but it does demonstrate the concept.
I think you are mixing two separate concepts here. The first is reconstructing an object where the handlers are all internal methods of the entity itself. Sample code from Axon framework
public class MyAggregateRoot extends AbstractAnnotatedAggregateRoot {
#AggregateIdentifier
private String aggregateIdentifier;
private String someProperty;
public MyAggregateRoot(String id) {
apply(new MyAggregateCreatedEvent(id));
}
// constructor needed for reconstruction
protected MyAggregateRoot() {
}
#EventSourcingHandler
private void handleMyAggregateCreatedEvent(MyAggregateCreatedEvent event) {
// make sure identifier is always initialized properly
this.aggregateIdentifier = event.getMyAggregateIdentifier();
// do something with someProperty
}
}
Surely you wouldn't put code that talks to an external API inside an aggregate's method.
The second is replaying events on a bounded context which could cause the problem you are talking about and depending on your case you may need to divide your event handlers into clusters.
See Axon frameworks documentation for this point to get a better understanding of the problem and the solution they went with.
Replaying Events on a Cluster
TLDR; store the SMS identifier within the event itself.
A core principle of event sourcing is "idempotency". Events are idempotent, meaning that processing them multiple times will have the same result as if they were processed once. Commands are "non-idempotent", meaning that the re-execution of a command may have a different result for each execution.
The fact that aggregates are identified by UUID (with a very low percentage of duplication) means that the client can generate the UUIDs of newly created aggregates. Process managers (a.k.a., "Sagas") coordinate actions across multiple aggregates by listening to events in order to issue commands, so in this sense, the process manager is also a "client". Cecause the process manager issues commands, it cannot be considered "idempotent".
One solution I came up with is to include the UUID of the soon-to-be-created SMS in the PasswordResetRequested event. This allows the process manager to only create the SMS if it does not yet already exist, hence achieving idempotency.
Sample code below (C++ pseudo-code):
// The event indicating a password reset was successfully requested.
class PasswordResetRequested : public Event {
public:
PasswordResetRequested(const Uuid& userUuid, const Uuid& smsUuid, const std::string& passwordResetCode);
const Uuid userUuid;
const Uuid smsUuid;
const std::string passwordResetCode;
};
// The user aggregate root.
class User {
public:
PasswordResetRequested requestPasswordReset() {
// Realistically, the password reset functionality would have it's own class
// with functionality like checking request timestamps, generationg of the random
// code, etc.
Uuid smsUuid = Uuid::random();
passwordResetCode_ = generateRandomString();
return PasswordResetRequested(userUuid_, smsUuid, passwordResetCode_);
}
private:
Uuid userUuid_;
string passwordResetCode_;
};
// The process manager (aka, "saga") for handling password resets.
class PasswordResetProcessManager {
public:
void on(const PasswordResetRequested& event) {
if (!smsRepository_.hasSms(event.smsUuid)) {
smsRepository_.queueSms(event.smsUuid, "Your password reset code is: " + event.passwordResetCode);
}
}
};
There are a few things to note about the above solution:
Firstly, while there is a (very) low possibility that the SMS UUIDs can conflict, it can actually happen, which could cause several issues.
Communication with the external service is prevented. For example, if user "bob" requests a password reset that generates an SMS UUID of "1234", then (perhaps 2 years later) user "frank" requests a password reset that generates the same SMS UUID of "1234", the process manager will not queue the SMS because it thinks it already exists, so frank will never see it.
Incorrect reporting in the read model. Because there is a duplicate UUID, the read side may display the SMS sent to "bob" when "frank" is viewing the list of SMSes the system sent him. If the duplicate UUIDs were generated in quick succession, it is possible that "frank" would be able to reset "bob"s password.
Secondly, moving the SMS UUID generation into the event means you must make the User aggregate aware of the PasswordResetProcessManager's functionality (but not the PasswordResetManager itself), which increases coupling. However, the coupling here is loose, in that the User is unaware of how to queue an SMS, only that an SMS should be queued. If the User class were to send the SMS itself, you could run into the situation in which the SmsQueued event is stored while the PasswordResetRequested event is not, meaning that the user will receive an SMS but the generated password reset code was not saved on the user, and so entering the code will not reset the password.
Thirdly, if a PasswordResetRequested event is generated but the system crashes before the PasswordResetProcessManager can create the SMS, then the SMS will eventually be sent, but only when the PasswordResetRequested event is re-played (which might be a long time in the future). E.g., the "eventual" part of eventual consistency could be a long time away.
The above approach works (and I can see that it should also work in more complicated scenarious, like the OrderProcessManager described here: https://msdn.microsoft.com/en-us/library/jj591569.aspx). However, I am very keen to hear what other people think about this approach.

How to get added record (not just the id) through publishAdd()-notification?

Each Sails.js model has the method publishAdd(). This notifies every listener, when a new record was added to a associated model.
This notification does not contain the newly created record. So I have to start another request from the client side to get the new record.
Is there a possibility, that Sails.js sends the new record with the notification, so I can reduce my request count?
Solution
I realized the accepted answer like that:
https://gist.github.com/openscript/7016c5fd8c5053b5e3a3
There's no way to get this record using the default publishAdd method. However, you can override that method and do the child record lookup in your implementation.
You can override publishAdd on a per-model basis by adding a publishAdd method to that model class, or override it for all models by adding the method to the config/models.js file.
I would start by copying the default publishAdd() method and then tweaking as necessary.
I know this is old, but I just had to solve this again, and didn't like the idea of dropping in duplicate code so if someone is looking for alternative, the trick is to update the model of the newly created record with an afterCreate: method.
Say you have a Game that you want to your Players to subscribe to. Games have notifications, a collection of text alerts that you only want players in the game to receive. To do this, subscribe to Game on the client by requesting it. Here I'm getting a particular game by calling game/gameId, then building my page based on what notifications and players are already on the model:
io.socket.get('/game/'+gameId, function(resData, jwres) {
let players = resData.players;
let notifications = resData.notifications;
$.each(players, function (k,v) {
if(v.id!=playerId){
addPartyMember(v);
}
});
$.each(notifications, function (k,v) {
addNotification(v.text);
});
});
Subscribed to game will only give the id's, as we know, but when I add a notification, I have both the Game Id and the notification record, so I can add the following to the Notification model:
afterCreate: function (newlyCreatedRecord, cb) {
Game.publishAdd(newlyCreatedRecord.game,'notifications',newlyCreatedRecord);
cb();}
Since my original socket.get subscribes to a particular game, I can publish only to those subscriber by using Game.publishAdd(). Now back on the client side, listen for the data coming back:
io.socket.on('game', function (event) {
if (event.attribute == 'notifications') {
addNotification(event.added.text);
}
});
The incoming records will look something like this:
{"id":"59fdd1439aee4e031e61f91f",
"verb":"addedTo",
"attribute" :"notifications",
"addedId":"59fef31ba264a60e2a88e5c1",
"added":{"game":"59fdd1439aee4e031e61f91f",
"text":"some messages",
"createdAt":"2017-11-05T11:16:43.488Z",
"updatedAt":"2017-11-05T11:16:43.488Z",
"id":"59fef31ba264a60e2a88e5c1"}}

Two big question marks about CQRS

I'm a C# developer but I read nearly every tutorial about cqrs out there, doesn't matter if the language was Java, because I want to learn the structure and base of cqrs.
But now I think, the fact that I read so much tutorials is the problem because there are differences in the tutorials and now I'm confused and don't know which technique I have to use.
Two main questions are running wild in my head and maybe some of you can bring some clarity in there.
On the command side, where should I place the logic to call my ORM for example?
Some tutorials do that in the command handler (what is more logic to me) and some do it in the event handlers which will be fired by the command handler which in that case do only validation logic.
For the event store and to undo thinks, which data do I have to save into the db, some tutorials save the aggregate and some save the event model.
I hope that someone can explain me what pattern to use and why, maybe both in different scenarios, I don't know.
An practical example would be great. (Only pseudo code)
Maybe a User registration, RegisterTheUser command:
Things to do:
Check if the username is already in use
Add user to db
Send confirmation mail (In command or in the UserIsRegistered event?)
Fire event ConfirmationMailSended or only UserIsRegistered event?
Kind regards
EDIT:
Here is my current implementation (Simple)
public class RegisterTheUser : ICommand
{
public String Login { get; set; }
public String Password { get; set; }
}
public class RegisterTheUserHandler : IHandleCommand<RegisterTheUser, AccountAggregate>
{
public void Handle(AccountAggregate agg, RegisterTheUser command)
{
if (agg.IsLoginAlreadyInUse(command.Login))
throw new LoginIsAlreadyInUse();
agg.AddUserAccount(command);
CommandBus.Execute<SendMail>(x => { });
EventBus.Raise<UserIsRegistred>(x => { x.Id = agg.UserAccount.Id; });
}
}
public class UserIsRegistred : IEvent
{
public Guid Id { get; set; }
}
public class AccountAggregate : AggregateBase
{
public AccountAggregate(IUnitOfWork uow)
{
UnitOfWork = uow;
}
private IUnitOfWork UnitOfWork { get; set; }
public UserAccount UserAccount { get; set; }
public void AddUserAccount(RegisterTheUser command)
{
UserAccount = new UserAccount
{
Id = Guid.NewGuid(),
IsAdmin = false,
Login = command.Login,
Password = Crypto.Sha512Encrypt(command.Password)
};
UnitOfWork.UserAccountRepository.Add(UserAccount);
UnitOfWork.Commit();
}
public Boolean IsLoginAlreadyInUse(String login)
{
var result = UnitOfWork.UserAccountRepository.SingleOrDefault(x => x.Login == login);
return (result != null);
}
}
So a number of questions, but I'll take a stab at answering.
On the command side, where should I place the logic to call my ORM for
example?
Having this logic either in the command handler or in your event handler, to me, really depends on the type of system you're building. If you have a fairly simple system, you can probably have your persistence logic in your event handlers, which receive events raised by your domain. The thinking here is that your commands handled by the command handler will already have the information needed and your command handler ends up being not much more than a router. If you need more complexity in your command handler, such as dealing with sagas, long running transactions, or some additional layer of validation, then your command handler will use your persistence layer here to pull out data (and perhaps write data) and then route the command to the proper domain or issue more commands or raise events. So I believe it really depends on the level of complexity you're dealing with.
I tend to favor simplicity over complexity when starting out, and would probably look at having that logic in the event handler to begin with. Move to the command handler if your system is more complex.
For the event store and to undo thinks, which data do I have to save
into the db, some tutorials save the aggregate and some save the event
model
I'm not exactly sure what you're asking here, but if you're asking what should be stored in your event store, then I think a simple solution is the aggregate id, the aggregate type, the event with data (serialized) and the event type. Off the top of my head, that's probably the bare bones of what you'd need: based on the aggregate id you're working with, get all the events for that aggregate (in order raised) and then replay them to rebuild the aggregate. I don't think you need to save the aggregate unless there's some compelling reason to (which is always possible).
As for your request for a practical example and the steps you laid out, that's probably a question in and of itself, but my thoughts on that are:
Check if the user name is already in use
Depending on your application, you may want to do this from the read side in your controller (or whichever layer is raising commands) before you issue a command. Validate at that point, but you'd probably want to validate again before persisting it. You could do that in your event handler where it would probably catch an exception because you're violating a unique index in your database.
Add user to DB
Again, my thought is keep it simple and handle it in your event handler, since your domain is raising a UserIsRegistered event.
Send confirmation email
Your domain could raise the UserIsRegistered event and a second event handler (EmailHandler) would also subscribe to that event and send out the email.
ConfirmationMailSent event could be raised by the event handler, added to the event queue and handled accordingly. I guess I'm not sure what you want to happen here.
But, hopefully this helps a bit.

ASP.NET MVC2 AsyncController: Does performing multiple async operations in series cause a possible race condition?

The preamble
We're implementing a MVC2 site that needs to consume an external API via https (We cannot use WCF or even old-style SOAP WebServices, I'm afraid). We're using AsyncController wherever we need to communicate with the API, and everything is running fine so far.
Some scenarios have come up where we need to make multiple API calls in series, using results from one step to perform the next.
The general pattern (simplified for demonstration purposes) so far is as follows:
public class WhateverController : AsyncController
{
public void DoStuffAsync(DoStuffModel data)
{
AsyncManager.OutstandingOperations.Increment();
var apiUri = API.getCorrectServiceUri();
var req = new WebClient();
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["result"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
req.DownloadStringAsync(apiUri);
}
public ActionResult DoStuffCompleted(string result)
{
return View(result);
}
}
We have several Actions that need to perform API calls in parallel working just fine already; we just perform multiple requests, and ensure that we increment AsyncManager.OutstandingOperations correctly.
The scenario
To perform multiple API service requests in series, we presently are calling the next step within the event handler for the first request's DownloadStringCompleted. eg,
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["step1"] = e.Result;
OtherActionAsync(e.Result);
AsyncManager.OutstandingOperations.Decrement();
}
where OtherActionAsync is another action defined in this same controller following the same pattern as defined above.
The question
Can calling other async actions from within the event handler cause a possible race when accessing values within AsyncManager?
I tried looking around MSDN but all of the commentary about AsyncManager.Sync() was regarding the BeginMethod/EndMethod pattern with IAsyncCallback. In that scenario, the documentation warns about potential race conditions.
We don't need to actually call another action within the controller, if that is off-putting to you. The code to build another WebClient and call .DownloadStringAsync() on that could just as easily be placed within the event handler of the first request. I have just shown it like that here to make it slightly easier to read.
Hopefully that makes sense! If not, please leave a comment and I'll attempt to clarify anything you like.
Thanks!
It turns out the answer is "No".
(for future reference incase anyone comes across this question via a search)