[ https://issues.apache.org/jira/browse/ISIS-2119?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Daniel Keir Haywood updated ISIS-2119: -------------------------------------- Summary: Increase timeout to avoid occasional exceptions when download Blobs (also fixed in "v1 maintenance") (was: Increase timeout to avoid occasional exceptions when download Blobs) > Increase timeout to avoid occasional exceptions when download Blobs (also > fixed in "v1 maintenance") > ----------------------------------------------------------------------------------------------------- > > Key: ISIS-2119 > URL: https://issues.apache.org/jira/browse/ISIS-2119 > Project: Isis > Issue Type: Bug > Affects Versions: 1.17.0 > Reporter: Daniel Keir Haywood > Assignee: Daniel Keir Haywood > Priority: Minor > Fix For: v1 maintenance, 2.0.0-M3 > > > On a slow connection, can get occasional exceptions when downloading a > blob... that the behaviour cannot be found on the entity: > {code} > org.apache.wicket.behavior.InvalidBehaviorIdException > Cannot find behavior with id '2' on component > 'org.apache.isis.viewer.wicket.ui.components.scalars.reference.ReferencePanel:theme:entityPageContainer:entity:rows:1:rowContents:2:col:rows:1:rowContents:1:col:tabGroups:1:panel:tabPanel:rows:1:rowContents:1:col:fieldSets:1:memberGroup:properties:1:property' > in page '[Page class = > org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage, id = 10, render > count = 1]'. Perhaps the behavior did not properly implement > getStatelessHint() and returned 'true' to indicate that it is stateless > instead of returning 'false' to indicate that it is stateful. > org.apache.wicket.Behaviors#getBehaviorById(Behaviors.java:316) > org.apache.wicket.Component#getBehaviorById(Component.java:4596) > org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:247) > org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:234) > org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:895) > org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64) > org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:265) > org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:222) > org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:293) > org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:261) > org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:203) > org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:284) > org.eclipse.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1621) > org.apache.isis.core.webapp.diagnostics.IsisLogOnExceptionFilter#doFilter(IsisLogOnExceptionFilter.java:52) > org.eclipse.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1621) > org.togglz.servlet.TogglzFilter#doFilter(TogglzFilter.java:100) > org.eclipse.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1621) > org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449) > org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365) > org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90) > org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83) > org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383) > org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362) > org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125) > org.eclipse.jetty.servlet.ServletHandler$CachedChain#doFilter(ServletHandler.java:1613) > org.eclipse.jetty.servlet.ServletHandler#doHandle(ServletHandler.java:541) > org.eclipse.jetty.server.handler.ScopedHandler#handle(ScopedHandler.java:143) > org.eclipse.jetty.security.SecurityHandler#handle(SecurityHandler.java:548) > org.eclipse.jetty.server.handler.HandlerWrapper#handle(HandlerWrapper.java:132) > org.eclipse.jetty.server.handler.ScopedHandler#nextHandle(ScopedHandler.java:190) > org.eclipse.jetty.server.session.SessionHandler#doHandle(SessionHandler.java:1593) > org.eclipse.jetty.server.handler.ScopedHandler#nextHandle(ScopedHandler.java:188) > org.eclipse.jetty.server.handler.ContextHandler#doHandle(ContextHandler.java:1239) > org.eclipse.jetty.server.handler.ScopedHandler#nextScope(ScopedHandler.java:168) > org.eclipse.jetty.servlet.ServletHandler#doScope(ServletHandler.java:481) > org.eclipse.jetty.server.session.SessionHandler#doScope(SessionHandler.java:1562) > org.eclipse.jetty.server.handler.ScopedHandler#nextScope(ScopedHandler.java:166) > org.eclipse.jetty.server.handler.ContextHandler#doScope(ContextHandler.java:1141) > org.eclipse.jetty.server.handler.ScopedHandler#handle(ScopedHandler.java:141) > org.eclipse.jetty.server.handler.HandlerWrapper#handle(HandlerWrapper.java:132) > org.eclipse.jetty.server.Server#handle(Server.java:564) > org.eclipse.jetty.server.HttpChannel#handle(HttpChannel.java:320) > org.eclipse.jetty.server.HttpConnection#onFillable(HttpConnection.java:251) > org.eclipse.jetty.io.AbstractConnection$ReadCallback#succeeded(AbstractConnection.java:279) > org.eclipse.jetty.io.FillInterest#fillable(FillInterest.java:110) > org.eclipse.jetty.io.ChannelEndPoint$2#run(ChannelEndPoint.java:124) > org.eclipse.jetty.util.thread.Invocable#invokePreferred(Invocable.java:122) > org.eclipse.jetty.util.thread.strategy.ExecutingExecutionStrategy#invoke(ExecutingExecutionStrategy.java:58) > org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume#produceConsume(ExecuteProduceConsume.java:201) > org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume#run(ExecuteProduceConsume.java:133) > org.eclipse.jetty.util.thread.QueuedThreadPool#runJob(QueuedThreadPool.java:672) > org.eclipse.jetty.util.thread.QueuedThreadPool$2#run(QueuedThreadPool.java:590) > java.lang.Thread#run(Thread.java:748) > {code} > There's not a lot to go on. > Inspecting the returned payload though, I discovered at the end: > {code} > <evaluate><![CDATA[(function(){setTimeout("window.location.href='./orders.Order:7975?24-1.IBehaviorListener.0-'", > 10);})();]]></evaluate> > {code} > which gave me the clue. The relevant code is in > ActionResultResponseHandlingStrategy: > {code} > SCHEDULE_HANDLER { > @Override > public void handleResults( > final ActionResultResponse resultResponse, > final IsisSessionFactory isisSessionFactory) { > final RequestCycle requestCycle = RequestCycle.get(); > AjaxRequestTarget target = > requestCycle.find(AjaxRequestTarget.class); > if (target == null) { > // non-Ajax request => just stream the Lob to the browser > // or if this is a no-arg action, there also will be no > parent for the component > > requestCycle.scheduleRequestHandlerAfterCurrent(resultResponse.getHandler()); > } else { > // otherwise, > // Ajax request => respond with a redirect to be able to > stream the Lob to the client > ResourceStreamRequestHandler scheduledHandler = > (ResourceStreamRequestHandler) resultResponse.getHandler(); > StreamAfterAjaxResponseBehavior streamingBehavior = new > StreamAfterAjaxResponseBehavior(scheduledHandler); > final Page page = target.getPage(); > page.add(streamingBehavior); > String callbackUrl = > streamingBehavior.getCallbackUrl().toString(); > target.appendJavaScript("setTimeout(\"window.location.href='" > + callbackUrl + "'\", 10);"); > } > } > }, > {code} > What's happening here is that response from the ajax call to invoke the > button is the fragments to rebuild the page ... it's not possible to also > return the BLOB. So the Ajax instead sets a timeout to download that Blob as > a separate web call. > Experimenting with this code, if the behaviour is stripped off (everything > after the "?") then the download doesn't occur; so this is needed. > Since I've seen the problem mostly with large docs and on a slow connection, > my guess is that this is some sort of race condition. Since we can wait a > bit more than 10ms, my suggestion is to increase the timeout to 250ms. > ~~~ > If this fails, then another idea might be to strip off any of the &hint-xxx > query args also. -- This message was sent by Atlassian Jira (v8.3.4#803005)