You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Raymond <pp...@hotmail.com> on 2005/03/12 08:24:41 UTC
strange bug: global created twice
Hi Tapestry Users,
There's a strange bug happening with our production Tapestry app (it never
happened in the testing environment).
The log file of the app shows that the Global object was created twice
(actually the "protected engine.createGlobal(cycle)" method was called
twice, sometimes even called many times) when the app was initializing. The
extra Global object was found to die after 10 hours (by seeing the log
statement in the Global object's finalize() method). And the webapp
continues to run normally. But some internal states were messed up because
we use the global object's private fields to store many application states
and datetime value for various periodic jobs.
Our production environment is quite busy and whenever the app is undeployed
and redeployed for a few minutes we could see in the Tomcat log many failed
requests. So I suspect perhaps the problem was the webapp received several
concurrent requests before it fully initialized itself when the app was
creating the Engine object. So createGlobal might be called twice and the 2
global objects may be used by different threads. A global object died when
no more thread was referencing it.
We are using Tomcat 5.028 with jdk 1.4.2_06 on a qutie slow machine.
Has anyone experienced similar problem? Does it mean that the createGlobal
method is not thread-safe? Any solution?
Thanks very much for help.
Raymond
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: strange bug: global created twice
Posted by Hanson Char <ha...@gmail.com>.
The proposed quick fix can be further optimized by moving the
servletContext.setAttribute outside the synchronized block:
private final int[] LOCK_GLOBAL = {};
protected void setupForRequest(RequestContext context)
{
...
boolean isGlobalCreated = false;
synchronized(LOCK_GLOBAL) {
if (_global == null)
{
_global = createGlobal(context);
isGlobalCreated = true;
}
}
if (isGlobalCreated) {
String name = GLOBAL_NAME + ":" + servletName;
servletContext.setAttribute(name, _global);
}
...
}
public Object getGlobal()
{
synchronized(LOCK_GLOBAL) {
return _global;
}
}
H
On Sun, 13 Mar 2005 02:56:47 +1100, Hanson Char <ha...@gmail.com> wrote:
> Also, to be completely thread-safe, the AbstractEngine.getGlobal
> method also needs synchronization (to avoid the caller to ever get
> access to a partially initialized global object.)
>
> public Object getGlobal()
> {
> synchronized(LOCK_GLOBAL) {
> return _global;
> }
> }
>
> H
>
> On Sat, 12 Mar 2005 21:43:07 +1100, Hanson Char <ha...@gmail.com> wrote:
> > The logic within the synchronzied block can be further simplified into:
> >
> > synchronized(LOCK_GLOBAL) {
> > if (_global == null)
> > {
> > String name = GLOBAL_NAME + ":" + servletName;
> > _global = createGlobal(context);
> > servletContext.setAttribute(name, _global);
> > }
> > }
> >
> > H
> >
> > On Sat, 12 Mar 2005 21:33:24 +1100, Hanson Char <ha...@gmail.com> wrote:
> > > From a cursory look at the AbstractEngine.java of Tapestry 3.0.2, it
> > > does seem the initialization of _global is not thread-safe. A quick
> > > fix would be to add a lock and synchronize on it.
> > >
> > > Example:
> > >
> > > // add a lock monitor for _global
> > > private final int[] LOCK_GLOBAL = {};
> > >
> > > ...
> > > synchronized(LOCK_GLOBAL) {
> > > if (_global == null)
> > > {
> > > String name = GLOBAL_NAME + ":" + servletName;
> > >
> > > _global = servletContext.getAttribute(name);
> > >
> > > if (_global == null)
> > > {
> > > _global = createGlobal(context);
> > >
> > > servletContext.setAttribute(name, _global);
> > > }
> > > }
> > > }
> > >
> > > H
> > >
> > >
> > > On Sat, 12 Mar 2005 15:24:41 +0800, Raymond <pp...@hotmail.com> wrote:
> > > > Hi Tapestry Users,
> > > >
> > > > There's a strange bug happening with our production Tapestry app (it never
> > > > happened in the testing environment).
> > > >
> > > > The log file of the app shows that the Global object was created twice
> > > > (actually the "protected engine.createGlobal(cycle)" method was called
> > > > twice, sometimes even called many times) when the app was initializing. The
> > > > extra Global object was found to die after 10 hours (by seeing the log
> > > > statement in the Global object's finalize() method). And the webapp
> > > > continues to run normally. But some internal states were messed up because
> > > > we use the global object's private fields to store many application states
> > > > and datetime value for various periodic jobs.
> > > >
> > > > Our production environment is quite busy and whenever the app is undeployed
> > > > and redeployed for a few minutes we could see in the Tomcat log many failed
> > > > requests. So I suspect perhaps the problem was the webapp received several
> > > > concurrent requests before it fully initialized itself when the app was
> > > > creating the Engine object. So createGlobal might be called twice and the 2
> > > > global objects may be used by different threads. A global object died when
> > > > no more thread was referencing it.
> > > >
> > > > We are using Tomcat 5.028 with jdk 1.4.2_06 on a qutie slow machine.
> > > >
> > > > Has anyone experienced similar problem? Does it mean that the createGlobal
> > > > method is not thread-safe? Any solution?
> > > >
> > > > Thanks very much for help.
> > > > Raymond
> > > >
> > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > > > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> > > >
> > > >
> > >
> >
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: strange bug: global created twice
Posted by Hanson Char <ha...@gmail.com>.
Also, to be completely thread-safe, the AbstractEngine.getGlobal
method also needs synchronization (to avoid the caller to ever get
access to a partially initialized global object.)
public Object getGlobal()
{
synchronized(LOCK_GLOBAL) {
return _global;
}
}
H
On Sat, 12 Mar 2005 21:43:07 +1100, Hanson Char <ha...@gmail.com> wrote:
> The logic within the synchronzied block can be further simplified into:
>
> synchronized(LOCK_GLOBAL) {
> if (_global == null)
> {
> String name = GLOBAL_NAME + ":" + servletName;
> _global = createGlobal(context);
> servletContext.setAttribute(name, _global);
> }
> }
>
> H
>
> On Sat, 12 Mar 2005 21:33:24 +1100, Hanson Char <ha...@gmail.com> wrote:
> > From a cursory look at the AbstractEngine.java of Tapestry 3.0.2, it
> > does seem the initialization of _global is not thread-safe. A quick
> > fix would be to add a lock and synchronize on it.
> >
> > Example:
> >
> > // add a lock monitor for _global
> > private final int[] LOCK_GLOBAL = {};
> >
> > ...
> > synchronized(LOCK_GLOBAL) {
> > if (_global == null)
> > {
> > String name = GLOBAL_NAME + ":" + servletName;
> >
> > _global = servletContext.getAttribute(name);
> >
> > if (_global == null)
> > {
> > _global = createGlobal(context);
> >
> > servletContext.setAttribute(name, _global);
> > }
> > }
> > }
> >
> > H
> >
> >
> > On Sat, 12 Mar 2005 15:24:41 +0800, Raymond <pp...@hotmail.com> wrote:
> > > Hi Tapestry Users,
> > >
> > > There's a strange bug happening with our production Tapestry app (it never
> > > happened in the testing environment).
> > >
> > > The log file of the app shows that the Global object was created twice
> > > (actually the "protected engine.createGlobal(cycle)" method was called
> > > twice, sometimes even called many times) when the app was initializing. The
> > > extra Global object was found to die after 10 hours (by seeing the log
> > > statement in the Global object's finalize() method). And the webapp
> > > continues to run normally. But some internal states were messed up because
> > > we use the global object's private fields to store many application states
> > > and datetime value for various periodic jobs.
> > >
> > > Our production environment is quite busy and whenever the app is undeployed
> > > and redeployed for a few minutes we could see in the Tomcat log many failed
> > > requests. So I suspect perhaps the problem was the webapp received several
> > > concurrent requests before it fully initialized itself when the app was
> > > creating the Engine object. So createGlobal might be called twice and the 2
> > > global objects may be used by different threads. A global object died when
> > > no more thread was referencing it.
> > >
> > > We are using Tomcat 5.028 with jdk 1.4.2_06 on a qutie slow machine.
> > >
> > > Has anyone experienced similar problem? Does it mean that the createGlobal
> > > method is not thread-safe? Any solution?
> > >
> > > Thanks very much for help.
> > > Raymond
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> > >
> > >
> >
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: strange bug: global created twice
Posted by Hanson Char <ha...@gmail.com>.
The logic within the synchronzied block can be further simplified into:
synchronized(LOCK_GLOBAL) {
if (_global == null)
{
String name = GLOBAL_NAME + ":" + servletName;
_global = createGlobal(context);
servletContext.setAttribute(name, _global);
}
}
H
On Sat, 12 Mar 2005 21:33:24 +1100, Hanson Char <ha...@gmail.com> wrote:
> From a cursory look at the AbstractEngine.java of Tapestry 3.0.2, it
> does seem the initialization of _global is not thread-safe. A quick
> fix would be to add a lock and synchronize on it.
>
> Example:
>
> // add a lock monitor for _global
> private final int[] LOCK_GLOBAL = {};
>
> ...
> synchronized(LOCK_GLOBAL) {
> if (_global == null)
> {
> String name = GLOBAL_NAME + ":" + servletName;
>
> _global = servletContext.getAttribute(name);
>
> if (_global == null)
> {
> _global = createGlobal(context);
>
> servletContext.setAttribute(name, _global);
> }
> }
> }
>
> H
>
>
> On Sat, 12 Mar 2005 15:24:41 +0800, Raymond <pp...@hotmail.com> wrote:
> > Hi Tapestry Users,
> >
> > There's a strange bug happening with our production Tapestry app (it never
> > happened in the testing environment).
> >
> > The log file of the app shows that the Global object was created twice
> > (actually the "protected engine.createGlobal(cycle)" method was called
> > twice, sometimes even called many times) when the app was initializing. The
> > extra Global object was found to die after 10 hours (by seeing the log
> > statement in the Global object's finalize() method). And the webapp
> > continues to run normally. But some internal states were messed up because
> > we use the global object's private fields to store many application states
> > and datetime value for various periodic jobs.
> >
> > Our production environment is quite busy and whenever the app is undeployed
> > and redeployed for a few minutes we could see in the Tomcat log many failed
> > requests. So I suspect perhaps the problem was the webapp received several
> > concurrent requests before it fully initialized itself when the app was
> > creating the Engine object. So createGlobal might be called twice and the 2
> > global objects may be used by different threads. A global object died when
> > no more thread was referencing it.
> >
> > We are using Tomcat 5.028 with jdk 1.4.2_06 on a qutie slow machine.
> >
> > Has anyone experienced similar problem? Does it mean that the createGlobal
> > method is not thread-safe? Any solution?
> >
> > Thanks very much for help.
> > Raymond
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> >
> >
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
Re: strange bug: global created twice
Posted by Hanson Char <ha...@gmail.com>.
>From a cursory look at the AbstractEngine.java of Tapestry 3.0.2, it
does seem the initialization of _global is not thread-safe. A quick
fix would be to add a lock and synchronize on it.
Example:
// add a lock monitor for _global
private final int[] LOCK_GLOBAL = {};
...
synchronized(LOCK_GLOBAL) {
if (_global == null)
{
String name = GLOBAL_NAME + ":" + servletName;
_global = servletContext.getAttribute(name);
if (_global == null)
{
_global = createGlobal(context);
servletContext.setAttribute(name, _global);
}
}
}
H
On Sat, 12 Mar 2005 15:24:41 +0800, Raymond <pp...@hotmail.com> wrote:
> Hi Tapestry Users,
>
> There's a strange bug happening with our production Tapestry app (it never
> happened in the testing environment).
>
> The log file of the app shows that the Global object was created twice
> (actually the "protected engine.createGlobal(cycle)" method was called
> twice, sometimes even called many times) when the app was initializing. The
> extra Global object was found to die after 10 hours (by seeing the log
> statement in the Global object's finalize() method). And the webapp
> continues to run normally. But some internal states were messed up because
> we use the global object's private fields to store many application states
> and datetime value for various periodic jobs.
>
> Our production environment is quite busy and whenever the app is undeployed
> and redeployed for a few minutes we could see in the Tomcat log many failed
> requests. So I suspect perhaps the problem was the webapp received several
> concurrent requests before it fully initialized itself when the app was
> creating the Engine object. So createGlobal might be called twice and the 2
> global objects may be used by different threads. A global object died when
> no more thread was referencing it.
>
> We are using Tomcat 5.028 with jdk 1.4.2_06 on a qutie slow machine.
>
> Has anyone experienced similar problem? Does it mean that the createGlobal
> method is not thread-safe? Any solution?
>
> Thanks very much for help.
> Raymond
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org