001
014
015 package com.liferay.portal.cache.ehcache;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.GetterUtil;
020 import com.liferay.portal.kernel.util.InitialThreadLocal;
021
022 import java.util.ArrayList;
023 import java.util.List;
024 import java.util.Properties;
025
026 import net.sf.ehcache.CacheException;
027 import net.sf.ehcache.Ehcache;
028 import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
029
030
034 public class EhcacheStreamBootstrapCacheLoader implements BootstrapCacheLoader {
035
036 public static void resetSkip() {
037 _skipBootstrapThreadLocal.remove();
038 }
039
040 public static void setSkip() {
041 _skipBootstrapThreadLocal.set(Boolean.TRUE);
042 }
043
044 public static synchronized void start() {
045 if (!_started) {
046 _started = true;
047 }
048
049 if (_log.isDebugEnabled()) {
050 _log.debug("Loading deferred caches");
051 }
052
053 try {
054 EhcacheStreamBootstrapHelpUtil.loadCachesFromCluster(
055 true,
056 _deferredEhcaches.toArray(
057 new Ehcache[_deferredEhcaches.size()]));
058 }
059 catch (Exception e) {
060 throw new CacheException(e);
061 }
062 finally {
063 _deferredEhcaches.clear();
064 }
065 }
066
067 public EhcacheStreamBootstrapCacheLoader(Properties properties) {
068 if (properties != null) {
069 _bootstrapAsynchronously = GetterUtil.getBoolean(
070 properties.getProperty("bootstrapAsynchronously"));
071 }
072 }
073
074 @Override
075 public Object clone() {
076 return this;
077 }
078
079 public void doLoad(Ehcache ehcache) {
080 synchronized (EhcacheStreamBootstrapCacheLoader.class) {
081 if (!_started) {
082 _deferredEhcaches.add(ehcache);
083
084 return;
085 }
086 }
087
088 if (_skipBootstrapThreadLocal.get()) {
089 return;
090 }
091
092 if (_log.isDebugEnabled()) {
093 _log.debug("Bootstraping " + ehcache.getName());
094 }
095
096 try {
097 EhcacheStreamBootstrapHelpUtil.loadCachesFromCluster(
098 false, ehcache);
099 }
100 catch (Exception e) {
101 throw new CacheException(e);
102 }
103 }
104
105 @Override
106 public boolean isAsynchronous() {
107 return _bootstrapAsynchronously;
108 }
109
110 @Override
111 public void load(Ehcache ehcache) {
112 if (_bootstrapAsynchronously) {
113 EhcacheStreamClientThread streamBootstrapThread =
114 new EhcacheStreamClientThread(ehcache);
115
116 streamBootstrapThread.start();
117 }
118 else {
119 doLoad(ehcache);
120 }
121 }
122
123 private static Log _log = LogFactoryUtil.getLog(
124 EhcacheStreamBootstrapCacheLoader.class);
125
126 private static List<Ehcache> _deferredEhcaches = new ArrayList<Ehcache>();
127 private static ThreadLocal<Boolean> _skipBootstrapThreadLocal =
128 new InitialThreadLocal<Boolean>(
129 EhcacheStreamBootstrapCacheLoader.class +
130 "._skipBootstrapThreadLocal",
131 false);
132 private static boolean _started;
133
134 private boolean _bootstrapAsynchronously = true;
135
136 private class EhcacheStreamClientThread extends Thread {
137
138 public EhcacheStreamClientThread(Ehcache ehcache) {
139 if (_log.isDebugEnabled()) {
140 _log.debug(
141 "Ehcache stream client thread for cache " +
142 ehcache.getName());
143 }
144
145 _ehcache = ehcache;
146
147 setDaemon(true);
148 setName(
149 EhcacheStreamClientThread.class.getName() + " - " +
150 ehcache.getName());
151 setPriority(Thread.NORM_PRIORITY);
152 }
153
154 @Override
155 public void run() {
156 try {
157 doLoad(_ehcache);
158 }
159 catch (Exception e) {
160 if (_log.isWarnEnabled()) {
161 _log.warn("Unable to asynchronously stream bootstrap", e);
162 }
163 }
164 }
165
166 private Ehcache _ehcache;
167
168 }
169
170 }