We did some load testing on our clustered dev CAS servers backed by JpaTicketRegistry to investigate the performance problems others have mentioned can be caused by DefaultTicketRegistryCleaner, http://www.nabble.com/DefaultTicketRegistryCleaner---spikes-under-DB-load-td20200644.html and http://www.nabble.com/MS-SQL-Server-backed-JPATicketRegistry-Deadlocks-td22853853.html. We did not experience deadlocks per se, but we did see application hangs that prevented users from authenticating. This is bad and we are interested in working on solution that we can contribute back to the core CAS codebase.
At first glance it appears a JpaTicketRegistryCleaner that does the following would be both simple and performant: public JpaTicketRegistryCleaner(final EntityManagerFactory factory) { final EntityManager entityManager = factory.createEntityManager(); this.deleteTGTQuery = entityManager.createQuery( "DELETE FROM TicketGrantingTicketImpl T " + "WHERE T.expired = true"); this.deleteSTQuery = entityManager.createQuery( "DELETE FROM ServiceTicketImpl T " + "WHERE T.expired = true"); } @Transactional public void clean() { this.deleteTGTQuery.executeUpdate(); this.deleteSTQuery.executeUpdate(); } Unfortunately the above could not work because the expired state is either not available in the database (service tickets) or does not always reflect the expired state (ticket-granting ticket). This is primarily due to the use of the strategy pattern to allow configurable ticket expiration policies in the AbstractTicket#isExpired() method. I would like to suggest that a simple boolean flag for ticket expiration state be maintained for all tickets, and that the isExpired() method simply return the boolean value. The AbstractTicket#updateState() method could continue to apply configurable ticket policy to update the expired flag, e.g.: protected final void updateState() { this.previousLastTimeUsed = this.lastTimeUsed; this.lastTimeUsed = System.currentTimeMillis(); this.countOfUses++; this.expired = this.expirationPolicy.isExpired(this) || (getGrantingTicket() != null && getGrantingTicket().isExpired()) || isExpiredInternal(); } Note that this solution would not require changes to the ticket interface or expiration policy design. The benefit of this approach is that the backing registry for tickets would have a simple flag that could be easily queried to determine whether a ticket could be safely deleted. This would facilitate the use case above as well as out-of-band SQL jobs to perform ticket cleanup. Please consider this and provide feedback. M -- You are currently subscribed to cas-dev@lists.jasig.org as: arch...@mail-archive.com To unsubscribe, change settings or access archives, see http://www.ja-sig.org/wiki/display/JSG/cas-dev