You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by Artem Gr <ar...@bizlink.ru> on 2004/02/10 15:52:25 UTC

Shared objects in Velocity Context.

The good thing about Velocity Context is that
you can put a lot of objects into the Context
and give all them to HTML-XML-writer, then HTML-writer
can do whatever he wants with those objects, or do nothing at all,
whilst CPU time is spent only when he actually do something.
Those objects in the Context can be thought of as a
problem-oriented-language targeted at HTML-writer.

This path, however, is not as convenient and efficient as it could be:
A lot of objects in the Context might need to use some context-specific
information, such as session, specific request parameters,
or something else put into the Context by someone.
And there is only a few ways for the object to receive this
information. One is to synchronize access to all objects in the
Context as a whole, that is, only one Velocity Context
might be merged into template at the time, so that we
can just give the Context to all the objects before merging it.
Other is for every new Context to create all the objects
from scratch and give the Context to each object thru object's
constructor. (I'll be glad to hear of another ways to accoplish this).
Described methods are surely inconvenient.
The first kills concurency and may produce user-visible hangs.
The second forces us to recreat all the objects in the Context,
which is not at all efficient, becouse memory allocation is never
cheap and objects might have some heavy initializers in constructors
or do some internal caching, which is humped when we recreate them,
and it is neither convenient nor efficient when we have to
create proxies to objects whoes number of instances should be limited,
instead of just placing those objects into the Context.

I came to simple solution for this problem
by giving the Context thru the hidden parameter of a method:
If method exists without hidden Context parameter,
then it is executed as usual, but if no such method exists,
then I check for a method with the same parameters plus the hidden
Context parameter, and if it is present, it is executed receiving
the current Context.
Thus shared objects can be put into Velocity Context and remain there,
and a big part of a context can be shared thru the context chaining,
with only dynamically changed values, such as session,
placed into the each-time-allocated Context.

Attached (as a demo) are my patches for "velocity-1.3.1".
If someone is interested and want to reimplement it for the mainline,
great. If someone is still interested, but have no time to implement,
there is a chance that I will try to write a better patch
for velocity-1.4.1-rc1, which, perhaps, should be more integrated,
becouse of Uberspect.
Although I don't know, yet, how the ASTMethod is generated.

Shared objects in Velocity Context.

Posted by Artem Gr <ar...@bizlink.ru>.
In case my demo patches doesn't make it to the mailing list in the
attachment, here are the URLs:
http://glim.ru/velocity/131.ASTMethod.diff
http://glim.ru/velocity/131.IntrospectionCacheData.diff


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org


Re: Shared objects in Velocity Context.

Posted by Neil Katin <ve...@askneil.com>.
Apologies if I don't understand your problem, but isn't
this what java.lang.ThreadLocal is supposed to be all
about?

I use them to hold database sessions and the current
context for a request; it seems to work painlessly.
It had some performance problems in java 1.2 days, but
now works efficiently.

Artem Gr wrote:

> By the way, I found a solution to "shared context-aware objects"
> problem, that no one here mentioned.
> It's very simple (and is often used, I just overlooked it).
> It is to put current context into map of threads:
> Map threadContexts = new HashMap();
> threadContexts.put( Thread.currentThread(), theContext );


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org


Re: Shared objects in Velocity Context.

Posted by Artem Gr <ar...@bizlink.ru>.
By the way, I found a solution to "shared context-aware objects"
problem, that no one here mentioned.
It's very simple (and is often used, I just overlooked it).
It is to put current context into map of threads:
Map threadContexts = new HashMap();
threadContexts.put( Thread.currentThread(), theContext );

AG> A lot of objects in the Context might need to use some context-specific
AG> information, such as session, specific request parameters,
AG> or something else put into the Context by someone.
AG> And there is only a few ways for the object to receive this
AG> information. One is to synchronize access to all objects in the
AG> Context as a whole, that is, only one Velocity Context
AG> might be merged into template at the time, so that we
AG> can just give the Context to all the objects before merging it.
AG> Other is for every new Context to create all the objects
AG> from scratch and give the Context to each object thru object's
AG> constructor. (I'll be glad to hear of another ways to accoplish this).
AG> Described methods are surely inconvenient.
AG> The first kills concurency and may produce user-visible hangs.
AG> The second forces us to recreat all the objects in the Context,
AG> which is not at all efficient, becouse memory allocation is never
AG> cheap and objects might have some heavy initializers in constructors
AG> or do some internal caching, which is humped when we recreate them,
AG> and it is neither convenient nor efficient when we have to
AG> create proxies to objects whoes number of instances should be limited,
AG> instead of just placing those objects into the Context.


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org


Re: Shared objects in Velocity Context.

Posted by Geir Magnusson Jr <ge...@4quarters.com>.
On Feb 10, 2004, at 9:52 AM, Artem Gr wrote:

> The good thing about Velocity Context is that
> you can put a lot of objects into the Context
> and give all them to HTML-XML-writer, then HTML-writer
> can do whatever he wants with those objects, or do nothing at all,
> whilst CPU time is spent only when he actually do something.
> Those objects in the Context can be thought of as a
> problem-oriented-language targeted at HTML-writer.

Ok

>
> This path, however, is not as convenient and efficient as it could be:
> A lot of objects in the Context might need to use some context-specific
> information, such as session, specific request parameters,
> or something else put into the Context by someone.

When you say 'context specific', I assume you mean 'application context 
specific'.  Yes, I agree, and that is what many people include when 
they talk of the data model or just model that your application works 
with.

> And there is only a few ways for the object to receive this
> information. One is to synchronize access to all objects in the
> Context as a whole, that is, only one Velocity Context
> might be merged into template at the time, so that we
> can just give the Context to all the objects before merging it.

I don't understand.

> Other is for every new Context to create all the objects
> from scratch and give the Context to each object thru object's
> constructor. (I'll be glad to hear of another ways to accoplish this).

I see now what you mean by the first part.

Using threadsafe objects is another way - create one set and put in a 
context that you wrap :

   VelocityContext commonContext = new VelocityContext();
   commonContext.put("request", httpServletRequest);
   ....

   VelocityContext myContext = new VelocityContext(commonContext);

and then you can access the stuff in the template :


    $mytool.doSomething($request.getParameter("foobar"))

etc...

> Described methods are surely inconvenient.
> The first kills concurency and may produce user-visible hangs.

Possible.

> The second forces us to recreat all the objects in the Context,
> which is not at all efficient, becouse memory allocation is never
> cheap and objects might have some heavy initializers in constructors
> or do some internal caching, which is humped when we recreate them,
> and it is neither convenient nor efficient when we have to
> create proxies to objects whoes number of instances should be limited,
> instead of just placing those objects into the Context.
>
> I came to simple solution for this problem
> by giving the Context thru the hidden parameter of a method:
> If method exists without hidden Context parameter,
> then it is executed as usual, but if no such method exists,
> then I check for a method with the same parameters plus the hidden
> Context parameter, and if it is present, it is executed receiving
> the current Context.

I don't see how this solves it.  If you are worried about concurrent 
access to objects in the context, then you have to be worried with this 
approach too.

Also, since you are now making your object 'Velocity context aware', 
why not just :

a) Put the context into the context :

       myContext.put("context", myContext);

    and ask your template designers to pass in the context :

        $myThingy.doSomething($context, $whatever)

or

b) more simply, to keep the load of your designers and reduce the 
surface areas of your APIs by not having methods that take the context 
also, and since your objects are context aware, just add the context at 
creation time :

     myContext.put("myThingy", new Thingy(myContext));


> Thus shared objects can be put into Velocity Context and remain there,
> and a big part of a context can be shared thru the context chaining,
> with only dynamically changed values, such as session,
> placed into the each-time-allocated Context.

Which you can do above.

>
> Attached (as a demo) are my patches for "velocity-1.3.1".
> If someone is interested and want to reimplement it for the mainline,
> great. If someone is still interested, but have no time to implement,
> there is a chance that I will try to write a better patch
> for velocity-1.4.1-rc1, which, perhaps, should be more integrated,
> becouse of Uberspect.
> Although I don't know, yet, how the ASTMethod is generated.

Before you spend more time, can you explain why the above suggestions 
don't solve the problem?

geir

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: velocity-dev-help@jakarta.apache.org
>
-- 
Geir Magnusson Jr                                   203-247-1713(m)
geir@4quarters.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org