Does raise an interesting point.

In a traditional page app, you would rarely have request overlap.  It
was possible (a wildly clicking user, perhaps).  Often the main page
would be one request, followed by a series of overlapping requests to
retrieve static assets.

It would be possible to add a filter to the page and component event
request chains that would single-thread requests for any specific
session.

That would raise some additional problems; for example, an earlier
user ran afoul of Tapestry's existing code (that single threads the
system periodically, to check to see if any resources on the file
system changed).  They had a window where process of one request would
"loop back" as a new request and thus two threads could end up
deadlocked.

So it does seem to me that if you are using Ajax techniques and thus
explicitly asynchronous access to the application, you should be
mindful of this.  We could bounce around some ideas as to how the
framework could assist: perhaps a per-session/per-page lock?

On Wed, Jul 9, 2008 at 2:36 PM, Martijn Brinkers <[EMAIL PROTECTED]> wrote:
> On one page I use a persistent Hashmap. The page contains an actionLink
> with a click event handler. The onclick event is activated with a delay
> using setTimeout. When the event is fired another actionLink is
> activated. Now what happens is that during the handling of the first
> actionLink the second actionLink is activated and this results in a
> ConcurrentModificationException on the Hashmap. I can solve it by using
> a multithread safe Hashmap but I want to understand under what
> circumstances you need to be carefull for multi threaded activation
> (with Tapestry 5 that is). Should a Persisted variable always be
> multithread safe?  I think so but what other Tapestry related items
> should be multithread safe as well?
>
> Martijn
>
> Stack trace:
>
> java.util.ConcurrentModificationException
> Stack trace
>              * java.util.HashMap
>                $HashIterator.nextEntry(HashMap.java:793)
>              * java.util.HashMap$KeyIterator.next(HashMap.java:828)
>              * 
> mitm.mimesecure.web.components.CertificateStoreGrid.downloadSelected(CertificateStoreGrid.java:76)
>              * 
> mitm.mimesecure.web.components.CertificateStoreGrid.dispatchComponentEvent(CertificateStoreGrid.java)
>              * 
> org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:864)
>              * 
> org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1025)
>              * 
> org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.handle(ComponentEventRequestHandlerImpl.java:67)
>              * 
> org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.handle(ImmediateActionRenderResponseFilter.java:42)
>              * 
> org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
>              * org.apache.tapestry5.services.TapestryModule
>                $37.handle(TapestryModule.java:1987)
>              * 
> org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:135)
>              * org.apache.tapestry5.services.TapestryModule
>                $12.service(TapestryModule.java:938)
>              * 
> org.apache.tapestry5.internal.services.LocalizationFilter.service(LocalizationFilter.java:42)
>              * org.apache.tapestry5.services.TapestryModule
>                $2.service(TapestryModule.java:586)
>              * 
> org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
>              * 
> org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:79)
>              * 
> org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:93)
>              * 
> org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:84)
>              * 
> org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:75)
>              * 
> org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:106)
>              * org.apache.tapestry5.services.TapestryModule
>                $11.service(TapestryModule.java:918)
>              * 
> org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
>              * 
> org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
>              * 
> org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:168)
>              * org.mortbay.jetty.servlet.ServletHandler
>                $CachedChain.doFilter(ServletHandler.java:1084)
>              * 
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
>              * 
> org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>              * 
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
>              * 
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
>              * 
> org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
>              * 
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>              * org.mortbay.jetty.Server.handle(Server.java:324)
>              * 
> org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
>              * org.mortbay.jetty.HttpConnection
>                $RequestHandler.headerComplete(HttpConnection.java:828)
>              * org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
>              * 
> org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
>              * 
> org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
>              * 
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
>              * org.mortbay.thread.BoundedThreadPool
>                $PoolThread.run(BoundedThreadPool.java:450)
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to