This just reinforces my feeling that CDIControl and context lifecycle 
management should be two separate APIs. Context control is relevant in Java EE 
and SE. Container start/stop is only relevant in JavaSE.

I would suggest that context lifecycle management should be dependent scoped 
injectable bean(s), so that you can access it either in a CDI bean or outside a 
CDI bean (and then control the other scopes).

For inspiration for the context control, we could look at Weld, which defines 
an API for context lifecycle management. As a quick example:

class Foo {

    @Inject RequestContext requestContext;

    void ensureRequestContextActive() {
        if (!requestContext.isActive()) {
            requestContext.activate();
        }
    }

    void endRequest() {
        if (requestContext.isActive()) {
            // e.g. Make sure any conversation that have timed out are cleaned 
up, we split this out so that we don't force people to do this, in case they 
are just restarting the request context for some reason
            requestContext.invalidate();
            requestContext.deactivate();
        }
    }

}

The API looks like:

// We use an empty subclass to allow injecting by type
public interface RequestContext extends ManagedContext {}

// Context is the standard CDI SPI
public interface ManagedContext extends Context {

   /**
    * Activate the Context.
    */
   public void activate();

   /**
    * Deactivate the Context, destroying any instances if the context is 
invalid.
    */
   public void deactivate();

   /**
    * Mark the context as due for destruction when deactivate is called.
    */
   public void invalidate();

}

Note that Weld mixes this lifecycle management API in with an abstraction over 
the context backing store (allowing you to use e.g. the http session, or a 
plain map you manage yourself, or whatever you want). I don't think we 
necessarily need to introduce that to Deltaspike right now.

A requested enhancement to this API for Weld, which I think we should support 
is the ability to inject not only built in context objects, but any that the 
user creates. I would suggest we do this based on extending ManagedContext.

When I wrote this, I modelled Request and Session identically (as above). 
ApplicationContext (and SingletonContext) is not modelled as a managed context, 
as I don't expect a user to be able to activate or deactivate it. The Dependent 
context is also not modelled as a managed context, as it has no lifecycle. I 
did create an interface for it, which simply extends Context with no more 
methods, to allow consistent use of injection.

Conversation context is obviously the more complex one ;-) It's modelled as a 
managed context, and adds:

* a method to access and mutate the parameter name used to carry the 
conversation id (the parameter is got from the request context object). I don't 
think we should have this in Deltaspike, as it's outside the spec by a long way 
;-)
* a method to access and mutate the concurrent access timeout *default* for the 
app. This is useful I think, and I would assume all impls do support this in 
some way
* a method to access and mutate the conversation inactivity timeout *default* 
for the app. This is useful I think, and I would assume all impls do support 
this in some way
* a method to get a list of all conversations the container knows about (for 
this session), returns a List<ManagedConversation>, more below
* a method to get the conversation by ID, returns ManagedConversation
* a method to have the container generate a new conversation id using whatever 
algorithm it wants
* a method to get the current active conversation

ManagedConversation is a subclass of Conversation, and adds:

* ability to lock and unlock the conversation (concurrent access)
* get the timestamp the conversation was last used
* "touch" which updates the last used timestamp to now

I'm not sure Deltaspike needs ManagedConversation.

You can read the full API at 
https://github.com/weld/api/tree/master/weld/src/main/java/org/jboss/weld/context
 - but ignore the sub packages, and the BoundContext interface, as they relate 
to abstracting out the backing store.

I think this approach would give a powerful, easy to use API for context 
lifecycle management. It also has the benefit of ironing out the differences 
between built in and user provided contexts, and provides a model for 
extensions to create context lifecycle management APIs based on.

WDYT?

On 29 Feb 2012, at 07:53, Mark Struberg wrote:

> Hi!
> 
> Pete did ask me a few days ago if the CdiContainer is really only targeted to 
> JavaSE.
> Well, basically it _was_. But yesterday I reviewed the 3 Quartz Extensions 
> from Ronald, OpenKnowledge and Seam3 and when looking at the first 2 I saw 
> that
> 
> 1.) OpenKnowledge introduces an own Context named @ThreadScoped and start it 
> manually in the newly started Quartz thread.
> 
> 2.) our TISS Quartz Extension (done by Ronald) uses OWB specific code to 
> start a RequestScope for the newly started thread in which Quartz runs.
> 
> I've not looked into the Seam3 extension in detail because it does a hell lot 
> more and I'm not sure if we really need all that. A few things look really 
> good but I didn't have enough time to plug them apart.
> 
> What are the pros and cons of 1.) and 2.) so far?
> 1.) is CDI container independent but you must not use @RequestScoped because 
> this Context is not active in the new thread. You can use the new 
> @ThreadScoped but if you use the same @Transactional services for the Quartz 
> job and the rest of your app, then you must not use a @RequestScoped 
> EntityManager. 
> 
> 
> 2.) Sharing the services between the Quartz job and the rest of the app is 
> perfectly fine but it's currently Container specific how the @RequestScoped 
> can get activated for a freshly created thread.
> 
> 
> And then Pete's words jumped into my head. 
> 
> 
> So, what about using the CdiContainer#startContext(RequestScoped.class); in 
> that CDI Extension?
> That looks pretty much perfect to me!
> 
> We could also provide multiple impls, e.g for: WeldSE, WeldEE, OwbSE, OwbEE, 
> ResinEE, 
> 
> Anyone could easily implement the control part himself if the standard 
> container integration doesn't work out of the box for a certain EE container.
> If e.g. OwbEE will not work on WebSphere-8.0.2, then its easy to just write 
> an own!
> 
> 
> 
> wdyt?
> 
> LieGrue,
> strub
> 
> 
> PS: Pete we might add some kind of Context-Control to the CDI-1.1 spec, wdyt?
> 

Reply via email to