1 21 package org.jsmtpd.core.send; 22 23 import java.io.File ; 24 import java.io.FileFilter ; 25 import java.io.IOException ; 26 import java.util.Collections ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.jsmtpd.config.ReadConfig; 34 import org.jsmtpd.core.mail.Email; 35 36 44 public class QueueService { 45 46 49 private List <Email> directService = Collections.synchronizedList(new LinkedList <Email>()); 50 private static QueueService instance = null; 51 private String tempPath; 52 private File retryDir; 53 private File pendingDir; 54 private Log log = LogFactory.getLog(QueueService.class); 55 private boolean running = true; 56 private long retryDelay; 57 private long currentDiskSize = 0; 58 private long maxDiskSize = 0; 59 61 private int fastServ; 62 63 private boolean safeMode = false; 64 private String safeModePath = ""; 65 private FileFilter filter = new EmailFileFilter(); 66 67 public static synchronized QueueService getInstance() { 68 if (instance == null) 69 instance = new QueueService(); 70 return instance; 71 } 72 73 78 public synchronized boolean queueMail(Email input) { 79 if (running == false) 80 return false; 81 log.debug("Queuing new mail "+input.getDiskName()+", Disk usage "+getStorageStats()); 82 if (safeMode) { 84 try { 85 Email.save(safeModePath + "/" + input.getDiskName(), input); 86 log.info("SafeMode on : written mail to " + safeModePath + "/" + input.getDiskName()); 87 } catch (IOException e) { 88 log.error("SafeMode on : can't write mail to " + safeModePath + "/" + input.getDiskName(), e); 89 } 90 } 91 if ((directService.size() < 20) && (input.getSize() < 512000)) { 93 directService.add(input); 94 return true; 95 } else { 96 if ((directService.size() < 5) && (input.getSize() > 512000)) { directService.add(input); 98 return true; 99 } else { 100 if ((currentDiskSize + input.getSize()) > maxDiskSize) { 101 log.warn("Can't store anymore incomming mails, storage size exceeded"); 102 return false; 103 } 104 try { 105 Email.save(tempPath + "mqueue/pending/" + input.getDiskName(), input); 106 File tmp = new File (tempPath + "mqueue/pending/" + input.getDiskName()); 107 currentDiskSize += tmp.length(); 108 return true; 109 } catch (IOException e) { 110 } 111 } 112 113 return false; 114 } 115 } 116 117 122 public synchronized boolean requeueMail(Email input) { 123 if (running == false) 124 return false; 125 log.debug("DSVC> Re-queuing new mail "+input.getDiskName()+", Disk usage "+getStorageStats()); 126 try { 127 input.increaseAttempts(); 128 Email.save(tempPath + "mqueue/retry/" + input.getDiskName(), input); 129 File tmp = new File (tempPath + "mqueue/retry/" + input.getDiskName()); 130 currentDiskSize += tmp.length(); 131 return true; 132 } catch (IOException e) { 133 134 } 135 return false; 136 } 137 138 143 public synchronized Email getEmail() { 144 149 if (running == false) 150 return null; 151 Email tmp = null; 152 tmp = pickRetry(); 153 if (tmp != null) 154 return tmp; 155 156 if (directService.size() > 0) { 157 tmp = (Email) directService.remove(0); 158 return tmp; 159 } 160 tmp = pickPending(); 161 if (tmp != null) 162 return tmp; 163 164 return null; 165 } 166 167 171 private Email pickPending() { 172 173 File [] pendingMails = pendingDir.listFiles(filter); 174 175 if ((pendingMails != null) && pendingMails.length != 0) { 176 try { 177 Email ret = Email.load(pendingMails[0].toString()); 178 currentDiskSize -= pendingMails[0].length(); 179 pendingMails[0].delete(); 180 return ret; 181 } catch (IOException e) { 182 File tmp = new File (tempPath + "/" + pendingMails[0].getName() + "-Bogus"); 183 pendingMails[0].renameTo(tmp); 184 log.error("Cant load mail " + pendingMails[0].toString() + ", error: " + e); 185 log.error("Mail moved to bogus"); 186 } 187 } 188 return null; 189 } 190 191 195 private Email pickRetry() { 196 File [] pendingMails = retryDir.listFiles(filter); 197 198 if (pendingMails != null) { 199 for (int i = 0; i < pendingMails.length; i++) { 200 long timeOffset = pendingMails[i].lastModified() + retryDelay; 201 if (timeOffset < System.currentTimeMillis()) { 202 try { 203 Email ret = Email.load(pendingMails[0].toString()); 204 currentDiskSize -= pendingMails[0].length(); 205 pendingMails[0].delete(); 206 return ret; 207 } catch (IOException e) { 208 File tmp = new File (tempPath + "/" + pendingMails[0].getName() + "-Bogus"); 209 pendingMails[0].renameTo(tmp); 210 log.error("Cant load mail " + pendingMails[0].toString() + ", error: " + e); 211 log.error("Mail moved to bogus"); 212 } 213 } 214 } 215 216 } 217 return null; 218 } 219 220 private QueueService() { 221 ReadConfig cfg = ReadConfig.getInstance(); 222 tempPath = cfg.getTempPath(); 223 retryDelay = cfg.getDelayRetry() * 60 * 1000; 224 retryDir = new File (tempPath + "/mqueue/retry"); 225 pendingDir = new File (tempPath + "/mqueue/pending"); 226 fastServ = cfg.getDMaxInstances() * 2; 227 log.debug("Buffer set to " + fastServ + " messages max for immediate processing"); 228 maxDiskSize = cfg.getMaxTemporarySize() * 1048576; 229 initDiskCount(new File (tempPath)); 230 log.debug("Storage usage "+getStorageStats()); 231 safeMode = cfg.getSafeMode(); 232 if (safeMode) 233 log.info("Safe Mode on"); 234 safeModePath = cfg.getSafeModePath(); 235 } 236 private String getStorageStats () { 237 String out = Math.round((float) currentDiskSize / 1048576) + "/" 238 + Math.round((float) maxDiskSize / 1048576) + " (in Mo)"; 239 return out; 240 } 241 private void initDiskCount(File input) { 242 if (input.isFile()) 243 currentDiskSize += input.length(); 244 else { 245 File [] sub = input.listFiles(); 246 for (int i = 0; i < sub.length; i++) { 247 File file = sub[i]; 248 initDiskCount(file); 249 } 250 } 251 } 252 253 public void shutdownService() { 254 running = false; 255 for (Iterator iter = directService.iterator(); iter.hasNext();) { 256 Email element = (Email) iter.next(); 257 try { 258 Email.save(tempPath + "mqueue/retry/" + element.getDiskName(), element); 259 log.debug("Shutdown : " + element.getDiskName() + " written to retry"); 260 } catch (IOException e) { 261 log.debug("Cant save mail on shutdown, mail " + element.getDiskName() + " is lost due to: " + e.getCause()); 262 } 263 } 264 } 265 266 } | Popular Tags |