Java tutorial
/* Copyright (C) 2016 NTT DATA Corporation This program is free software; you can redistribute it and/or Modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ package com.clustercontrol.commons.util; import java.util.Calendar; import java.util.LinkedList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.persistence.sessions.SessionEvent; import org.eclipse.persistence.sessions.SessionEventAdapter; import org.eclipse.persistence.sessions.server.ConnectionPool; import org.eclipse.persistence.sessions.server.ServerSession; import com.clustercontrol.commons.util.DBConnectionPoolStats; import com.clustercontrol.commons.util.HinemosEntityManager; import com.clustercontrol.commons.util.JpaTransactionManager; import com.clustercontrol.maintenance.util.HinemosPropertyUtil; import com.clustercontrol.util.HinemosTime; /** * eclipselink?SessionEvent?????callback API? * SessionEventAdapter?SessionEventListener?? * * @see org.eclipse.persistence.sessions.SessionEventListener * @see org.eclipse.persistence.sessions.SessionEventAdapter */ public class JpaSessionEventListener extends SessionEventAdapter { private static final Log m_log = LogFactory.getLog(JpaSessionEventListener.class); private static final LinkedList<DBConnectionPoolStats> queue = new LinkedList<DBConnectionPoolStats>(); private static final Object queueUpdateLock = new Object(); private static int maxQueueSize = 12; private static long lastAddTime = 0; public JpaSessionEventListener() { if (queue.peekLast() == null) { setLastAddTime(HinemosTime.currentTimeMillis()); queue.addLast(new DBConnectionPoolStats(lastAddTime, 0)); m_log.debug("initialize queue."); } } private static void setLastAddTime(long time) { lastAddTime = time; } public LinkedList<DBConnectionPoolStats> getPoolStats() { LinkedList<DBConnectionPoolStats> copiedQueue = null; synchronized (queueUpdateLock) { copiedQueue = new LinkedList<DBConnectionPoolStats>(queue); } return copiedQueue; } /** * PUBLIC: * This event is raised on when using the server/client sessions. * This event is raised after a connection is acquired from a connection pool. */ public void postAcquireConnection(SessionEvent event) { m_log.debug("Connection acquired from connection pool"); if (m_log.isTraceEnabled()) { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); for (StackTraceElement element : elements) { m_log.trace("postAcquireConnection():" + element); } } } private static void setMaxQueueSize(int size) { maxQueueSize = size; } /** * PUBLIC: * This event is raised on when using the server/client sessions. * This event is raised before a connection is released into a connection pool. */ public void preReleaseConnection(SessionEvent event) { m_log.debug("Connection release to connection pool"); HinemosEntityManager em = null; em = (HinemosEntityManager) HinemosSessionContext.instance().getProperty(JpaTransactionManager.EM); if (em != null) { setMaxQueueSize(HinemosPropertyUtil .getHinemosPropertyNum("common.db.connectionpool.stats.threshold", Long.valueOf(12)) .intValue()); ServerSession ss = em.unwrap(ServerSession.class); // Hinemos 6.0???????????? // ???????????????????? for (ConnectionPool pool : ss.getConnectionPools().values()) { int used = (pool.getTotalNumberOfConnections() - pool.getConnectionsAvailable().size()); if (m_log.isDebugEnabled()) { m_log.debug("Pool name=" + pool.getName() + ", Used size=" + used + ", Free size=" + pool.getConnectionsAvailable().size()); m_log.debug("Initial=" + pool.getInitialNumberOfConnections() + ":Min=" + pool.getMinNumberOfConnections() + ":Max=" + pool.getMaxNumberOfConnections()); } // Min???? if (used > pool.getMinNumberOfConnections()) { if (m_log.isDebugEnabled()) m_log.info("update min setting:" + pool.getMinNumberOfConnections() + "->" + used + "/max(" + pool.getMaxNumberOfConnections() + ")"); pool.setMinNumberOfConnections(used); } // 1???????"X0"?????????????? // ?????????Min?(?????????) Calendar now = HinemosTime.getCalendarInstance(); Calendar comparetime = (Calendar) now.clone(); // ""???? comparetime.clear(); comparetime.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), now.get(Calendar.HOUR_OF_DAY), 0, 0); // ???1???????????(???) // comparetime.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), 0); synchronized (queueUpdateLock) { // ??"X0"??????("X0"?????)??? if (lastAddTime < comparetime.getTimeInMillis()) { if (m_log.isDebugEnabled()) m_log.debug("add queue:used=" + used); queue.addLast(new DBConnectionPoolStats(now.getTimeInMillis(), used)); lastAddTime = now.getTimeInMillis(); // ???? while (queue.size() > maxQueueSize) { if (m_log.isDebugEnabled()) m_log.debug( "remove queue: currentSize=" + queue.size() + ", maxSize=" + maxQueueSize); queue.removeFirst(); } // Min(??)????? int max = used; for (DBConnectionPoolStats stats : queue) { if (stats.getMaxUseCount() > max) max = stats.getMaxUseCount(); } if (m_log.isDebugEnabled()) m_log.debug("max use:" + max); if (pool.getMinNumberOfConnections() > max) { if (m_log.isDebugEnabled()) m_log.info("update min setting(from stats):" + pool.getMinNumberOfConnections() + "->" + used + "/max(" + pool.getMaxNumberOfConnections() + ")"); pool.setMinNumberOfConnections(max); } } // ????????? else if (used > queue.peekLast().getMaxUseCount()) { if (m_log.isDebugEnabled()) m_log.debug("update queue:used=" + used); queue.peekLast().setMaxUseInfo(now.getTimeInMillis(), used); } } } } if (m_log.isTraceEnabled()) { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); for (StackTraceElement element : elements) { m_log.trace("preReleaseConnection():" + element); } } } }