Hi Chris,

the RegistryProxy should work, we use something similar for a script editor
component with access to the Registry.
We don't use WebSockets, though, so the normal lifecycle applies.

With WebSockets, however, someone has to handle it manually.
Beware, I don't have any experience with Tapestry and WebSockets, so it's
more like an educated guess.

If you look at the Registry, it has a cleanupThread() method, which locks
the Registry and calls cleanup() on the delegates to PerThreadManager.

https://github.com/apache/tapestry-5/blob/5655dd7fcb0441971147670254dd54800b93f4c0/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java#L545

The PerThreadManager#cleanup() call is the one triggering
HibernateSessionManager#threadCleanup() to close the Session.

We had a similar issue with anything that needs to run outside a "normal"
HTTP "1 request == 1 Thread" environment, like using Quartz for job
scheduling.

With my limited WebSockets knowledge, I guess that you'd need to call
Registry#cleanupThread() or at least PerthreadManager#cleanup() after each
@OnMessage to ensure that Tapestry resets itself to a sensible state.

Cheers
Ben

On Wed, Jun 12, 2024 at 3:08 AM Christopher Dodunski (Tapestry) <
chrisfromtapes...@christopher.net.nz> wrote:

> Hi Ben,
>
> Thank you for those helpful suggestions!  You're right... debugging is
> tricky given the large number of moving parts. 😊
>
> I've made some progress since last writing.  By activating
> "hibernate.c3p0.debugUnreturnedConnectionStackTraces" within my
> Hibernate configuration I've been able to narrow down exactly which
> calls to HibernateCrudServiceDAO produce these leaked connections.  When
> this DAO service is invoked using dependency injection - as it is in
> most cases - connections do not get leaked.  So, for the most part the
> tapestry-hibernate module is working exactly as it should.
>
> Connections get leaked when the client is a desktop app that connects
> via WebSocket.  With such connections, Tomcat instantiates a concrete
> wrapper class found within the parent web application.  The constructor
> of this class acquires a particular Tapestry IoC service directly from
> the Tapestry registry (below is my RegistryProxy class which facilitates
> this).  Overall this approach has worked well, allowing the parent
> web-app to "push" updates out to external desktop clients via WebSocket.
>   Aside from the small issue of leaked DB connections - back end
> Hibernate sessions seemingly not closed when the front end WebSocket
> session is closed.  Perhaps there is something I can do within the
> onClose() of my wrapper class to resolve this?
>
> If, based on your better knowledge of Tapestry IoC, something springs to
> mind I'd be keen to hear it.
>
>
> public class RegistryProxy {
>
>      private static ServletContext context;
>
>
>      public static <T> T getService(Class<T> serviceInterface){
>          Registry registry =
> (Registry)context.getAttribute(TapestryFilter.REGISTRY_CONTEXT_NAME);
>          return registry.getService(serviceInterface);
>      }
>
>
>      //Called by TapestryContextListener
>      public static void setServletContext(ServletContext context){
>          RegistryProxy.context = context;
>      }
>
>      //Use this method to access context from any location
>      public static ServletContext getServletContext(){
>          return RegistryProxy.context;
>      }
> }
>
>
> Kind regards,
>
> Chris.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to