src/org/sonews/util/Purger.java
author cli
Sun Sep 11 15:05:04 2011 +0200 (2011-09-11)
changeset 48 b78e77619152
parent 37 74139325d305
permissions -rwxr-xr-x
Merge Channel and Group classes.
     1 /*
     2  *   SONEWS News Server
     3  *   see AUTHORS for the list of contributors
     4  *
     5  *   This program is free software: you can redistribute it and/or modify
     6  *   it under the terms of the GNU General Public License as published by
     7  *   the Free Software Foundation, either version 3 of the License, or
     8  *   (at your option) any later version.
     9  *
    10  *   This program is distributed in the hope that it will be useful,
    11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  *   GNU General Public License for more details.
    14  *
    15  *   You should have received a copy of the GNU General Public License
    16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 package org.sonews.util;
    19 
    20 import java.util.Date;
    21 import java.util.List;
    22 import org.sonews.daemon.AbstractDaemon;
    23 import org.sonews.config.Config;
    24 import org.sonews.storage.Article;
    25 import org.sonews.storage.Headers;
    26 import org.sonews.storage.Group;
    27 import org.sonews.storage.StorageBackendException;
    28 import org.sonews.storage.StorageManager;
    29 
    30 /**
    31  * The purger is started in configurable intervals to search
    32  * for messages that can be purged. A message must be deleted if its lifetime
    33  * has exceeded, if it was marked as deleted or if the maximum number of
    34  * articles in the database is reached.
    35  * @author Christian Lins
    36  * @since sonews/0.5.0
    37  */
    38 public class Purger extends AbstractDaemon {
    39 
    40 	/**
    41 	 * Loops through all messages and deletes them if their time
    42 	 * has come.
    43 	 */
    44 	@Override
    45 	public void run() {
    46 		try {
    47 			while (isRunning()) {
    48 				purgeDeleted();
    49 				purgeOutdated();
    50 
    51 				Thread.sleep(120000); // Sleep for two minutes
    52 			}
    53 		} catch (StorageBackendException ex) {
    54 			ex.printStackTrace();
    55 		} catch (InterruptedException ex) {
    56 			Log.get().warning("Purger interrupted: " + ex);
    57 		}
    58 	}
    59 
    60 	private void purgeDeleted()
    61 			throws StorageBackendException {
    62 		List<Group> groups = StorageManager.current().getGroups();
    63 		for (Group channel : groups) {
    64 			if (!(channel instanceof Group)) {
    65 				continue;
    66 			}
    67 
    68 			Group group = (Group) channel;
    69 			// Look for groups that are marked as deleted
    70 			if (group.isDeleted()) {
    71 				List<Long> ids = StorageManager.current().getArticleNumbers(group.getInternalID());
    72 				if (ids.size() == 0) {
    73 					StorageManager.current().purgeGroup(group);
    74 					Log.get().info("Group " + group.getName() + " purged.");
    75 				}
    76 
    77 				for (int n = 0; n < ids.size() && n < 10; n++) {
    78 					Article art = StorageManager.current().getArticle(ids.get(n), group.getInternalID());
    79 					StorageManager.current().delete(art.getMessageID());
    80 					Log.get().info("Article " + art.getMessageID() + " purged.");
    81 				}
    82 			}
    83 		}
    84 	}
    85 
    86 	private void purgeOutdated()
    87 			throws InterruptedException, StorageBackendException {
    88 		long articleMaximum =
    89 				Config.inst().get("sonews.article.maxnum", Long.MAX_VALUE);
    90 		long lifetime =
    91 				Config.inst().get("sonews.article.lifetime", -1);
    92 
    93 		if (lifetime > 0 || articleMaximum < Stats.getInstance().getNumberOfNews()) {
    94 			Log.get().info("Purging old messages...");
    95 			String mid = StorageManager.current().getOldestArticle();
    96 			if (mid == null) // No articles in the database
    97 			{
    98 				return;
    99 			}
   100 
   101 			Article art = StorageManager.current().getArticle(mid);
   102 			long artDate = 0;
   103 			String dateStr = art.getHeader(Headers.DATE)[0];
   104 			try {
   105 				artDate = Date.parse(dateStr) / 1000 / 60 / 60 / 24;
   106 			} catch (IllegalArgumentException ex) {
   107 				Log.get().warning("Could not parse date string: " + dateStr + " " + ex);
   108 			}
   109 
   110 			// Should we delete the message because of its age or because the
   111 			// article maximum was reached?
   112 			if (lifetime < 0 || artDate < (new Date().getTime() + lifetime)) {
   113 				StorageManager.current().delete(mid);
   114 				System.out.println("Deleted: " + mid);
   115 			} else {
   116 				Thread.sleep(1000 * 60); // Wait 60 seconds
   117 				return;
   118 			}
   119 		} else {
   120 			Log.get().info("Lifetime purger is disabled");
   121 			Thread.sleep(1000 * 60 * 30); // Wait 30 minutes
   122 		}
   123 	}
   124 }