@@ -32,13 +32,13 @@ import groovy.util.logging.Slf4j
32
32
// @CompileStatic
33
33
@Slf4j
34
34
public class CacheManager {
35
- static final String CACHE_LOCATION = " .assetcache"
36
- static final Integer CACHE_DEBOUNCE_MS = 5000 // De-bounce 5 seconds
37
- static Map<String , Map<String , Object > > cache = [:]
35
+ static final String CACHE_LOCATION = " .assetcache"
36
+ static final Integer CACHE_DEBOUNCE_MS = 5000 // De-bounce 5 seconds
37
+ static Map<String , Map<String , Object > > cache = [:]
38
38
static String configCacheBustDigest
39
- static final Object LOCK_OBJECT = new Object ()
40
- static final Object LOCK_FETCH_OBJECT = new Object ()
41
- static CachePersister cachePersister
39
+ static final Object LOCK_OBJECT = new Object ()
40
+ static final Object LOCK_FETCH_OBJECT = new Object ()
41
+ static CachePersister cachePersister
42
42
43
43
/**
44
44
* Returns the cache string value of a file if it exists in the cache and is unmodified since last checked
@@ -47,39 +47,39 @@ public class CacheManager {
47
47
* @param originalFileName - Original file name of the file. This is for cache busting bundled assets
48
48
* @return A String value of the cache
49
49
*/
50
- public static Map<String ,Object > findCache (String fileName , String md5 , String originalFileName = null ) {
51
- loadPersistedCache()
50
+ public static Map<String , Object > findCache (String fileName , String md5 , String originalFileName = null ) {
51
+ loadPersistedCache()
52
52
checkCacheValidity()
53
53
def cacheRecord
54
- synchronized(LOCK_FETCH_OBJECT ) {
55
- cacheRecord = cache[fileName]
56
- if (cacheRecord && cacheRecord. md5 == md5 && cacheRecord. originalFileName == originalFileName) {
57
- def cacheFiles = cacheRecord. dependencies. keySet()
58
- def expiredCacheFound = cacheFiles. find { String cacheFileName ->
59
- def cacheFile = AssetHelper . fileForUri(cacheFileName)
60
- if (! cacheFile) {
61
- return true
62
- }
63
- def depMd5 = AssetHelper . getByteDigest(cacheFile. inputStream. bytes)
64
- if (cacheRecord. dependencies[cacheFileName] != depMd5) {
65
- return true
66
- }
67
- return false
68
- }
69
-
70
- if (expiredCacheFound) {
71
- cache. remove(fileName)
72
- asyncCacheSave()
73
- return null
74
- }
75
- return cacheRecord
76
- } else if (cacheRecord) {
77
- cache. remove(fileName)
78
- asyncCacheSave()
79
- return null
80
- }
81
- }
82
- }
54
+ synchronized (LOCK_FETCH_OBJECT ) {
55
+ cacheRecord = cache[fileName]
56
+ if (cacheRecord && cacheRecord. md5 == md5 && cacheRecord. originalFileName == originalFileName) {
57
+ def cacheFiles = cacheRecord. dependencies. keySet()
58
+ def expiredCacheFound = cacheFiles. find { String cacheFileName ->
59
+ def cacheFile = AssetHelper . fileForUri(cacheFileName)
60
+ if (! cacheFile) {
61
+ return true
62
+ }
63
+ def depMd5 = AssetHelper . getByteDigest(cacheFile. inputStream. bytes)
64
+ if (cacheRecord. dependencies[cacheFileName] != depMd5) {
65
+ return true
66
+ }
67
+ return false
68
+ }
69
+
70
+ if (expiredCacheFound) {
71
+ cache. remove(fileName)
72
+ asyncCacheSave()
73
+ return null
74
+ }
75
+ return cacheRecord
76
+ } else if (cacheRecord) {
77
+ cache. remove(fileName)
78
+ asyncCacheSave()
79
+ return null
80
+ }
81
+ }
82
+ }
83
83
84
84
/**
85
85
* Creates a cache entry for a file. This includes a name, md5Hash and processed file text
@@ -88,142 +88,152 @@ public class CacheManager {
88
88
* @param processedFileText The processed text of the file being cached
89
89
* @param originalFileName The original file name of the base file being persisted
90
90
*/
91
- public static void createCache (String fileName , String md5Hash , String processedFileText , String originalFileName = null ) {
92
- synchronized(LOCK_FETCH_OBJECT ) {
93
- loadPersistedCache()
94
- checkCacheValidity()
95
- def thisCache = cache
96
- def cacheRecord = thisCache[fileName]
97
- if (cacheRecord) {
98
- thisCache[fileName] = cacheRecord + [
99
- md5 : md5Hash,
100
- originalFileName : originalFileName,
101
- processedFileText : processedFileText
102
- ]
103
- } else {
104
- thisCache[fileName] = [
105
- md5 : md5Hash,
106
- originalFileName : originalFileName,
107
- processedFileText : processedFileText,
108
- requireModules : [:],
109
- dependencies : [:]
110
- ]
111
- }
112
- asyncCacheSave()
113
- }
114
- }
91
+ public static void createCache (String fileName , String md5Hash , String processedFileText , String originalFileName = null ) {
92
+ synchronized (LOCK_FETCH_OBJECT ) {
93
+ loadPersistedCache()
94
+ checkCacheValidity()
95
+ def thisCache = cache
96
+ def cacheRecord = thisCache[fileName]
97
+ if (cacheRecord) {
98
+ thisCache[fileName] = cacheRecord + [
99
+ md5 : md5Hash,
100
+ originalFileName : originalFileName,
101
+ processedFileText : processedFileText
102
+ ]
103
+ } else {
104
+ thisCache[fileName] = [
105
+ md5 : md5Hash,
106
+ originalFileName : originalFileName,
107
+ processedFileText : processedFileText,
108
+ requireModules : [:],
109
+ dependencies : [:]
110
+ ]
111
+ }
112
+ asyncCacheSave()
113
+ }
114
+ }
115
115
116
116
/**
117
117
* Called during asset processing to add a dependent file to another file cache. This allows for cache busting on
118
118
* things like imported less files or sass files.
119
119
* @param fileName The name of the file we are adding a dependency to
120
120
* @param dependentFile the AssetFile object we are adding as a dependency
121
121
*/
122
- public static void addCacheDependency (String fileName , AssetFile dependentFile ) {
123
- synchronized(LOCK_FETCH_OBJECT ) {
124
- def cacheRecord = cache[fileName]
125
- if (! cacheRecord) {
126
- createCache(fileName, null , null )
127
- cacheRecord = cache[fileName]
128
- }
129
-
130
- def newMd5 = dependentFile. getByteDigest()
131
- cacheRecord. dependencies[dependentFile. path] = newMd5
132
- asyncCacheSave()
133
- }
134
- }
135
-
136
-
137
- /**
122
+ public static void addCacheDependency (String fileName , AssetFile dependentFile ) {
123
+ synchronized (LOCK_FETCH_OBJECT ) {
124
+ def cacheRecord = cache[fileName]
125
+ if (! cacheRecord) {
126
+ createCache(fileName, null , null )
127
+ cacheRecord = cache[fileName]
128
+ }
129
+
130
+ def newMd5 = dependentFile. getByteDigest()
131
+ cacheRecord. dependencies[dependentFile. path] = newMd5
132
+ asyncCacheSave()
133
+ }
134
+ }
135
+
136
+
137
+ /**
138
138
* Called during asset processing to add a dependent module processed to the cache path.
139
139
* @param fileName The name of the file we are adding a dependency to
140
140
* @param moduleName The name of the module we are caching along side
141
141
* @param dependentModuleContent the AssetFile object we are adding as a dependency
142
142
*/
143
- public static void addCacheModule (String fileName , String moduleName , String dependentModuleContent ) {
144
- synchronized(LOCK_FETCH_OBJECT ) {
145
- def cacheRecord = cache[fileName]
146
- if (! cacheRecord) {
147
- createCache(fileName, null , null )
148
- cacheRecord = cache[fileName]
149
- }
150
- cacheRecord. requireModules[moduleName] = dependentModuleContent
151
- asyncCacheSave()
152
- }
153
- }
143
+ public static void addCacheModule (String fileName , String moduleName , String dependentModuleContent ) {
144
+ synchronized (LOCK_FETCH_OBJECT ) {
145
+ def cacheRecord = cache[fileName]
146
+ if (! cacheRecord) {
147
+ createCache(fileName, null , null )
148
+ cacheRecord = cache[fileName]
149
+ }
150
+ cacheRecord. requireModules[moduleName] = dependentModuleContent
151
+ asyncCacheSave()
152
+ }
153
+ }
154
154
155
155
/**
156
156
* Asynchronously starts a thread used to persist the cache to disk
157
157
* It also performs a debounce behavior so rapid calls to the save do not cause repeat saves
158
158
*/
159
- public static void asyncCacheSave () {
160
- synchronized(LOCK_OBJECT ) {
161
- if (! cachePersister) {
162
- cachePersister = new CachePersister ()
163
- cachePersister. start()
164
- }
165
- }
166
- cachePersister. debounceSave(CACHE_DEBOUNCE_MS );
167
- }
159
+ public static void asyncCacheSave () {
160
+ synchronized (LOCK_OBJECT ) {
161
+ if (! cachePersister) {
162
+ cachePersister = new CachePersister ()
163
+ cachePersister. start()
164
+ }
165
+ }
166
+ cachePersister. debounceSave(CACHE_DEBOUNCE_MS );
167
+ }
168
168
169
169
/**
170
170
* Called by the async {@link CachePersister} class to save the cache map to disk
171
171
*/
172
- public static void save () {
173
- synchronized(LOCK_FETCH_OBJECT ) {
174
- String cacheLocation = AssetPipelineConfigHolder . config?. cacheLocation ?: CACHE_LOCATION
175
- FileOutputStream fos = new FileOutputStream (cacheLocation);
176
- Map<String , Map<String , Object > > cacheSaveData = [configCacheBustDigest : configCacheBustDigest, cache : cache]
177
- ObjectOutputStream oos = new ObjectOutputStream (fos);
178
- oos. writeObject(cacheSaveData)
179
- oos. close()
180
- }
181
- }
182
-
183
- /**
184
- * Loads an Asset Cache dependency graph for asset-pipeline.
185
- * This is currently encoded in JSON
186
- *
187
- * If the asset cache file does not exist or a cache is already loaded, the cache store is not parsed.
188
- */
189
- public static void loadPersistedCache () {
190
- if (cache) {
191
- return ;
192
- }
193
- String cacheLocation = AssetPipelineConfigHolder . config?. cacheLocation ?: CACHE_LOCATION
194
- File assetFile = new File (cacheLocation)
195
- if (! assetFile. exists()) {
196
- return ;
197
- }
198
-
199
- try {
200
- FileInputStream fis = new FileInputStream (cacheLocation);
201
- ObjectInputStream ois = new ObjectInputStream (fis);
202
- def fileCache = ois. readObject()
203
- if (fileCache?. configCacheBustDigest) {
172
+ public static void save () {
173
+ synchronized (LOCK_FETCH_OBJECT ) {
174
+ String cacheLocation = AssetPipelineConfigHolder . config?. cacheLocation
175
+ if (! cacheLocation) {
176
+ log. warn(" Asset Pipeline Cache Location is not set. Using default location: {}" , CACHE_LOCATION )
177
+ cacheLocation = CACHE_LOCATION
178
+ }
179
+
180
+ FileOutputStream fos = new FileOutputStream (cacheLocation);
181
+ Map<String , Map<String , Object > > cacheSaveData = [configCacheBustDigest : configCacheBustDigest, cache : cache]
182
+ ObjectOutputStream oos = new ObjectOutputStream (fos);
183
+ oos. writeObject(cacheSaveData)
184
+ oos. close()
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Loads an Asset Cache dependency graph for asset-pipeline.
190
+ * This is currently encoded in JSON
191
+ *
192
+ * If the asset cache file does not exist or a cache is already loaded, the cache store is not parsed.
193
+ */
194
+ public static void loadPersistedCache () {
195
+ if (cache) {
196
+ return ;
197
+ }
198
+ String cacheLocation = AssetPipelineConfigHolder . config?. cacheLocation
199
+ if (! cacheLocation) {
200
+ log. warn(" Asset Pipeline Cache Location is not set. Using default location: {}" , CACHE_LOCATION )
201
+ cacheLocation = CACHE_LOCATION
202
+ }
203
+
204
+ File assetFile = new File (cacheLocation)
205
+ if (! assetFile. exists()) {
206
+ return ;
207
+ }
208
+
209
+ try {
210
+ FileInputStream fis = new FileInputStream (cacheLocation)
211
+ ObjectInputStream ois = new ObjectInputStream (fis);
212
+ def fileCache = ois. readObject()
213
+ if (fileCache?. configCacheBustDigest) {
204
214
configCacheBustDigest = fileCache. configCacheBustDigest
205
215
}
206
- if (fileCache?. cache) {
207
- fileCache. cache. each{ entry ->
216
+ if (fileCache?. cache) {
217
+ fileCache. cache. each { entry ->
208
218
cache[entry. key] = entry. value
209
219
}
210
220
}
211
221
212
- } catch (ex) {
213
- // If there is a parser error from a previous bad cache flush ignore it and move on
214
- }
215
-
216
- }
222
+ } catch (ex) {
223
+ // If there is a parser error from a previous bad cache flush ignore it and move on
224
+ }
225
+
226
+ }
217
227
218
228
/**
219
229
* Checks the config digest name to see if any configurations have changed.
220
230
* If they have the cache needs to be reset and marked as expired
221
231
*/
222
232
private static void checkCacheValidity () {
223
- if (configCacheBustDigest != AssetPipelineConfigHolder . getDigestString()) {
224
- synchronized(LOCK_FETCH_OBJECT ) {
225
- cache. clear()
226
- }
233
+ if (configCacheBustDigest != AssetPipelineConfigHolder . getDigestString()) {
234
+ synchronized (LOCK_FETCH_OBJECT ) {
235
+ cache. clear()
236
+ }
227
237
configCacheBustDigest = AssetPipelineConfigHolder . getDigestString()
228
238
}
229
239
}
0 commit comments