----- Original Message -----
From: "Vojtech Szocs" <vszocs(a)redhat.com>
To: "Alon Bar-Lev" <alonbl(a)redhat.com>
Cc: "Mark Proctor" <mdproctor(a)gmail.com>, devel(a)ovirt.org
Sent: Friday, November 7, 2014 4:45:57 PM
Subject: Re: [ovirt-devel] Thoughts on modularization
----- Original Message -----
> From: "Alon Bar-Lev" <alonbl(a)redhat.com>
> To: "Vojtech Szocs" <vszocs(a)redhat.com>
> Cc: devel(a)ovirt.org, "Mark Proctor" <mdproctor(a)gmail.com>
> Sent: Wednesday, November 5, 2014 5:16:15 PM
> Subject: Re: [ovirt-devel] Thoughts on modularization
>
>
>
> ----- Original Message -----
> > From: "Vojtech Szocs" <vszocs(a)redhat.com>
> > To: "Alon Bar-Lev" <alonbl(a)redhat.com>
> > Cc: devel(a)ovirt.org, "Mark Proctor" <mdproctor(a)gmail.com>
> > Sent: Wednesday, November 5, 2014 6:07:50 PM
> > Subject: Re: [ovirt-devel] Thoughts on modularization
> >
> >
> >
> > ----- Original Message -----
> > > From: "Alon Bar-Lev" <alonbl(a)redhat.com>
> > > To: "Vojtech Szocs" <vszocs(a)redhat.com>
> > > Cc: devel(a)ovirt.org, "Mark Proctor" <mdproctor(a)gmail.com>
> > > Sent: Wednesday, November 5, 2014 4:32:31 PM
> > > Subject: Re: [ovirt-devel] Thoughts on modularization
> > >
> > >
> > >
> > > ----- Original Message -----
> > > > From: "Vojtech Szocs" <vszocs(a)redhat.com>
> > > > To: "Alon Bar-Lev" <alonbl(a)redhat.com>
> > > > Cc: devel(a)ovirt.org, "Mark Proctor"
<mdproctor(a)gmail.com>
> > > > Sent: Wednesday, November 5, 2014 5:24:14 PM
> > > > Subject: Re: [ovirt-devel] Thoughts on modularization
> > > >
> > > >
> > > >
> > > > ----- Original Message -----
> > > > > From: "Alon Bar-Lev" <alonbl(a)redhat.com>
> > > > > To: "Vojtech Szocs" <vszocs(a)redhat.com>
> > > > > Cc: devel(a)ovirt.org, "Mark Proctor"
<mdproctor(a)gmail.com>
> > > > > Sent: Wednesday, November 5, 2014 4:12:06 PM
> > > > > Subject: Re: [ovirt-devel] Thoughts on modularization
> > > > >
> > > > >
> > > > >
> > > > > ----- Original Message -----
> > > > > > From: "Vojtech Szocs" <vszocs(a)redhat.com>
> > > > > > To: devel(a)ovirt.org
> > > > > > Cc: "Mark Proctor" <mdproctor(a)gmail.com>
> > > > > > Sent: Wednesday, November 5, 2014 5:04:24 PM
> > > > > > Subject: [ovirt-devel] Thoughts on modularization
> > > > > >
> > > > > > Hi guys,
> > > > > >
> > > > > > I've discussed this recently with Yair and Mark, I just
wanted to
> > > > > > share
> > > > > > some more thoughts on this topic -- in particular, how
> > > > > > modularization
> > > > > > problem can be approached (regardless of implementation
details).
> > > > > >
> > > > > > I see two approaches here. The typical one is to define
APIs for
> > > > > > modules
> > > > > > to consume. For example, oVirt Engine extension API has API
for
> > > > > > auth
> > > > > > stuff; oVirt UI plugin API has API for showing tabs and
dialogs,
> > > > > > etc.
> > > > > > The advantage is strict consistency, disadvantage is burden
of
> > > > > > having
> > > > > > to maintain the whole API. With this approach, you tell
modules:
> > > > > > "This
> > > > > > is the API to work with system, defining how you can plug
into
> > > > > > it."
> > > > > >
> > > > > > Now turn 180 degrees. The other approach, which is really
> > > > > > interesting,
> > > > > > is to let modules themselves export API. This naturally
leads to
> > > > > > module
> > > > > > hierarchies. Ultimately, this leads to micro-kernel-style
> > > > > > development,
> > > > > > where all logic resides in modules. Now you might ask:
"What if
> > > > > > we
> > > > > > want
> > > > > > to employ some consistent work flow across multiple
modules? For
> > > > > > example,
> > > > > > have some pluggable *auth* infra?" -- this can be done
via some
> > > > > > "higher"
> > > > > > level module, that exports API and "lower" level
modules consume
> > > > > > that
> > > > > > API.
> > > > > >
> > > > > > If you have any ideas, please share!
> > > > >
> > > > > Both solutions can be applied using existing extension api, an
> > > > > extension
> > > > > can
> > > > > locate other extension and interact with it the same way the
core
> > > > > interacts
> > > > > with extensions.
> > > >
> > > > But how does core interact with extensions? I assume via
well-defined
> > > > API, i.e. in accordance with first approach mentioned above.
> > >
> > > presentation:
> > >
http://www.ovirt.org/File:Ovirt_3.5_-_aaa.pdf
> >
> > Thanks for sharing!
> >
> > >
> > > package org.ovirt.engine.api.extensions;
> > >
> > > /**
> > > * Interface of an extension.
> > > */
> > > public interface Extension {
> > >
> > > /**
> > > * Invoke operation.
> > > * @param input input parameters.
> > > * @param output output parameters.
> > > *
> > > * <p>
> > > * Interaction is done via the parameters.
> > > * Exceptions are not allowed.
> > > * </p>
> > > * <p>
> > > * Basic mappings available at {@link Base}.
> > > * </p>
> > > *
> > > * @see Base
> > > */
> > > void invoke(ExtMap input, ExtMap output);
> > >
> > > }
> >
> > OK, so it was my lack of knowledge of AAA implementation :)
> >
> > Since Extension interface is invoke-based, I assume that Engine
> > core (backend) invokes extensions on specific occasions, right?
>
> correct, and nothing prevents extension to invoke other extensions.
I see. I just wanted to clarify who makes the initial invocation.
If there is some core, extensions just extend that core. This is
different from my view of pure modularization, where there is no
core, there are just modules and all important logic resides in
modules.
Well, with the proper resources (time + personnel) I see no reason why engine cannot be
transformed into pure modularization appraoch, as you suggest for UI, besides of course
having a small
microkernel or call it whatever you want that will be responsible on loading the
extesnsions, resolving dependencies etc...
>
> > >
> > > > With second approach mentioned above, core would not interact with
> > > > extensions at all (or in a very limited way), instead - extensions
> > > > would interact with each other. In other words, extension would not
> > > > need to implement core-specific API (there would be none), instead
> > > > it would inject its dependencies (other modules/extensions) and
> > > > consume their APIs. This is the difference I wanted to point out :)
> > >
> > > The extension interface is primitive to enable exactly that, provided
> > > java
> > > people will open their minds :)
> >
> > Simple interface means great flexibility, now I understand the
> > rationale behind typed maps in extension API.
> >
> > What I had in mind was something like this (maybe crazy):
> >
> > * imagine for a moment that the backend is fully modular
> > (logic lives in modules, no logic outside modules)
> >
> > * @DependsOn("SomeOtherModule") // modules can form hierarchies
> > public class MyModule implements Module {
> > public void loaded() {} // executed just once per module
> > }
>
> you again using java magic for something that can go to declaration...
Java annotations are static metadata, they are not magic :)
Annotations are helpful because they declare what should be
done, not how it should be done. @DependsOn in example above
means that some infra will process/scan classes and if it
finds this annotation, it will invoke extra logic according
to the semantics of this annotation.
Yes, it could also go into "conventional" declaration like
properties files etc. I have nothing against that, the major
point is declaring useful metadata in some way :)
>
> >
> > * API for fetching modules, i.e. getModuleByName('xxx')
>
> there is no need as within the extension context you have access to this
> information, all you need is iterate a list, see Base.java.
What I meant: module A exports API "foo", module B depends on
module A and therefore can consume API "foo".
IIUC, in Engine ext-api you must find appropriate extension
yourself, in order to invoke it. This is the difference,
because what I suggested above is to allow modules to state
their dependencies, instead of having to locate them on their
own.
Declaring dependencies in advance has many advantages, one
of them is you can avoid "always load all dependencies in
some sequence" because you don't know which module will
need which other module.
>
> > API for exporting module API, i.e. exportApiObject(foo)
>
> not sure why it is needed... once extension is loaded it is available.
It was meant as means of communication between modules.
Engine ext-api invoke-based interface defines communication
between extensions via input & output maps. What I meant is
different mean of communication -> one module exports its
API (i.e. object) and another module can consume that API.
>
> > This way, you'd have one "core" module, providing most general
> > functionality/abstractions. Then you'd have more specific modules,
> > plugged into "core" module's API etc. In other words, hierarchy
of
> > modules. This is essentially modularization taken to extreme :)
> >
> > (BTW, above is just an idea.)
>
> not sure I understand what is the functionality difference between this and
> the primitive approach we already have...
The difference is:
a, have some (monolithic) core, which invokes extensions
b, have no core, everything is a module
>
> 1. every configuration at /etc/ovirt-engine/extensions.d and
> /usr/share/ovirt-engine/extensions.d are loaded during engine startup.
In a modular architecture, where everything is a module, module
"tree" is determined (according to module dependency declarations)
and loaded.
In a typical extension architecture, all extensions are always
loaded in some sequence.
>
> 2. each extension has two phases load and init, during init an extension
> can
> locate other extensions by name via its context. it is true that probably
> missing functionality is to support ordering of the init and load, we left
> it into future as there was no actual need for this.
This is actually quite similar to how our UI plugins are loaded,
except for that "locating other plugins" is not implemented.
>
> 3. each extension can interact with other extension.
>
> 4. there must be core model to trigger the entire thing, core cannot be
> just
> a loader.
This is a design decision. A "core" can be either monolithic base
(includes business logic) that invokes extensions. Alternatively,
"core" can be just module loader, and all logic is in modules.
So I disagree - core CAN be "just" a module loader.
See
http://requirejs.org/docs/whyamd.html for details on this topic.
>
> Alon
>
_______________________________________________
Devel mailing list
Devel(a)ovirt.org
http://lists.ovirt.org/mailman/listinfo/devel