PageRenderTime 27ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/core/src/main/java/org/torquebox/core/pool/SharedPool.java

https://gitlab.com/meetly/torquebox
Java | 256 lines | 127 code | 37 blank | 92 comment | 25 complexity | 48901d253cb3a16e73f06cbc82c37f2c MD5 | raw file
  1. /*
  2. * Copyright 2008-2013 Red Hat, Inc, and individual contributors.
  3. *
  4. * This is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU Lesser General Public License as
  6. * published by the Free Software Foundation; either version 2.1 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This software is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this software; if not, write to the Free
  16. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  17. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  18. */
  19. package org.torquebox.core.pool;
  20. import java.util.concurrent.atomic.AtomicInteger;
  21. import org.jboss.as.naming.context.NamespaceContextSelector;
  22. import org.jboss.logging.Logger;
  23. /**
  24. * A pool implementation that shares a single instance to all consumers.
  25. *
  26. * <p>
  27. * The pool may be primed with either an instance directly or by providing a
  28. * factory capable of creating the instance. In the case that a
  29. * {@link InstanceFactory} is used, exactly one instance will be created.
  30. * </p>
  31. *
  32. * @author Bob McWhirter <bmcwhirt@redhat.com>
  33. *
  34. * @param <T>
  35. * The poolable resource.
  36. */
  37. public class SharedPool<T> implements Pool<T> {
  38. protected Logger log = Logger.getLogger( getClass() );
  39. /**
  40. * Construct.
  41. */
  42. public SharedPool() {
  43. }
  44. /**
  45. * Construct with an instance factory.
  46. *
  47. * @param factory
  48. * The factory to create the initial instance.
  49. */
  50. public SharedPool(InstanceFactory<T> factory) {
  51. this.factory = factory;
  52. }
  53. /**
  54. * Construct with an instance.
  55. *
  56. * @param instance
  57. * The initial instance.
  58. */
  59. public SharedPool(T instance) {
  60. this.instance = instance;
  61. }
  62. /**
  63. * Set the pool name.
  64. *
  65. * @param name
  66. * The pool name.
  67. */
  68. public void setName(String name) {
  69. this.name = name;
  70. }
  71. /**
  72. * Retrieve the pool name.
  73. *
  74. * @return The pool name.
  75. */
  76. public String getName() {
  77. return this.name;
  78. }
  79. /**
  80. * Set the shared instance.
  81. *
  82. * @param instance
  83. * The initial instance.
  84. */
  85. public void setInstance(T instance) {
  86. this.instance = instance;
  87. }
  88. /**
  89. * Retrieve the shared instance.
  90. *
  91. * @return The shared instance.
  92. */
  93. public T getInstance() {
  94. return this.instance;
  95. }
  96. /**
  97. * Set the instance factory to create the initial instance.
  98. *
  99. * @param factory
  100. * The instance factory.
  101. */
  102. public void setInstanceFactory(InstanceFactory<T> factory) {
  103. this.factory = factory;
  104. }
  105. /**
  106. * Retrieve the instance factory to create the initial instance.
  107. *
  108. * @return The instance factory;
  109. */
  110. public InstanceFactory<T> getInstanceFactory() {
  111. return this.factory;
  112. }
  113. public synchronized void startPool() throws Exception {
  114. if (this.instance == null) {
  115. this.instance = newInstance();
  116. }
  117. }
  118. protected T newInstance() throws Exception {
  119. if (this.nsContextSelector != null) {
  120. NamespaceContextSelector.pushCurrentSelector( this.nsContextSelector );
  121. }
  122. try {
  123. return factory.createInstance( getName() );
  124. } finally {
  125. if (this.nsContextSelector != null) {
  126. NamespaceContextSelector.popCurrentSelector();
  127. }
  128. }
  129. }
  130. public boolean isLazy() {
  131. return isDeferredUntilRequested();
  132. }
  133. public boolean isStarted() {
  134. return this.instance != null;
  135. }
  136. public boolean isDeferredUntilRequested() {
  137. return this.deferUntilRequested;
  138. }
  139. public void setDeferUntilRequested(boolean deferUntilRequested) {
  140. this.deferUntilRequested = deferUntilRequested;
  141. }
  142. /**
  143. * Create the pool.
  144. *
  145. * @throws Exception
  146. * if an error occurs starting the pool.
  147. */
  148. public synchronized void start() throws Exception {
  149. if (this.instance != null) {
  150. return;
  151. }
  152. if (this.factory == null) {
  153. throw new IllegalArgumentException( "Neither an instance nor an instance-factory provided." );
  154. }
  155. if (this.deferUntilRequested) {
  156. log.info( "Deferring start for " + this.name + " runtime pool." );
  157. } else {
  158. startPool();
  159. }
  160. }
  161. /**
  162. * Destroy the pool.
  163. */
  164. public synchronized void stop() {
  165. if (this.factory != null && this.instance != null) {
  166. this.factory.destroyInstance( this.instance );
  167. }
  168. this.instance = null;
  169. this.factory = null;
  170. log.info( "Stopped runtime pool " + this.name );
  171. }
  172. @Override
  173. public T borrowInstance(String requester) throws Exception {
  174. return borrowInstance( requester, 0 );
  175. }
  176. @Override
  177. public void releaseInstance(T instance) {
  178. if (instance == this.instance) {
  179. this.instanceCount.decrementAndGet();
  180. }
  181. }
  182. @Override
  183. public T borrowInstance(String requester, long timeout) throws Exception {
  184. if (this.instance == null) {
  185. synchronized(this) {
  186. startPool();
  187. long remaining = timeout;
  188. while (this.instance == null) {
  189. long startWait = System.currentTimeMillis();
  190. this.wait( timeout );
  191. remaining = remaining - (System.currentTimeMillis() - startWait);
  192. if (remaining <= 0) {
  193. return null;
  194. }
  195. }
  196. }
  197. }
  198. this.instanceCount.incrementAndGet();
  199. return this.instance;
  200. }
  201. public void setNamespaceContextSelector(NamespaceContextSelector nsContextSelector) {
  202. this.nsContextSelector = nsContextSelector;
  203. }
  204. public NamespaceContextSelector getNamespaceContextSelector() {
  205. return this.nsContextSelector;
  206. }
  207. public boolean isDrained() {
  208. return this.instanceCount.get() == 0;
  209. }
  210. /** Name of the pool. */
  211. private String name = "anonymous-pool";
  212. /** The shared instance. */
  213. private T instance;
  214. private AtomicInteger instanceCount = new AtomicInteger();
  215. /** Optional factory to create the initial instance. */
  216. private InstanceFactory<T> factory;
  217. private boolean deferUntilRequested = true;
  218. private NamespaceContextSelector nsContextSelector = null;
  219. }