Hi Romain,

Thanks for the tips. I need to look into your comment: "There are some
samples of a method scope. Sounds all you need linked with
some interception to activate the scope."  but I'm not sure that it will
address what I'm describing below.

I'm sorry for another long post but I don't know how to make this much
shorter. :-)  Also, none of this is urgent, and I'm not expecting any
significant help but any hints will be much appreciated.

I'm going to try to describe my situation in a different way and maybe it
will be clearer.  To clarify, I'm not asking about how the CDI spec works,
or how exactly it is implemented in OWB. Rather, there are few CDI services
(implemented in OWB) that I would like to continue to use as is but there
are other CDI services or features that are a special case of the more
general case. Below I try to describe the more general case, and how CDI is
a special case of it. What I'm trying to understand is how I might be able
to modify OWB to implement the general case.

To help with the discussion, I'd like to first introduce the term "World".
A world is modeled with a set of CDI beans (i.e. types and scopes). At
runtime, the world becomes "alive" in contexts and threads, and it could
possibly be persisted to be resumed at a later time.

The CDI spec assumes a single anonymous world (i.e. there are no persistent
world identifiers). The implementation of this anonymous CDI world in OWB
is in WebBeansContext and it is instantiate by making an instance and
entering it. CDI also assumes that in this world there is a one to one
mapping between scopes and active contexts at any one time. This is a
special case of having multiple active contexts for a scope and each object
proxy/contextual reference being aware of which context it came from. CDI
also doesn't require identifiers for contexts. There is one single, and
anonymous, active context and that is all that matters. The more general
case is that contexts have identifiers to distinguish them from each other
in addition to their scope. In other words, CDI contexts are only indexed
by scope, the more general case is that contexts are indexed by scope and
an additional key, or simply identified with global IRI/URIs, GUIDs, etc.
In this case, when a contextual reference is created, it has to also be
indexed by a specific context.

Because in CDI there is only one anonymous world at design time, and only
one instance of it at runtime in the form of the singleton active contexts,
there is no need to track where bean instances came from, what context to
use when resolving a contextual reference (when there are multiple active
ones), etc. This is all a special case of many worlds, multiple active
contexts, contexts and worlds with stable identifiers instead of the
singleton and anonymous worlds and contexts (basically null for
world/context ID), etc.

What I'm trying to understand is how can I use OWB to generalized the CDI
assumptions. It can be done either by multiple active contexts within a
single world, each with their own identity, and any contextual reference is
context aware (through the identity). Or, the better option is multiple
worlds and in each world CDI is implemented as usual but contextual
references are world aware through world identity. Either way, when an
object reference is obtained from one context, or from one world, and this
object is traversed, the other objects that are reached are the correct
ones. This is not a problem in CDI because there is a guarantee that there
is a single instance of the world (in the form of singleton active
contexts) and it is up to the implementation to guarantee this.

If the above is making things a little clearer, what I would like to
attempt is to do the following (in the same JVM for now):

1. Be able to instantiate multiple WebBeanContext instances.

2. Have a thread running in one instance be able to getReference(Bean<?>
bean, Type beanType, CreationalContext<?> ctx); on one of the BeanManager
of the other WebBeanContext instance and get an object (which could be
Instance<X>)  that is still connected to the other instance (its world)
without the thread having to manage this.

3. When this object is traversed, what is accessed is in that world's
contexts, not this world. i.e. the active contexts in that world, not the
ones in this world. Again, without thread based management.

A further generalization is that it should be possible to place some order
on these WebBeanContext instances rather than just a set; a hierarchical
tree for example. If a WebBeanContext is queried for Instance<X>, and this
WebBeanContext has children in the hierarchy (i.e. subworlds), the returned
Instance<X> will traverse the subworlds in depth or breadth first order.
All objects remain connected to their worlds.

The above scenarios will need explicit identities. Either multiple active
contexts in a single world with identities, or anonymous singleton contexts
in each world but with world identities. All references have to be identity
aware.

In terms of implementation details, I would like to experiment with this
idea within a parent classloader that has the common types that will be
accessible across the different worlds and each WebBeanContext might be in
its own sub classloader, or have it bean archives controlled. This could
also mean that the the same type might be modeled as belonging to different
scopes in each world instance (In the real world it is very common to have
the same types of things be contextualized in different ways) This is an
issue that is local to the world. What I care about is the types and the
instances. The contextual references have to remain connected to the
worlds, and behave according to their scopes in their worlds.

All of the above is not a radical change from CDI. It just generalizes it a
little and opens up a lot of possibilities. A further generalization that
I'm interested in is to then represent and persist these worlds (along with
their classpaths) in a graph database like OrientDB and at runtime worlds
are loaded on demand as WebBeanContexts and world events will trigger world
specific services to populate and instantiate the types that are common
across worlds. For example, one world might instantiate Person class from
REST services while the other instantiate the same type from database. Each
world will be in charge of how it populates its world, and the Java type
system and security manager will further enforce what is accessible across
these worlds.

