Author: dbkr
Date: 2006-05-05 19:55:39 +0000 (Fri, 05 May 2006)
New Revision: 8611
Added:
trunk/apps/fnmail/src/fnmail/MailLog.java
trunk/apps/fnmail/src/fnmail/utils/DateStringFactory.java
Modified:
trunk/apps/fnmail/src/fnmail/Contact.java
trunk/apps/fnmail/src/fnmail/MailFetcher.java
trunk/apps/fnmail/src/fnmail/MessageSender.java
trunk/apps/fnmail/src/fnmail/fcp/FCPConnection.java
trunk/apps/fnmail/src/fnmail/fcp/HighLevelFCPClient.java
trunk/apps/fnmail/src/fnmail/fcp/NoNodeConnectionException.java
Log:
Backwards incompatible change - use dates in the keys. Also fixes a bug that
stopped it from working if the node was shut down and started up again.
Modified: trunk/apps/fnmail/src/fnmail/Contact.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/Contact.java 2006-05-05 18:38:50 UTC (rev
8610)
+++ trunk/apps/fnmail/src/fnmail/Contact.java 2006-05-05 19:55:39 UTC (rev
8611)
@@ -1,55 +1,22 @@
package fnmail;
import java.io.File;
+import java.io.IOException;
import java.io.FileReader;
-import java.io.FileOutputStream;
import java.io.BufferedReader;
-import java.io.PrintWriter;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Iterator;
+import java.util.Date;
+import fnmail.utils.DateStringFactory;
+
public class Contact {
public static final String KEYFILE = "key";
- private static final String LOGFILE = "log";
-
+ private static final String LOGFILE_PREFIX = "log-";
+ private final File contact_dir;
private final File keyfile;
- private final File logfile;
- private HashMap messages;
- private int lastMessageId;
Contact(File dir) {
+ this.contact_dir = dir;
this.keyfile = new File(dir, KEYFILE);
- this.logfile = new File(dir, LOGFILE);
-
- this.lastMessageId = 0;
-
- this.messages = new HashMap();
-
- FileReader frdr;
- try {
- frdr = new FileReader(this.logfile);
-
-
- BufferedReader br = new BufferedReader(frdr);
- String line;
-
- while ( (line = br.readLine()) != null) {
- String[] parts = line.split("=");
-
- if (parts.length != 2) continue;
-
- int thisnum = Integer.parseInt(parts[0]);
- if (thisnum > this.lastMessageId)
- this.lastMessageId = thisnum;
- this.messages.put(new Integer(thisnum),
parts[1]);
- }
-
- frdr.close();
- } catch (IOException ioe) {
- return;
- }
}
public String getKey() throws IOException {
@@ -60,42 +27,24 @@
return key;
}
- public int getNextMessageId() {
- return this.lastMessageId + 1;
+ public MailLog getLog(String date) {
+ return new MailLog(new File(this.contact_dir, LOGFILE_PREFIX +
date));
}
- public void addMessage(int num, String checksum) {
- this.messages.put(new Integer(num), checksum);
- if (num > this.lastMessageId)
- this.lastMessageId = num;
- this.writeLogFile();
- }
-
- private void writeLogFile() {
- FileOutputStream fos;
- try {
- fos = new FileOutputStream(this.logfile);
- } catch (IOException ioe) {
- return;
- }
+ public void pruneLogs(Date keepafter) {
+ File[] files = contact_dir.listFiles();
- PrintWriter pw = new PrintWriter(fos);
-
- Iterator i = this.messages.entrySet().iterator();
- while (i.hasNext()) {
- Map.Entry e = (Map.Entry)i.next();
-
- Integer num = (Integer)e.getKey();
- String checksum = (String)e.getValue();
- pw.println(num.toString()+"="+checksum);
+ int i;
+ for (i = 0; i< files.length; i++) {
+ if (!files[i].getName().startsWith(LOGFILE_PREFIX))
+ continue;
+ Date logdate =
DateStringFactory.DateFromKeyString(files[i].getName().substring(LOGFILE_PREFIX.length()));
+ if (logdate == null) {
+ // couldn't parse the date... hmm
+ files[i].delete();
+ } else if (logdate.before(keepafter)) {
+ files[i].delete();
+ }
}
-
- pw.flush();
-
- try {
- fos.close();
- } catch (IOException ioe) {
- return;
- }
}
}
Modified: trunk/apps/fnmail/src/fnmail/MailFetcher.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/MailFetcher.java 2006-05-05 18:38:50 UTC
(rev 8610)
+++ trunk/apps/fnmail/src/fnmail/MailFetcher.java 2006-05-05 19:55:39 UTC
(rev 8611)
@@ -2,6 +2,7 @@
import fnmail.fcp.FCPConnection;
import fnmail.fcp.HighLevelFCPClient;
+import fnmail.utils.DateStringFactory;
import java.io.File;
import java.io.IOException;
@@ -10,6 +11,8 @@
import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Calendar;
+import java.util.TimeZone;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -18,6 +21,9 @@
private File contact_dir;
private final FCPConnection fcpconn;
private final SimpleDateFormat sdf;
+ private static final int POLL_AHEAD = 3;
+ private static int PASSES_PER_DAY = 3;
+ private static int MAX_DAYS_BACK = 30;
MailFetcher(MessageBank m, File ctdir, FCPConnection fcpc) {
this.mb = m;
@@ -36,21 +42,42 @@
}
private void fetch_from(Contact contact) {
+ int i;
+ for (i = 1 - MAX_DAYS_BACK; i <= 0; i++) {
+ String datestr =
DateStringFactory.getOffsetKeyString(i);
+ MailLog log = contact.getLog(datestr);
+
+ if (log.getPasses() < PASSES_PER_DAY) {
+ this.fetch_day(contact, log, datestr);
+ // don't count passes for today since more
+ // mail may arrive
+ if (i < 0) log.incPasses();
+ }
+ }
+
+ TimeZone gmt = TimeZone.getTimeZone("GMT");
+ Calendar cal = Calendar.getInstance(gmt);
+ cal.setTime(new Date());
+
+ cal.add(Calendar.DAY_OF_MONTH, 0 - MAX_DAYS_BACK);
+ contact.pruneLogs(cal.getTime());
+ }
+
+ public void fetch_day(Contact contact, MailLog log, String date) {
HighLevelFCPClient fcpcli;
fcpcli = new HighLevelFCPClient(this.fcpconn);
-
String keybase;
try {
- keybase = contact.getKey();
+ keybase = contact.getKey() + date + "-";
} catch (IOException ioe) {
// Jinkies, Scoob! No key!
return;
}
- int startnum = contact.getNextMessageId();
+ int startnum = log.getNextMessageId();
- for (int i = startnum; i < startnum + 3; i++) {
+ for (int i = startnum; i < startnum + POLL_AHEAD; i++) {
System.out.println("trying to fetch "+keybase+i);
@@ -59,7 +86,7 @@
if (result != null) {
try {
String checksum =
this.storeMessage(result);
- contact.addMessage(i, checksum);
+ log.addMessage(i, checksum);
} catch (IOException ioe) {
continue;
}
Added: trunk/apps/fnmail/src/fnmail/MailLog.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/MailLog.java 2006-05-05 18:38:50 UTC (rev
8610)
+++ trunk/apps/fnmail/src/fnmail/MailLog.java 2006-05-05 19:55:39 UTC (rev
8611)
@@ -0,0 +1,108 @@
+package fnmail;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileOutputStream;
+import java.io.BufferedReader;
+import java.io.PrintWriter;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Iterator;
+
+
+class MailLog {
+ private final File logfile;
+ private HashMap messages;
+ private int lastMessageId;
+ private int passes;
+
+ MailLog(File logfile) {
+ this.lastMessageId = 0;
+ this.passes = 0;
+
+ this.messages = new HashMap();
+ this.logfile = logfile;
+
+ FileReader frdr;
+ try {
+ frdr = new FileReader(this.logfile);
+
+
+ BufferedReader br = new BufferedReader(frdr);
+ String line;
+
+ while ( (line = br.readLine()) != null) {
+ String[] parts = line.split("=");
+
+ if (parts.length != 2) continue;
+
+ System.out.println(parts[0]);
+ if (parts[0].equalsIgnoreCase("passes")) {
+ this.passes =
Integer.parseInt(parts[1]);
+ continue;
+ }
+
+ int thisnum = Integer.parseInt(parts[0]);
+ if (thisnum > this.lastMessageId)
+ this.lastMessageId = thisnum;
+ this.messages.put(new Integer(thisnum),
parts[1]);
+ }
+
+ frdr.close();
+ } catch (IOException ioe) {
+ return;
+ }
+ }
+
+ public int incPasses() {
+ this.passes++;
+ this.writeLogFile();
+ return this.passes;
+ }
+
+ public int getPasses() {
+ return this.passes;
+ }
+
+ public int getNextMessageId() {
+ return this.lastMessageId + 1;
+ }
+
+ public void addMessage(int num, String checksum) {
+ this.messages.put(new Integer(num), checksum);
+ if (num > this.lastMessageId)
+ this.lastMessageId = num;
+ this.writeLogFile();
+ }
+
+ private void writeLogFile() {
+ FileOutputStream fos;
+ try {
+ fos = new FileOutputStream(this.logfile);
+ } catch (IOException ioe) {
+ return;
+ }
+
+ PrintWriter pw = new PrintWriter(fos);
+
+ pw.println("passes="+this.passes);
+
+ Iterator i = this.messages.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Map.Entry)i.next();
+
+ Integer num = (Integer)e.getKey();
+ String checksum = (String)e.getValue();
+ pw.println(num.toString()+"="+checksum);
+ }
+
+ pw.flush();
+
+ try {
+ fos.close();
+ } catch (IOException ioe) {
+ return;
+ }
+ }
+}
Modified: trunk/apps/fnmail/src/fnmail/MessageSender.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/MessageSender.java 2006-05-05 18:38:50 UTC
(rev 8610)
+++ trunk/apps/fnmail/src/fnmail/MessageSender.java 2006-05-05 19:55:39 UTC
(rev 8611)
@@ -13,6 +13,7 @@
import fnmail.fcp.FCPInsertErrorMessage;
import fnmail.fcp.FCPBadFileException;
import fnmail.utils.EmailAddress;
+import fnmail.utils.DateStringFactory;
public class MessageSender implements Runnable {
public static final String OUTBOX_DIR = "outbox";
@@ -119,7 +120,7 @@
}
if (addr.domain.equalsIgnoreCase("nim.fnmail")) {
- if (this.slotinsert(msg, NIM_KEY_PREFIX+addr.user)) {
+ if (this.slotinsert(msg,
NIM_KEY_PREFIX+addr.user+"-"+DateStringFactory.getKeyString())) {
msg.delete();
}
}
Modified: trunk/apps/fnmail/src/fnmail/fcp/FCPConnection.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/fcp/FCPConnection.java 2006-05-05 18:38:50 UTC
(rev 8610)
+++ trunk/apps/fnmail/src/fnmail/fcp/FCPConnection.java 2006-05-05 19:55:39 UTC
(rev 8611)
@@ -18,13 +18,19 @@
public FCPConnection(FCPContext ctx) {
this.fcpctx = ctx;
this.clients = new HashMap();
- this.nextMsgId = 1;
+ this.tryConnect();
+ }
+
+ private void tryConnect() {
+ if (this.conn != null) return;
+
try {
+ this.nextMsgId = 1;
this.conn = this.fcpctx.getConn();
this.is = this.conn.getInputStream();
this.os = this.conn.getOutputStream();
-
+
FCPMessage hello = new FCPMessage(this.nextMsgId,
"ClientHello");
this.nextMsgId++;
hello.writeto(this.os);
@@ -38,14 +44,10 @@
System.out.println("Warning - got
'"+reply.getType()+"' from node, expecting 'NodeHello'");
}
} catch (IOException ioe) {
- System.out.println("Warning - could not connect to node
- "+ioe.getMessage());
- try {
- if (this.conn != null) {
- this.conn.close();
- }
- } catch (IOException ioe2) {
- }
this.conn = null;
+ this.is = null;
+ this.os = null;
+ return;
} catch (FCPBadFileException bfe) {
// won't be thrown from a hello, so should really
// never get here!
@@ -55,18 +57,16 @@
public void run() {
while (true) {
try {
- if (this.conn == null) {
- this.conn = this.fcpctx.getConn();
- this.is = this.conn.getInputStream();
- this.os = this.conn.getOutputStream();
- }
+ this.tryConnect();
+ if (this.conn == null) throw new IOException();
FCPMessage msg = this.getMessage();
if (msg.getType() == null) throw new
IOException("Connection closed");
this.dispatch(msg);
} catch (IOException ioe) {
- System.out.println("Warning - error
communicating with node - "+ioe.getMessage());
this.conn = null;
+ this.os = null;
+ this.is = null;
// tell all our clients it's all over
Iterator i = this.clients.values().iterator();
while (i.hasNext()) {
@@ -92,12 +92,12 @@
}
public synchronized void doRequest(FCPClient cli, FCPMessage msg)
throws NoNodeConnectionException, FCPBadFileException {
- if (this.os == null) throw new NoNodeConnectionException();
+ if (this.os == null) throw new NoNodeConnectionException("No
Connection");
this.clients.put(msg.getId(), cli);
try {
msg.writeto(this.os);
} catch (IOException ioe) {
- throw new NoNodeConnectionException();
+ throw new NoNodeConnectionException(ioe.getMessage());
}
}
Modified: trunk/apps/fnmail/src/fnmail/fcp/HighLevelFCPClient.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/fcp/HighLevelFCPClient.java 2006-05-05
18:38:50 UTC (rev 8610)
+++ trunk/apps/fnmail/src/fnmail/fcp/HighLevelFCPClient.java 2006-05-05
19:55:39 UTC (rev 8611)
@@ -25,6 +25,7 @@
break;
} catch (NoNodeConnectionException nnce) {
try {
+ System.out.println("got no conn
exception: "+nnce.getMessage());
Thread.sleep(5000);
} catch (InterruptedException ie) {
}
Modified: trunk/apps/fnmail/src/fnmail/fcp/NoNodeConnectionException.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/fcp/NoNodeConnectionException.java
2006-05-05 18:38:50 UTC (rev 8610)
+++ trunk/apps/fnmail/src/fnmail/fcp/NoNodeConnectionException.java
2006-05-05 19:55:39 UTC (rev 8611)
@@ -1,5 +1,11 @@
package fnmail.fcp;
public class NoNodeConnectionException extends Exception {
+ NoNodeConnectionException() {
+ super();
+ }
+ NoNodeConnectionException(String s) {
+ super(s);
+ }
}
Added: trunk/apps/fnmail/src/fnmail/utils/DateStringFactory.java
===================================================================
--- trunk/apps/fnmail/src/fnmail/utils/DateStringFactory.java 2006-05-05
18:38:50 UTC (rev 8610)
+++ trunk/apps/fnmail/src/fnmail/utils/DateStringFactory.java 2006-05-05
19:55:39 UTC (rev 8611)
@@ -0,0 +1,34 @@
+package fnmail.utils;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+
+public class DateStringFactory {
+ private static final TimeZone gmt = TimeZone.getTimeZone("GMT");
+ private static final Calendar cal = Calendar.getInstance(gmt);
+ private static final SimpleDateFormat sdf = new
SimpleDateFormat("yyyyMMdd");
+
+ public static String getKeyString() {
+ return getOffsetKeyString(0);
+ }
+
+ // get a date in a format we use for keys, offset from today
+ public static synchronized String getOffsetKeyString(int offset) {
+ cal.setTime(new Date());
+ cal.add(Calendar.DAY_OF_MONTH, offset);
+
+ return sdf.format(cal.getTime());
+ }
+
+ public static Date DateFromKeyString(String str) {
+ try {
+ sdf.setLenient(false);
+ return sdf.parse(str);
+ } catch (ParseException pe) {
+ return null;
+ }
+ }
+}