ASOs are specified in terms of implementation classes, not interfaces.
That makes it more awkward and error prone to create a proxy for them
(you have to create a subclass and hit all the non-private methods and
make them delegate, and there can be issues concerning constructors
that get in the way).

I'd prefer to find a solution, if necessary, that wrapped around all
the code paths that could be accessing a shared resource such as an
ASO.  One coarse lock, not many small (and potentially deadlocking)
ones.

On Wed, Jul 9, 2008 at 3:10 PM, Martijn Brinkers <[EMAIL PROTECTED]> wrote:
>
>> 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?
>
> A per-session/per-page lock still allows concurrent access to ASO's I
> guess?
> I think that making any 'globally' accessible objects (ie Persisted
> objects, ASO's...?) thread safe is the safest choice but I'm not sure if
> that works for everyone. Would it be possible to automatically create a
> thread safe wrapper (proxy) for a Persisted object (and ASO) that only
> allows single threaded access to that object? Trigger the auto wrapper
> when a specific annotation is added to the persisted object like
> @ThreadSafe (or something like that). You can then choose to make the
> object thread safe by yourself or let Tapestry make a thread safe
> wrapper for you.
>
> Martijn
>
> On Wed, 2008-07-09 at 14:48 -0700, Howard Lewis Ship wrote:
>> 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]
>> >
>> >
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> 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