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 (_deferredEhcaches.isEmpty()) {
050 return;
051 }
052
053 if (_log.isDebugEnabled()) {
054 _log.debug("Loading deferred caches");
055 }
056
057 try {
058 EhcacheStreamBootstrapHelpUtil.loadCachesFromCluster(
059 _deferredEhcaches.toArray(
060 new Ehcache[_deferredEhcaches.size()]));
061 }
062 catch (Exception e) {
063 throw new CacheException(e);
064 }
065 finally {
066 _deferredEhcaches.clear();
067 }
068 }
069
070 public EhcacheStreamBootstrapCacheLoader(Properties properties) {
071 if (properties != null) {
072 _bootstrapAsynchronously = GetterUtil.getBoolean(
073 properties.getProperty("bootstrapAsynchronously"));
074 }
075 }
076
077 @Override
078 public Object clone() {
079 return this;
080 }
081
082 public void doLoad(Ehcache ehcache) {
083 synchronized (EhcacheStreamBootstrapCacheLoader.class) {
084 if (!_started) {
085 _deferredEhcaches.add(ehcache);
086
087 return;
088 }
089 }
090
091 if (_skipBootstrapThreadLocal.get()) {
092 return;
093 }
094
095 if (_log.isDebugEnabled()) {
096 _log.debug("Bootstraping " + ehcache.getName());
097 }
098
099 try {
100 EhcacheStreamBootstrapHelpUtil.loadCachesFromCluster(ehcache);
101 }
102 catch (Exception e) {
103 throw new CacheException(e);
104 }
105 }
106
107 @Override
108 public boolean isAsynchronous() {
109 return _bootstrapAsynchronously;
110 }
111
112 @Override
113 public void load(Ehcache ehcache) {
114 if (_bootstrapAsynchronously) {
115 EhcacheStreamClientThread streamBootstrapThread =
116 new EhcacheStreamClientThread(ehcache);
117
118 streamBootstrapThread.start();
119 }
120 else {
121 doLoad(ehcache);
122 }
123 }
124
125 private static Log _log = LogFactoryUtil.getLog(
126 EhcacheStreamBootstrapCacheLoader.class);
127
128 private static List<Ehcache> _deferredEhcaches = new ArrayList<Ehcache>();
129 private static ThreadLocal<Boolean> _skipBootstrapThreadLocal =
130 new InitialThreadLocal<Boolean>(
131 EhcacheStreamBootstrapCacheLoader.class +
132 "._skipBootstrapThreadLocal",
133 false);
134 private static boolean _started;
135
136 private boolean _bootstrapAsynchronously = true;
137
138 private class EhcacheStreamClientThread extends Thread {
139
140 public EhcacheStreamClientThread(Ehcache ehcache) {
141 if (_log.isDebugEnabled()) {
142 _log.debug(
143 "Ehcache stream client thread for cache " +
144 ehcache.getName());
145 }
146
147 _ehcache = ehcache;
148
149 setDaemon(true);
150 setName(
151 EhcacheStreamClientThread.class.getName() + " - " +
152 ehcache.getName());
153 setPriority(Thread.NORM_PRIORITY);
154 }
155
156 @Override
157 public void run() {
158 try {
159 doLoad(_ehcache);
160 }
161 catch (Exception e) {
162 if (_log.isWarnEnabled()) {
163 _log.warn("Unable to asynchronously stream bootstrap", e);
164 }
165 }
166 }
167
168 private Ehcache _ehcache;
169
170 }
171
172 }