polygene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niclas Hedhman <nic...@hedhman.org>
Subject Initializable, Invariants in invaluable inspection
Date Mon, 25 Dec 2017 00:27:25 GMT
Merry Christmas everyone,

Never mind the title, but there is a design flaw in the initializable
system for values. I think it stems from the fact that it was initially not
very well defined and has since changed from being a callback for the Mixin
rather than the Composite.

At the moment, for ValueComposites (I have not checked it to be the case
for the others) the Initializable is called at vbf.newValueBuilder() after
the injection phase. This is suitable for setting up things like
creationTime and anything else that is not depending on what else is set
from the builder.

But, one can't use it to compute a property during initialization, and
since properties are immutable in Value Composites, there is actually no
way at the moment to do this other than in the code that instantiate the
value.

So, we put this (able to initialize properties during the newInstance()
phase) aside as a "requirement", and let's look at a broader picture;
Invariants.


Long ago, we tried to solve the request that one could declare Invariant
checks, especially for aggregated Entities. That effort never took root in
Qi4j, and perhaps now is the time to look at the whole picture.


Invariant checking is about ensuring that an Entity Aggregate is never
accessible in a incoherent state. Transactions/UnitOfWork takes care of the
atomicity, but there is no built-in mechanism to ensure that an invalid
state has not occurred "naturally", say, the total allocated container CPU
load isn't higher than the host's available CPU capacity. At the moment,
such thing needs to be built in somewhere, and without front-facing
services handling such entities, it is quite easy for developers to
"forget" or "didn't know" such rules.

The same checking mechanism should be generic enough to apply to all
Composites, so let's assume that we solve this somehow.

Now, such checking needs to happen in more than one place. On one hand, for
entities, this needs to take place at uow.complete(), prior to committing
it to persistent storage. For all composites it also needs to happen at
builder.newInstance(). And for Transient Composites, it would also need to
happen on every set() method.

So these hook points are needed to support Invariant checks (mechanics not
relevant right now), but could we make these hook points more generic, so
that the initialization issue above could leverage the same underlying hook?

If so, then I wonder if the majority of hooks that are in place, could be
made equally generic, and therefor a big reduction in codebase handling all
these hooks to be invoked. There are a great number that comes to my mind,
beyond the two mentioned ones above;

* Activation system
* Lifecycle interface for entities
* Field injection, Constructor injecton, Method injection
* newValueBuilderWithState(), newValueBuilderWithPrototype(),...
* newEntityBuilderWithState()
* addUnitOfWorkCallback, removeUnitOfWorkCallback
* StateChangeNotificationConcern

And I am sure there are others.

So, we could either organically add better handling of Initializable, such
as adding a separate interface called during builder.newInstance(), meant
for the Composite (i.e. resolved to a single mixin method call), and later
figure out how to do Invariants.
OR, we could tackle this head on, and figure out how such generic hook
mechanism is supposed to work, and how to refactor a bunch of core
functionality into pluggable parts.

To me, the latter sounds like the "right" but "slow" thing to do. If it
sounds reasonable to do this ( a 4.0 release in a year or so), then the
next steps would be to identify all the hooks that are needed, define the
mechanism and then start the refactoring.

WDYAT?


Cheers
-- 
Niclas Hedhman, Software Developer
http://polygene.apache.org - New Energy for Java

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message