It's possible to create a lockless parallel domain using Actors. As an alternative to LMAX.
Cheers,
v
So in this approach we do not need CommandHandlers...
Simply AggregateRoots handle commands.
I consider this as shooting int the foot, because in this approach we
get rid of Application Layer. What are consequences of trivializing
layers?
1. It can not be seen in this "hello world" sample, but in real cases
ARs will be overloaded with Application (not Domain) logic:P
But I can imagine systems where there is no App logic, only Domain
logic, so this approach is potentially useful somewhere...
2. What about scenarios where more than one AR (same BC) need to play
to fulfill command? I know about scalability, but what if requirements
demands this?
Cheers,
Sławek Sobótka
> > 1. It can not be seen in this "hello world" sample, but in real cases
> > ARs will be overloaded with Application (not Domain) logic:P
> > But I can imagine systems where there is no App logic, only Domain
> > logic, so this approach is potentially useful somewhere...
>
> Could you elaborate with an example on this ? I assume the logic would
> still be somewhere in the controller (in case of MVC)
Briefly described above. App Layer is still something between
Presentation Layer (C) and Domain logic.
> > 2. What about scenarios where more than one AR (same BC) need to play
> > to fulfill command? I know about scalability, but what if requirements
> > demands this?
>
> Good remark; On the technical side, there is currently nothing that holds
> me back to have a command handled by multiple AR types. However; I was not
> aware this was a valid use case, but maybe it might be a good idea to make
> this possible...
What about such a UC:
When confirming Order we must generate an Invoice?
Let's assume that Order and Invoice are both in "Sales" Bounded
Context and let's assume they must be calculated in one transaction.
Of course in real ERP Aggregates would be modeled in totally different
shape and boundary, but lets abstract from domain and focus on
technical issues (because we are discussing a kind of framework here).
Sample code:
http://code.google.com/p/ddd-cqrs-sample/source/browse/trunk/ddd_cqrs-sample/src/main/java/pl/com/bottega/erp/sales/application/commands/handlers/SubmitOrderCommandHandler.java
Some visualization:
http://prezi.com/hi2dmhfej9zu/ddd-cqrs-sample/
Some reading introducing to mentioned code:
http://code.google.com/p/ddd-cqrs-sample/wiki/DomainDrivenDesignBusinessDeveloperMentalModel#Application_Architecture
http://code.google.com/p/ddd-cqrs-sample/wiki/DomainDrivenDesignBusinessDeveloperMentalModel#Application_Layer
Cheers,
Sławek Sobótka
I'd say having multiple collaborating aggregates is quite common,
eventhough only one aggregate gets affected/changed. You can't assume
full consistency for the other aggregates, only eventual consistency
(i.e. they can be changed in the meantime). You could move some of the
internal state of the other aggregates into the command (i.e. surfaced
in the readmodel, displayed to an end-user, copied into the command.
Note this is a matter of trust/security), but that depends on the use
case, and is somewhat counterintuitive to encapsulation.
It's just easier to have an explicit command handler, IMO. The command
contracts and types are not part of the domain type system (the former
are about wire representation, not behavior). As such, it's a slippery
slope towards high coupling/versioning problems. But that's not to say
this is going to affect you/everyone. Really depends on the size of
the system/BC (the problem with simplistic examples is they offer poor
guidance for larger systems).
As for logic, it should be in neither the controller, nor the command
handler. Belongs in domain services or objects.
Cheers,
Nuno
http://groups.google.com/group/lmax-disruptor
> Cheers,
>
> Nuno
From a quick read on the articles, It seams that disruptor was created to eliminate the latency in exchanging data between concurrent threads, yet the biggest success case is when we use it with a single thread, in which case I would assume that wouldn't be such a problem. I'm sure I'm missing something, can anyone clarify this for me?
Nuno
There's only a single thread processing [nonblocking] domain logic but
many threads doing [blocking] IO. With another architecture (e.g.
actors) you don't bother with possibly blocking code because you have
many threads, which become a bottleneck on runtimes not designed for
concurrency. If they used Erlang, for example, with very cheap
processes they would not bother with nonblocking code.
> Nuno
Here's the .NET port of the LMAX Disruptor which also has LMAX contributors committing code. This is the one I'm using in my .NET projects.
If it just the BLP then we need also to assume that a single producer is able to dispatch far mor the 6 million request to the Disruptor to keep the BPL busy. So it must multithreaded.
Is this a correct assumption?
Sent from my iPhone
You don't want your framework to take up a lot of overhead, and that's what that number is quantifying: depending on what your BLP is doing you can expect the framework won't get in your way at 6 million messages or less.
IMO you explain it pretty good; have you ever considered writing a blog post (series) about it ?
Tom
Typed on a mobile
BTW, the loadhandler parameter in the scritchybus constructor is supposed to be calling your IOC container, but apparently that is something that is not obvious to some devs. I will try to find a way to make it a little bit more obvious.
I call activator.createinstance as a sensible default, but I would advise anybody to use a proper container.
Thanks!
Typed on a mobile
One of the responsibilities of this layer is to make explicit the
dependencies that are used for a use case. As example ...
class FooHandler : Handes<FooCommand> {
public FooHandler(IFooRepository, IDoSomethingService, IBarRepository) {
}
void Handle(FooCommand msg) {
var item = fooRepo.GetById(msg.FooId);
var itemtoJoin = barRepository.GetById(msg.BarId);
itemtoJoin.JoinTo(item, doSomethingService);
barRepository.Save(itemToJoin);
}
}
It is quite common that there are many objects at play in the app service.
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.
On 17 nov, 13:23, Greg Young <gregoryyou...@gmail.com> wrote:
> I have some worries with a lack of command handlers/app service layer.
>
> One of the responsibilities of this layer is to make explicit the
> dependencies that are used for a use case. As example ...
>
> class FooHandler : Handes<FooCommand> {
> public FooHandler(IFooRepository, IDoSomethingService, IBarRepository) {
> }
> void Handle(FooCommand msg) {
> var item = fooRepo.GetById(msg.FooId);
> var itemtoJoin = barRepository.GetById(msg.BarId);
> itemtoJoin.JoinTo(item, doSomethingService);
> barRepository.Save(itemToJoin);
> }
>
> }
>
> It is quite common that there are many objects at play in the app service.
>