Author: xor Date: 2008-11-06 19:55:40 +0000 (Thu, 06 Nov 2008) New Revision: 23363
Modified: trunk/plugins/Freetalk/FTIdentityManager.java trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java trunk/plugins/Freetalk/WoT/FTIdentityWoT.java trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java Log: Implement the identity-retrieval loop. Modified: trunk/plugins/Freetalk/FTIdentityManager.java =================================================================== --- trunk/plugins/Freetalk/FTIdentityManager.java 2008-11-06 19:34:57 UTC (rev 23362) +++ trunk/plugins/Freetalk/FTIdentityManager.java 2008-11-06 19:55:40 UTC (rev 23363) @@ -3,22 +3,34 @@ * http://www.gnu.org/ for further details of the GPL. */ package plugins.Freetalk; +import java.util.Date; +import java.util.Hashtable; import java.util.Iterator; +import java.util.List; +import plugins.WoT.Identity; +import plugins.WoT.OwnIdentity; +import plugins.WoT.WoT; + import com.db4o.ObjectContainer; import com.db4o.ObjectSet; +import com.db4o.query.Query; +import freenet.keys.FreenetURI; import freenet.support.Executor; +import freenet.support.Logger; /** * @author saces, xor * */ -public abstract class FTIdentityManager implements Iterable<FTIdentity> { - +public abstract class FTIdentityManager implements Runnable, Iterable<FTIdentity> { + protected final ObjectContainer db; protected final Executor mExecutor; + + public boolean isRunning = true; public FTIdentityManager(ObjectContainer myDB, Executor newExecutor) { db = myDB; @@ -46,4 +58,6 @@ return false; } + + public abstract void run(); } Modified: trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java 2008-11-06 19:34:57 UTC (rev 23362) +++ trunk/plugins/Freetalk/WoT/FTIdentityManagerWoT.java 2008-11-06 19:55:40 UTC (rev 23363) @@ -3,12 +3,20 @@ * http://www.gnu.org/ for further details of the GPL. */ package plugins.Freetalk.WoT; +import java.util.List; + import plugins.Freetalk.FTIdentityManager; +import plugins.WoT.Identity; +import plugins.WoT.OwnIdentity; import plugins.WoT.WoT; +import plugins.WoT.exceptions.InvalidParameterException; import com.db4o.ObjectContainer; +import com.db4o.ObjectSet; +import com.db4o.query.Query; import freenet.support.Executor; +import freenet.support.Logger; /** * An identity manager which uses the identities from the WoT plugin. @@ -18,6 +26,9 @@ */ public class FTIdentityManagerWoT extends FTIdentityManager { + /* FIXME: This really has to be tweaked before release. I set it quite short for debugging */ + private static final int THREAD_PERIOD = 5 * 60 * 1000; + private WoT mWoT; /** @@ -27,4 +38,101 @@ super(myDB, executor); mWoT = newWoT; } + + private void receiveIdentities() throws InvalidParameterException { + long time = System.currentTimeMillis(); + + ObjectSet<OwnIdentity> oids = mWoT.getAllOwnIdentities(); + for(OwnIdentity o : oids) { + synchronized(this) { /* We lock here and not during the whole function to allow other threads to execute */ + Query q = db.query(); + q.constrain(FTOwnIdentityWoT.class); + q.descend("mIdentity").equals(o); + ObjectSet<FTOwnIdentityWoT> result = q.execute(); + + if(result.size() == 0) { + db.store(new FTOwnIdentityWoT(db, o)); + db.commit(); + } else { + assert(result.size() == 1); + result.next().setLastReceivedFromWoT(time); + } + } + } + + List<Identity> ids = mWoT.getIdentitiesByScore(null, 30, "freetalk"); /* FIXME: the "30" has to be configurable */ + + for(Identity i : ids) { + synchronized(this) { /* We lock here and not during the whole function to allow other threads to execute */ + Query q = db.query(); + q.constrain(FTIdentityWoT.class); + q.descend("mIdentity").equals(i); + ObjectSet<FTIdentityWoT> result = q.execute(); + + if(result.size() == 0) { + db.store(new FTIdentityWoT(db, i)); + db.commit(); + } else { + assert(result.size() == 1); + result.next().setLastReceivedFromWoT(time); + } + } + } + } + + private synchronized void garbageCollectIdentities() { + /* Executing the thread loop once will always take longer than THREAD_PERIOD. Therefore, if we set the limit to 3*THREAD_PERIOD, + * it will hit identities which were last received before more than 2*THREAD_LOOP, not exactly 3*THREAD_LOOP. */ + long lastAcceptTime = System.currentTimeMillis() - THREAD_PERIOD * 3; + + Query q = db.query(); + q.constrain(FTIdentityWoT.class); + q.descend("isNeeded").equals(false); + q.descend("lastReceivedFromWoT").constrain(new Long(lastAcceptTime)).smaller(); + ObjectSet<FTIdentityWoT> result = q.execute(); + + while(result.hasNext()) { + FTIdentityWoT i = result.next(); + assert(identityIsNotNeeded(i)); /* Check whether the isNeeded field of the identity was correct */ + db.delete(i); + } + + db.commit(); + } + + /** + * Debug function for checking whether the isNeeded field of an identity is correct. + */ + private boolean identityIsNotNeeded(FTIdentityWoT i) { + /* FIXME: This function does not lock, it should probably. But we cannot lock on the message manager because it locks on the identity + * manager and therefore this might cause deadlock. */ + Query q = db.query(); + q.constrain(FTMessageWoT.class); + q.descend("mAuthor").equals(i); + return (q.execute().size() == 0); + } + + + @Override + public void run() { + try { + Thread.sleep((long) (3*60*1000 * (0.5f + Math.random()))); /* Let the node start up */ + } catch (InterruptedException e) { } + + while(isRunning) { + try { + receiveIdentities(); + } + + catch(InvalidParameterException e) { + Logger.error(this, "Exception in identity fetch loop", e); + } + + garbageCollectIdentities(); + + try { + Thread.sleep((long) (THREAD_PERIOD * (0.5f + Math.random()))); + } catch (InterruptedException e) { } + } + } } Modified: trunk/plugins/Freetalk/WoT/FTIdentityWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FTIdentityWoT.java 2008-11-06 19:34:57 UTC (rev 23362) +++ trunk/plugins/Freetalk/WoT/FTIdentityWoT.java 2008-11-06 19:55:40 UTC (rev 23363) @@ -5,6 +5,8 @@ import java.util.Date; +import com.db4o.ObjectContainer; + import freenet.keys.FreenetURI; import plugins.Freetalk.FTIdentity; @@ -16,26 +18,64 @@ */ public class FTIdentityWoT implements FTIdentity { + protected final ObjectContainer db; + protected final Identity mIdentity; + + /** + * Used for garbage collecting old identities which are not returned by the WoT plugin anymore. + * We delete them if they were not received for a certain time interval. + */ + private long mLastReceivedFromWoT; + + /** + * Set to true if the identity is referenced by any messages. + */ + private boolean mIsNeeded; - public FTIdentityWoT(Identity newIndentity) { - mIdentity = newIndentity; + public FTIdentityWoT(ObjectContainer myDB, Identity myIndentity) { + db = myDB; + mIdentity = myIndentity; + mLastReceivedFromWoT = System.currentTimeMillis(); + mIsNeeded = false; } - public boolean doesPublishTrustList() { + public synchronized boolean doesPublishTrustList() { return mIdentity.doesPublishTrustList(); } - public Date getLastChange() { + public synchronized Date getLastChange() { return mIdentity.getLastChange(); } - public String getNickName() { + public synchronized String getNickName() { return mIdentity.getNickName(); } - public FreenetURI getRequestURI() { + public synchronized FreenetURI getRequestURI() { return mIdentity.getRequestURI(); } + + public synchronized long getLastReceivedFromWoT() { + return mLastReceivedFromWoT; + } + + public synchronized void setLastReceivedFromWoT(long time) { + mLastReceivedFromWoT = time; + store(); + } + + public synchronized boolean isNeeded() { + return mIsNeeded; + } + + public synchronized void setIsNeeded(boolean newValue) { + mIsNeeded = newValue; + } + + protected void store() { + db.store(this); + db.commit(); + } } Modified: trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java =================================================================== --- trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java 2008-11-06 19:34:57 UTC (rev 23362) +++ trunk/plugins/Freetalk/WoT/FTOwnIdentityWoT.java 2008-11-06 19:55:40 UTC (rev 23363) @@ -7,6 +7,8 @@ import java.util.Iterator; import java.util.LinkedList; +import com.db4o.ObjectContainer; + import plugins.Freetalk.FTBoard; import plugins.Freetalk.FTIdentity; import plugins.Freetalk.FTMessage; @@ -19,11 +21,11 @@ * */ public class FTOwnIdentityWoT extends FTIdentityWoT implements FTOwnIdentity { - + private final LinkedList<FTBoard> mSubscribedBoards = new LinkedList<FTBoard>(); - public FTOwnIdentityWoT(OwnIdentity newIndentity) { - super(newIndentity); + public FTOwnIdentityWoT(ObjectContainer myDB, OwnIdentity newIndentity) { + super(myDB, newIndentity); } protected OwnIdentity getOwnIdentity() { @@ -49,10 +51,13 @@ return; } mSubscribedBoards.add(board); + + store(); } public synchronized void unsubscribeFromBoard(FTBoard board) { mSubscribedBoards.remove(board); + store(); } public synchronized Iterator<FTBoard> subscribedBoardsIterator() { @@ -63,7 +68,7 @@ // TODO Auto-generated method stub return false; } - + /* public final void exportXML(OutputStream out) throws IOException { Writer w = new BufferedWriter(new OutputStreamWriter(out));
