cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Adam Boyle <abo...@valsphere.com>
Subject ROP: detecting that my client connection has timed out
Date Fri, 08 Apr 2016 03:28:31 GMT
I have a rich client application that uses the Apache Cayenne Remote Object Persistence framework
to access and store data. Thus far I have been unable to find a graceful way of detecting
and handling a client connection timeout. A MissingSessionException is thrown on both the
client and server when an action is attempted after the session has timed out, but on the
client side this exception is caught and a stacktrace is printed to the console without propagating
out to the caller:

    Apr 07, 2016 2:48:48 PM org.apache.cayenne.remote.BaseConnection sendMessage
    INFO: --- Message 6: Query
    Apr 07, 2016 2:48:48 PM org.apache.cayenne.remote.BaseConnection sendMessage
    INFO: *** Message error for 6: Query - took 16 ms.
    org.apache.cayenne.remote.service.MissingSessionException: [v.4.0.M2 Feb 26 2015 08:16:32]
[v.4.0.M2 Feb 26 2015 08:16:32] No session associated with request.
        at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:127)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:180)
        at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:109)
        at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:396)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
        at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
        at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
        at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
        at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:499)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
        at java.lang.Thread.run(Thread.java:745)

Is there a simple way of detecting that the connection is dead so that I can prompt the user
to reconnect?

On a related note, what happens to the existing client ObjectContext objects that are in use
if the connection is able to be re-established? Are the uncommitted PersistentObjects previously
created in those contexts lost forever?

The only (hacky) solution I can think of is to actually run a keep-alive thread to periodically
send a low-latency query to Cayenne to keep the ROP session active and separately track application
activity and prompt the user to enter their password if a certain period of time has passed
with no activity. The problem that I see with an approach like that is that there are lots
of ways that activity could be missed, the application is not truly timing out, and it really
doesn't address the underlying problem which is that sessions need to time out for a reason
and there doesn't seem to be a way to detect such a timeout.

Thanks in advance for any help you can provide!
-Adam


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message