Further Info; At the moment, the Initializable is called both on vbf.newValueBuilder() (and its variants) as well as vbf.newInstance(). This is a result of that the Value prototype is constructed with Mixins, and mixins are handled uniformly in this respect.
On Mon, Dec 25, 2017 at 8:27 AM, Niclas Hedhman <[email protected]> wrote: > 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 > -- Niclas Hedhman, Software Developer http://polygene.apache.org - New Energy for Java