I think the main two thing that I need to implement is:

1. A contextual reference can also be indexed by the container it came from
and resolves to that container regardless of where it is accessed from, and
in a way that doesn't depend on thread locals. The state that is usually
captures in the tread locals has to be put in the contextual references.
Maybe OWB already does this to some degree, I don't know. The CDI
specification doesn't address this so I'm assuming OWB doesn't guarantee
it. I know that this could be managed at runtime by some very smart
ThreadLocals, Interceptors, AOP, etc. but without explicit identity
integrated into the contextual references it will be hard to persist
contexts.

2. Hierarchical CDI containers, and when iterating over an Instance<X> sub
containers are also considered. Or, when a type is looked for in a parent
container, and it is not available, or its context is not active, the
parent or child  container is considered, based on the specific use case.
Considering parents is useful for defaults but considering children is
useful when a world is partitioned into a subtree.

Again, sorry for the long post!

Best,
Shahim


> > > parent context without having to define custom beans or bean
> qualifiers
> > > for
> > > > the related contexts. The Bean type is exactly the same but there are
> > > > additional instances in other contexts that should be considered when
> > > > needed. There are also other types of beans in those contexts and
> when
> > > each
> > > > bean instance is looked at in a context, it should be considered in
> > > > relationship to other instances in that same context.
> > > >
> > > > With the above example, I would like to possibly do the following in
> some
> > > > code that is running in the @PersonScoped context for a specific
> person
> > > > (contexts are identified per person just like sessions,
> conversations,
> > > etc.
> > > > are internally identified in the usual case), and all the
> instantiated
> > > > ancestor @OrgSScoped contexts that were previously instantiated at
> > > runtime
> > > > and assigned as parent contexts for this specific person. If this
> code
> > > has
> > > > the following injection point:
> > > >
> > > > @Inject Instance<WorkInfo> workInfo;
> > > >
> > > > and there is a bean:
> > > > @OrgScoped
> > > > class WorkInfo {}
> > > >
> > > > and the code iterates over the instances, it should see a list of
> > > WorkInfo
> > > > instances starting from the direct @OrgScoped context as usual but
> then
> > > > also be able to get the instances from the parent contexts that were
> > > > explicitly managed at runtime. So, the code will see their WorkInfo
> > > > instances from their direct work context but then other instances
> from
> > > the
> > > > parent contexts.
> > > >
> > > > I think this can be boiled down to having a method that returns a
> list of
> > > > contexts from BeanManager as in:
> > > >
> > > > public List<Context> getContext(Class<? extends Annotation>
> scopeType);
> > > >
> > > > and have the various CDI services be able to deal with this by going
> > > > through the list. The current behavior would be equivalent to only
> using
> > > > the first context on this list, if it is available.
> > > >
> > > >
> > > > I know this might sound strange but the CDI programming model is very
> > > > useful (more flexible domain modeling, injection, type resolution,
> etc.)
> > > > but the context model is not flexible enough. There are a lot of real
> > > world
> > > > situations that can be addressed with more flexible contexts rather
> than
> > > > with additional qualifiers and scopes. The organization example above
> > > can't
> > > > really be dealt with with more qualifiers and scopes. There is no
> limit
> > > to
> > > > the nesting of organizational structures and there is a lot of
> > > duplication
> > > > of information types in each nested context (i.e. same Bean but
> different
> > > > instance).
> > > >
> > > > The above example is just a simplified version of my use case. I'm in
> the
> > > > biomedical domain and involved in ontology development, and data
> > > > integration and exchange. The ability to create runtime contexts of
> the
> > > > same scope, populate those contexts with the same type of data but
> from
> > > > different sources, and have those instances available for injection
> in a
> > > > controlled way (beyond the simple one context per scope) could be
> very
> > > > powerful. Think about all the identical medication information that
> > > exists
> > > > for you in different contexts (hospitals, clinics, etc.) but where
> the
> > > > different prescriptions are very contextual and can't be well
> understood
> > > > outside their own context. They are based on a specific visit,
> doctor, a
> > > > specific diagnosis, etc. all of which forms a single clinical context
> > > > instance but these instances should be accessible from other contexts
> for
> > > > validation, monitoring, reconciliation, etc. This is complicated but
> I'm
> > > > trying to explore the possibility of representing some of this as CDI
> > > > context instances (rather than qualifiers, etc.) with some additional
> > > APIs
> > > > to link contexts, and resolve injection points across these linked
> > > contexts
> > > > in an application specific way without having to give up on using the
> > > rest
> > > > of CDI.
> > > >
> > > > What do I need to look at in the current OpenWebBeans implementation
> to
> > > > start to understand how I might be able to do this? Any hints will be
> > > > really appreciated, and at some point I'll be familiar enough with
> the
> > > > implement details to be able to help with other tasks :-)
> > > >
>
> There are some samples of a method scope. Sounds all you need linked with
> some interception to activate the scope.
>
>
> > > > Best,
> > > > Shahim
> > >
> > >
>

Reply via email to