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));


Reply via email to