polygene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niclas Hedhman <nic...@hedhman.org>
Subject Activation (post-3.0)
Date Fri, 26 May 2017 09:43:22 GMT
Gang,

The more I look at Activation the more I realize that it is very
problematic and I don't think we have gotten it right.

There are these areas of concern;

  1. Lazy initialization, which may happen in threaded execution, which
wasn't anticipated on design.

  2. Non-symmetric activate()/passivate() semantics.

  3. Permitted operations

There is not too much to say about the first one, other than a review of
thread-safety during activation is needed. What I think I have observed is
that a service might be used prior to completion of activation. This might
have been the result of avoiding two or more activations to end up calling
each other.

On number 2, if a service is lazily activated, then upon first use, the
service will be activated. Then by definition, it should follow that if the
service has been passivated, it should "go back" to this "not activated"
state and a new use should activate it again. I am pretty sure that this
doesn't happen. And currently, I suspect that there are a lot of places
where a passivate()->activate() will not result in a poperly operational
state.

There has previously not been any limitation of what one can do in
activation code, on the basis that any needed services will be activated
along the way. Allowing anything in activation is probably the cause of
number 1, and the fix (resulting in number 1) was probably the wrong
solution.

This topic goes really, really deep into the Services semantics, and I
don't think it is something to be fixed for 3.0, but I think we need to
have some serious, possibly long, discussion of what is needed.

To some degree it comes down to the same problem as "Constructors" and
"Setters", which is "when is the object ready?". For instance, can a final
field be 'not initialized"? Well, like this;

private static class Test {
    private final String name;

    public Test() {
        printName();
        name = "Niclas";
    }

    private void printName() {
        System.out.println(name);
    }

    public static void main( String[] args ) {
        new Test();
    }
}

The Java Language Spec 12.5 deals with this, and we are analogous of the
super-class calling a subclass method before subclass has been initialized.

The analogy with "pojo setters" is similar, that it is difficult to know
when the pojo is ready to be used. Some people applies "default values
everywhere" so that object is operational even if no setters are called.

I am sure that Spring Framework has similar problems, and I suspect that
they prohibit cyclic-dependencies (dependencies is a topic also relevant to
this discussion).

So, we have these (or similar) problems everywhere, What can we do during
initialization? When can we use the object being initialized? What can we
do during initialization code? Are there more than one phase in
initialization?

The good news is that Polygene has limited the scope under consideration,
compared to Spring (where "everything is a nail"). We have Services that
has this "ability" of passivation, and we have (perhaps unfortunately)
extended the same interface to modules/layers/application.

I am not sure exactly how to get out of the actual problem, but some things
that has crossed my mind as Random Thoughts(tm) are;

  1. More and well-defined phases?

  2. Lambdas?

  3. No lazy-instantiation?


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