users@concurrency-ee-spec.java.net

[jsr236-spec users] [jsr236-experts] Re: New ContextService API proposal from JSR 359 spec lead

From: Andrew Evers <andrew.evers_at_gmail.com>
Date: Wed, 23 Jan 2013 15:11:32 -0500

Hi guys,

To me there are two parts of this:
a) Passing additional information. There are other places that this
could be put, either part of the task itself (ie. via constructor or
setter during task setup); or execution properties. Execution property
values are restricted to strings, so either we need to change this
back to Object/Serializable; or the value passed needs to be a string
key into another data source; or the setup information needs to be
passed in as a string.
b) Locking the contextual information.

Of these, handling the locking is the difficult part. The most
effective way to handle this is to make the required lock(s) visible
to the entity that actually starts the tasks. This means that it can
skip over tasks that require locks that are currently held elsewhere,
and effectively avoid (most) deadlocks by taking all required locks at
the same time. Doing it later (once the task has started) means that
the task can start but then block immediately. This applies even for
tasks that are just using JDBC connections from a limited container
pool.

While exposing adding lock declarations to the executor service is the
most effective, this would require quite a few changes to the API and
implementation of the service. Having the container handle these
independently is also difficult as that is effectively a separate
spec.

I think that an optimistic approach is probably best for now. The
executor service ignores locking and resource contention completely,
and leaves these concerns to the task submitter/executor since they
have substantially more information available: eg. they may know that
no locking is required, or that only one object needs to be locked. In
complex situations they may use multiple services to ensure effective
performance.

That points towards using executor properties to handle this, either
by adding a key to retrieve the appropriate object (eg. SipSession),
and requisite locking. A base class that other tasks extend could help
with this for specific applications (eg. telephony). In this case
there needs to be agreement between the submitter and executor as to
what the contract is. Task execution needs to explicitly handle the
case where the value can no longer be retrieved.

This does raise a question in the spec though, what errors should be
given if serialization is required and some part of the task cannot be
serialized?

Regards,

Andrew.





On Tue, Jan 22, 2013 at 10:48 PM, Binod <binod.pg_at_oracle.com> wrote:
>
> The case we (JSR 359 EG) have is not "only" to pass a contextual information
> from application to the task/callable/runnable. The ContextHint is a way for
> the application to provide a hint to the container about the task execution
> strategy.
>
> Specifically, the ContainerSpecificContextObject can be a "SipSession" or a
> "SipApplicationSession". When the container receives this object as
> the hint, it should select a locking strategy such that there is no
> concurrent execution of tasks for that ContainerSpecificContextObject.
>
> So, for the usecases, we have been thinking about, the ContextHint may
> not be serializable and the lifecycle management of the ContextHint is
> upto the specific container that know about it.
>
> BTW, ContextHint mechanism is just a suggestion. I am open to any
> mechanism that help us utilizing JSR 236.
>
> thanks,
> Binod.
>
>
> On Wednesday 23 January 2013 01:30 AM, Nathan Rauh wrote:
>
> Anthony/Binod,
>
> I'm not sure I see the need for a new method that adds a ContextHint
> capability. Execution properties should already allow for this, apart from
> the requirement that execution properties always be String values whereas
> the ContextHint in the example has some other custom type
> (ContainerSpecificContextObject).
>
> Here's an example with the existing ContextService interfaces,
>
> Map<String, String> hints =
> Collections.singletonMap("com.mycompany.hints.MY_HINT_1", hint);
> Runnable rProxy = ctxService.createContextualProxy(myRunnableInstance,
> hints, Runnable.class);
> Future f = execSvc.submit(rProxy);
>
> ...
> hint =
> ctxService.getExecutionProperties(myRunnableInstance).get("com.mycompany.hints.MY_HINT_1");
>
> I would be open to allowing data types other than String from execution
> properties, provided those other types are serializable types defined in
> Java SE and deserializable from any classloader. But I'm hesitant to allow
> just any type to be stored as an execution property (or ContextHint) because
> contextual proxies must be able to serialize/deserialize properly, which
> means knowing the correct classloader of everything that serializes along
> with it.
>
> So I'm curious to learn more about what the "ContainerSpecificContextObject"
> is.
>
> Nathan Rauh
> ____________________________________________
> Software Engineer, WebSphere Application Server
> IBM Rochester Bldg 002-2 C111
> 3605 Highway 52N
> Rochester, MN 55901-7802
>
>
>
> From: Anthony Lai <anthony.lai_at_oracle.com>
> To: jsr236-experts_at_concurrency-ee-spec.java.net
> Cc: Binod <binod.pg_at_oracle.com>
> Date: 01/22/2013 01:07 PM
> Subject: [jsr236-experts] New ContextService API proposal from JSR
> 359 spec lead
> ________________________________
>
>
>
> Dear Experts,
>
> Binod, the spec lead for JSR 359 - SIP Servlet 2.0, is proposing a new API
> in ContextService to pass in application-provided information that can be
> retrieved in the thread that executes the task.
>
> Forwarding Binod's suggestion:
>
> <quote>
> It is possible for some containers to build contextual object based
> on application provided information. For example, a container could support
> thread safe execution of the tasks based on a specific contextual
> information.
>
> <T> T createContextualProxy(T instance, Properties executionProperties,
> Class<T> intf, ContextHint<C> hint)
> Object getContextHint(Object contextObject)
> /** Context hint information that contains the container specific
> object. **/
> interface ContextHint<C> {
> void setHint(C hint);
> C getHint();
> }
>
> Example code:
>
> public class MyRunnable implements Runnable {
> public void run() {
> System.out.println("MyRunnable.run with Container Context
> available.");
> ContextService ctxService = (ContextService) ctx
>
> .lookup("java:comp/env/concurrent/ContainerSpecificContextService");
> ContainerSpecificContextObject object =
> ctxService.getContextHint(this);
> }
> }
>
> InitialContext ctx = new InitialContext();
> ManagedExecutorService mes = (ManagedExecutorService)
> ctx.lookup("java:comp/env/concurrent/ContainerThreadPool");
>
> ContextService ctxService = (ContextService) ctx
>
> .lookup("java:comp/env/concurrent/ContainerSpecificContextService");
>
> MyRunnable myRunnableInstance = ...;
>
> ContextHint<ContainerSpecificContextObject> hint = new
> MyContextHint<ContainerSpecificContextObject>(...);
> Runnable rProxy = ctxService.createContextualProxy(myRunnableInstance,
> Runnable.class, hint);
>
> Future f = mes.submit(rProxy);
> </unquote>
>
> Any comments are welcome.
>
> Regards
> Anthony
>
>
>
>