Mercurial > dive4elements > framework
comparison artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java @ 90:68285f7bc476
More javadoc.
artifacts/trunk@846 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 26 Mar 2010 17:59:50 +0000 |
parents | 8447467cef86 |
children | 730ff077a58c |
comparison
equal
deleted
inserted
replaced
89:d348fe1fd822 | 90:68285f7bc476 |
---|---|
13 | 13 |
14 import java.util.ArrayList; | 14 import java.util.ArrayList; |
15 import java.util.List; | 15 import java.util.List; |
16 | 16 |
17 /** | 17 /** |
18 * The database cleaner runs in background. It sleep for a configurable | |
19 * while and when it wakes up it removes outdated artifacts from the | |
20 * database. Outdated means that the the last access to the artifact | |
21 * is longer aga then the time to live of this artifact.<br> | |
22 * Before the artifact is finally removed from the system it is | |
23 * revived one last time an the #endOfLife() method of the artifact | |
24 * is called.<br> | |
25 * The artifact implementations may e.g. use this to remove some extrenal | |
26 * resources form the system. | |
27 * | |
18 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> | 28 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> |
19 */ | 29 */ |
20 public class DatabaseCleaner | 30 public class DatabaseCleaner |
21 extends Thread | 31 extends Thread |
22 { | 32 { |
33 /** | |
34 * Implementors of this interface are able to create a | |
35 * living artifact from a given byte array. | |
36 */ | |
23 public interface ArtifactReviver { | 37 public interface ArtifactReviver { |
24 | 38 |
39 /** | |
40 * Called to revive an artifact from a given byte array. | |
41 * @param factoryName The name of the factory which | |
42 * created this artifact. | |
43 * @param bytes The bytes of the serialized artifact. | |
44 * @return The revived artfiact. | |
45 */ | |
25 Artifact reviveArtifact(String factoryName, byte [] bytes); | 46 Artifact reviveArtifact(String factoryName, byte [] bytes); |
26 | 47 |
27 } // interface ArtifactReviver | 48 } // interface ArtifactReviver |
28 | 49 |
29 private static Logger logger = Logger.getLogger(DatabaseCleaner.class); | 50 private static Logger logger = Logger.getLogger(DatabaseCleaner.class); |
30 | 51 |
52 /** | |
53 * Number of artifacts to be loaded at once. Used to | |
54 * mitigate the problem of a massive denial of service | |
55 * if too many artifacts have died since last cleanup. | |
56 */ | |
31 public static final int MAX_ROWS = 50; | 57 public static final int MAX_ROWS = 50; |
32 | 58 |
59 /** | |
60 * The SQL statement to select the outdated artifacts. | |
61 */ | |
33 public static final String SQL_OUTDATED = | 62 public static final String SQL_OUTDATED = |
34 SQL.get("artifacts.outdated"); | 63 SQL.get("artifacts.outdated"); |
35 | 64 |
65 /** | |
66 * The SQL statement to delete some artifacts from the database. | |
67 */ | |
36 public static final String SQL_DELETE = | 68 public static final String SQL_DELETE = |
37 SQL.get("artifacts.delete"); | 69 SQL.get("artifacts.delete"); |
38 | 70 |
71 /** | |
72 * XPath to figure out how long the cleaner should sleep between | |
73 * cleanups. This is stored in the global configuration. | |
74 */ | |
39 public static final String SLEEP_XPATH = | 75 public static final String SLEEP_XPATH = |
40 "/artifact-database/cleaner/sleep-time/text()"; | 76 "/artifact-database/cleaner/sleep-time/text()"; |
41 | 77 |
78 /** | |
79 * Default nap time between cleanups: 5 minutes. | |
80 */ | |
42 public static final long SLEEP_DEFAULT = | 81 public static final long SLEEP_DEFAULT = |
43 5 * 60 * 1000L; // 5 minutes | 82 5 * 60 * 1000L; // 5 minutes |
44 | 83 |
84 /** | |
85 * The configured nap time. | |
86 */ | |
45 protected long sleepTime; | 87 protected long sleepTime; |
46 | 88 |
89 /** | |
90 * Internal locking mechanism to prevent some race conditions. | |
91 */ | |
47 protected Object sleepLock = new Object(); | 92 protected Object sleepLock = new Object(); |
48 | 93 |
94 /** | |
95 * A reference to the global context. | |
96 */ | |
49 protected Object context; | 97 protected Object context; |
50 | 98 |
99 /** | |
100 * A specialized Id filter which only delete some artifacts. | |
101 * This is used to prevent deletion of living artifacts. | |
102 */ | |
51 protected Id.Filter filter; | 103 protected Id.Filter filter; |
52 | 104 |
105 /** | |
106 * The reviver used to bring the dead artifact on last | |
107 * time back to live to call endOfLife() on them. | |
108 */ | |
53 protected ArtifactReviver reviver; | 109 protected ArtifactReviver reviver; |
54 | 110 |
111 /** | |
112 * Default constructor. | |
113 */ | |
55 public DatabaseCleaner() { | 114 public DatabaseCleaner() { |
56 } | 115 } |
57 | 116 |
117 /** | |
118 * Constructor to create a cleaner with a given global context | |
119 * and an given reviver. | |
120 * @param context The global context of the artifact database | |
121 * @param reviver The reviver to awake artifact one last time. | |
122 */ | |
58 public DatabaseCleaner(Object context, ArtifactReviver reviver) { | 123 public DatabaseCleaner(Object context, ArtifactReviver reviver) { |
59 setDaemon(true); | 124 setDaemon(true); |
60 sleepTime = getSleepTime(); | 125 sleepTime = getSleepTime(); |
61 this.context = context; | 126 this.context = context; |
62 this.reviver = reviver; | 127 this.reviver = reviver; |
63 } | 128 } |
64 | 129 |
130 /** | |
131 * Sets the filter that prevents deletion of living artifacts. | |
132 * Living artifacts are artifacts which are currently active | |
133 * inside the artifact database. Deleting them in this state | |
134 * would create severe internal problems. | |
135 * @param filter | |
136 */ | |
65 public void setFilter(Id.Filter filter) { | 137 public void setFilter(Id.Filter filter) { |
66 this.filter = filter; | 138 this.filter = filter; |
67 } | 139 } |
68 | 140 |
141 /** | |
142 * External hook to tell the cleaner to wake up before its | |
143 * regular nap time is over. This is the case when the artifact | |
144 * database finds an artifact which is already outdated. | |
145 */ | |
69 public void wakeup() { | 146 public void wakeup() { |
70 synchronized (sleepLock) { | 147 synchronized (sleepLock) { |
71 sleepLock.notify(); | 148 sleepLock.notify(); |
72 } | 149 } |
73 } | 150 } |
74 | 151 |
152 /** | |
153 * Fetches the sleep time from the global configuration. | |
154 * @return the time to sleep between database cleanups in ms. | |
155 */ | |
75 protected static long getSleepTime() { | 156 protected static long getSleepTime() { |
76 String sleepTimeString = Config.getStringXPath(SLEEP_XPATH); | 157 String sleepTimeString = Config.getStringXPath(SLEEP_XPATH); |
77 | 158 |
78 if (sleepTimeString == null) { | 159 if (sleepTimeString == null) { |
79 return SLEEP_DEFAULT; | 160 return SLEEP_DEFAULT; |
200 } | 281 } |
201 | 282 |
202 logger.info("artifacts removed: " + removedArtifacts); | 283 logger.info("artifacts removed: " + removedArtifacts); |
203 } | 284 } |
204 | 285 |
286 /** | |
287 * The main code of the cleaner. It sleeps for the configured | |
288 * nap time, cleans up the database, sleeps again and so on. | |
289 */ | |
290 @Override | |
205 public void run() { | 291 public void run() { |
206 logger.info("sleep time: " + sleepTime + "ms"); | 292 logger.info("sleep time: " + sleepTime + "ms"); |
207 for (;;) { | 293 for (;;) { |
208 cleanup(); | 294 cleanup(); |
209 long startTime = System.currentTimeMillis(); | 295 long startTime = System.currentTimeMillis(); |
222 logger.debug("Cleaner slept " + (stopTime - startTime) + "ms"); | 308 logger.debug("Cleaner slept " + (stopTime - startTime) + "ms"); |
223 } | 309 } |
224 } // for (;;) | 310 } // for (;;) |
225 } | 311 } |
226 } | 312 } |
227 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: | 313 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |