1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/org/sonews/util/Purger.java Sun Aug 29 17:28:58 2010 +0200
1.3 @@ -0,0 +1,149 @@
1.4 +/*
1.5 + * SONEWS News Server
1.6 + * see AUTHORS for the list of contributors
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, either version 3 of the License, or
1.11 + * (at your option) any later version.
1.12 + *
1.13 + * This program is distributed in the hope that it will be useful,
1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 + * GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License
1.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
1.20 + */
1.21 +
1.22 +package org.sonews.util;
1.23 +
1.24 +import org.sonews.daemon.AbstractDaemon;
1.25 +import org.sonews.config.Config;
1.26 +import org.sonews.storage.Article;
1.27 +import org.sonews.storage.Headers;
1.28 +import java.util.Date;
1.29 +import java.util.List;
1.30 +import org.sonews.storage.Channel;
1.31 +import org.sonews.storage.Group;
1.32 +import org.sonews.storage.StorageBackendException;
1.33 +import org.sonews.storage.StorageManager;
1.34 +
1.35 +/**
1.36 + * The purger is started in configurable intervals to search
1.37 + * for messages that can be purged. A message must be deleted if its lifetime
1.38 + * has exceeded, if it was marked as deleted or if the maximum number of
1.39 + * articles in the database is reached.
1.40 + * @author Christian Lins
1.41 + * @since sonews/0.5.0
1.42 + */
1.43 +public class Purger extends AbstractDaemon
1.44 +{
1.45 +
1.46 + /**
1.47 + * Loops through all messages and deletes them if their time
1.48 + * has come.
1.49 + */
1.50 + @Override
1.51 + public void run()
1.52 + {
1.53 + try
1.54 + {
1.55 + while(isRunning())
1.56 + {
1.57 + purgeDeleted();
1.58 + purgeOutdated();
1.59 +
1.60 + Thread.sleep(120000); // Sleep for two minutes
1.61 + }
1.62 + }
1.63 + catch(StorageBackendException ex)
1.64 + {
1.65 + ex.printStackTrace();
1.66 + }
1.67 + catch(InterruptedException ex)
1.68 + {
1.69 + Log.get().warning("Purger interrupted: " + ex);
1.70 + }
1.71 + }
1.72 +
1.73 + private void purgeDeleted()
1.74 + throws StorageBackendException
1.75 + {
1.76 + List<Channel> groups = StorageManager.current().getGroups();
1.77 + for(Channel channel : groups)
1.78 + {
1.79 + if(!(channel instanceof Group))
1.80 + continue;
1.81 +
1.82 + Group group = (Group)channel;
1.83 + // Look for groups that are marked as deleted
1.84 + if(group.isDeleted())
1.85 + {
1.86 + List<Long> ids = StorageManager.current().getArticleNumbers(group.getInternalID());
1.87 + if(ids.size() == 0)
1.88 + {
1.89 + StorageManager.current().purgeGroup(group);
1.90 + Log.get().info("Group " + group.getName() + " purged.");
1.91 + }
1.92 +
1.93 + for(int n = 0; n < ids.size() && n < 10; n++)
1.94 + {
1.95 + Article art = StorageManager.current().getArticle(ids.get(n), group.getInternalID());
1.96 + StorageManager.current().delete(art.getMessageID());
1.97 + Log.get().info("Article " + art.getMessageID() + " purged.");
1.98 + }
1.99 + }
1.100 + }
1.101 + }
1.102 +
1.103 + private void purgeOutdated()
1.104 + throws InterruptedException, StorageBackendException
1.105 + {
1.106 + long articleMaximum =
1.107 + Config.inst().get("sonews.article.maxnum", Long.MAX_VALUE);
1.108 + long lifetime =
1.109 + Config.inst().get("sonews.article.lifetime", -1);
1.110 +
1.111 + if(lifetime > 0 || articleMaximum < Stats.getInstance().getNumberOfNews())
1.112 + {
1.113 + Log.get().info("Purging old messages...");
1.114 + String mid = StorageManager.current().getOldestArticle();
1.115 + if (mid == null) // No articles in the database
1.116 + {
1.117 + return;
1.118 + }
1.119 +
1.120 + Article art = StorageManager.current().getArticle(mid);
1.121 + long artDate = 0;
1.122 + String dateStr = art.getHeader(Headers.DATE)[0];
1.123 + try
1.124 + {
1.125 + artDate = Date.parse(dateStr) / 1000 / 60 / 60 / 24;
1.126 + }
1.127 + catch (IllegalArgumentException ex)
1.128 + {
1.129 + Log.get().warning("Could not parse date string: " + dateStr + " " + ex);
1.130 + }
1.131 +
1.132 + // Should we delete the message because of its age or because the
1.133 + // article maximum was reached?
1.134 + if (lifetime < 0 || artDate < (new Date().getTime() + lifetime))
1.135 + {
1.136 + StorageManager.current().delete(mid);
1.137 + System.out.println("Deleted: " + mid);
1.138 + }
1.139 + else
1.140 + {
1.141 + Thread.sleep(1000 * 60); // Wait 60 seconds
1.142 + return;
1.143 + }
1.144 + }
1.145 + else
1.146 + {
1.147 + Log.get().info("Lifetime purger is disabled");
1.148 + Thread.sleep(1000 * 60 * 30); // Wait 30 minutes
1.149 + }
1.150 + }
1.151 +
1.152 +}