You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2012/12/27 08:03:50 UTC
svn commit: r1426134 - in
/manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs:
JobManager.java JobQueue.java TrackerClass.java
Author: kwright
Date: Thu Dec 27 07:03:49 2012
New Revision: 1426134
URL: http://svn.apache.org/viewvc?rev=1426134&view=rev
Log:
Partial inclusion of TrackerClass.
Added:
manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java (with props)
Modified:
manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobManager.java
manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobQueue.java
Modified: manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobManager.java?rev=1426134&r1=1426133&r2=1426134&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobManager.java (original)
+++ manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobManager.java Thu Dec 27 07:03:49 2012
@@ -639,12 +639,14 @@ public class JobManager implements IJobM
// Clean up carrydown stuff
carryDown.reset();
database.performCommit();
+ TrackerClass.noteCommit();
Logging.jobs.debug("Reset complete");
break;
}
catch (ManifoldCFException e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
if (e.getErrorCode() == e.DATABASE_TRANSACTION_ABORT)
{
if (Logging.perf.isDebugEnabled())
@@ -657,6 +659,7 @@ public class JobManager implements IJobM
catch (Error e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
throw e;
}
finally
@@ -681,11 +684,13 @@ public class JobManager implements IJobM
{
jobQueue.resetDocumentWorkerStatus();
database.performCommit();
+ TrackerClass.noteCommit();
break;
}
catch (ManifoldCFException e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
if (e.getErrorCode() == e.DATABASE_TRANSACTION_ABORT)
{
if (Logging.perf.isDebugEnabled())
@@ -698,6 +703,7 @@ public class JobManager implements IJobM
catch (Error e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
throw e;
}
finally
@@ -726,6 +732,7 @@ public class JobManager implements IJobM
{
Logging.jobs.debug("Resetting doc deleting status");
jobQueue.resetDocDeleteWorkerStatus();
+ TrackerClass.noteCommit();
Logging.jobs.debug("Reset complete");
}
@@ -736,6 +743,7 @@ public class JobManager implements IJobM
{
Logging.jobs.debug("Resetting doc cleaning status");
jobQueue.resetDocCleanupWorkerStatus();
+ TrackerClass.noteCommit();
Logging.jobs.debug("Reset complete");
}
@@ -4145,6 +4153,7 @@ public class JobManager implements IJobM
jobQueue.reactivateHopcountRemovedRecords(jobID);
database.performCommit();
+ TrackerClass.noteCommit();
if (Logging.perf.isDebugEnabled())
Logging.perf.debug("Took "+new Long(System.currentTimeMillis()-startTime).toString()+" ms to add "+Integer.toString(reorderedDocIDHashes.length)+
@@ -4164,6 +4173,7 @@ public class JobManager implements IJobM
catch (ManifoldCFException e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
if (e.getErrorCode() == e.DATABASE_TRANSACTION_ABORT)
{
sleepAmt = getRandomAmount();
@@ -4177,6 +4187,7 @@ public class JobManager implements IJobM
catch (Error e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
throw e;
}
finally
@@ -5353,6 +5364,7 @@ public class JobManager implements IJobM
// No special treatment needed for hopcount or carrydown, since these all get deleted at once
// at the end of the job delete process.
jobQueue.prepareDeleteScan(jobID);
+ TrackerClass.noteCommit();
}
/** Prepare for a full scan.
@@ -5386,11 +5398,13 @@ public class JobManager implements IJobM
jobQueue.prepareFullScan(jobID);
database.performCommit();
+ TrackerClass.noteCommit();
break;
}
catch (ManifoldCFException e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
if (e.getErrorCode() == e.DATABASE_TRANSACTION_ABORT)
{
if (Logging.perf.isDebugEnabled())
@@ -5403,6 +5417,7 @@ public class JobManager implements IJobM
catch (Error e)
{
database.signalRollback();
+ TrackerClass.noteRollback();
throw e;
}
finally
Modified: manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobQueue.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobQueue.java?rev=1426134&r1=1426133&r2=1426134&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobQueue.java (original)
+++ manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobQueue.java Thu Dec 27 07:03:49 2012
@@ -381,6 +381,8 @@ public class JobQueue extends org.apache
// Reindex the jobqueue table, since we've probably made lots of bad tuples doing the above operations.
reindexTable();
unconditionallyAnalyzeTables();
+
+ TrackerClass.noteGlobalEvent("Restart");
}
/** Flip all records for a job that have status HOPCOUNTREMOVED back to PENDING.
@@ -398,6 +400,8 @@ public class JobQueue extends org.apache
new UnitaryClause(jobIDField,jobID),
new UnitaryClause(statusField,statusToString(STATUS_HOPCOUNTREMOVED))});
performUpdate(map,"WHERE "+query,list,null);
+
+ TrackerClass.noteJobEvent(jobID,"Map HOPCOUNTREMOVED to PENDING");
}
/** Delete all records for a job that have status HOPCOUNTREMOVED.
@@ -455,6 +459,8 @@ public class JobQueue extends org.apache
statusToString(STATUS_ACTIVEPURGATORY),
statusToString(STATUS_ACTIVENEEDRESCANPURGATORY)})});
performUpdate(map,"WHERE "+query,list,null);
+
+ TrackerClass.noteGlobalEvent("Reset document worker status");
}
/** Reset doc delete worker status.
@@ -470,6 +476,8 @@ public class JobQueue extends org.apache
String query = buildConjunctionClause(list,new ClauseDescription[]{
new UnitaryClause(statusField,statusToString(STATUS_BEINGDELETED))});
performUpdate(map,"WHERE "+query,list,null);
+
+ TrackerClass.noteGlobalEvent("Reset document delete worker status");
}
/** Reset doc cleaning worker status.
@@ -485,6 +493,8 @@ public class JobQueue extends org.apache
String query = buildConjunctionClause(list,new ClauseDescription[]{
new UnitaryClause(statusField,statusToString(STATUS_BEINGCLEANED))});
performUpdate(map,"WHERE "+query,list,null);
+
+ TrackerClass.noteGlobalEvent("Reset document cleanup worker status");
}
/** Prepare for a job delete pass. This will not be called
@@ -535,6 +545,7 @@ public class JobQueue extends org.apache
// Do an analyze, otherwise our plans are going to be crap right off the bat
unconditionallyAnalyzeTables();
+ TrackerClass.noteJobEvent(jobID,"Prepare delete scan");
}
/** Prepare for a "full scan" job. This will not be called
@@ -584,6 +595,8 @@ public class JobQueue extends org.apache
noteModifications(0,2,0);
// Do an analyze, otherwise our plans are going to be crap right off the bat
unconditionallyAnalyzeTables();
+
+ TrackerClass.noteJobEvent(jobID,"Prepare full scan");
}
/** Prepare for an "incremental" job. This is called ONLY when the job is inactive;
@@ -613,6 +626,8 @@ public class JobQueue extends org.apache
noteModifications(0,1,0);
// Do an analyze, otherwise our plans are going to be crap right off the bat
unconditionallyAnalyzeTables();
+
+ TrackerClass.noteJobEvent(jobID,"Prepare incremental scan");
}
/** Delete ingested document identifiers (as part of deleting the owning job).
@@ -726,6 +741,7 @@ public class JobQueue extends org.apache
// Leave doc priority unchanged.
break;
default:
+ TrackerClass.printForensics(recID, currentStatus);
throw new ManifoldCFException("Unexpected jobqueue status - record id "+recID.toString()+", expecting active status, saw "+Integer.toString(currentStatus));
}
@@ -738,6 +754,8 @@ public class JobQueue extends org.apache
String query = buildConjunctionClause(list,new ClauseDescription[]{
new UnitaryClause(idField,recID)});
performUpdate(map,"WHERE "+query,list,null);
+
+ TrackerClass.noteRecordEvent(recID, newStatus, "Note completion");
}
/** Either delete a record, or set status to "rescan", depending on the
@@ -767,6 +785,7 @@ public class JobQueue extends org.apache
// Leave doc priority unchanged.
break;
default:
+ TrackerClass.printForensics(recID, currentStatus);
throw new ManifoldCFException("Unexpected jobqueue status - record id "+recID.toString()+", expecting active status, saw "+Integer.toString(currentStatus));
}
@@ -779,6 +798,7 @@ public class JobQueue extends org.apache
String query = buildConjunctionClause(list,new ClauseDescription[]{
new UnitaryClause(idField,recID)});
performUpdate(map,"WHERE "+query,list,null);
+ TrackerClass.noteRecordEvent(recID, newStatus, "Rescan or delete");
return false;
}
@@ -815,6 +835,7 @@ public class JobQueue extends org.apache
// Leave doc priority unchanged.
break;
default:
+ TrackerClass.printForensics(recID, currentStatus);
throw new ManifoldCFException("Unexpected jobqueue status - record id "+recID.toString()+", expecting active status, saw "+Integer.toString(currentStatus));
}
@@ -827,6 +848,7 @@ public class JobQueue extends org.apache
String query = buildConjunctionClause(list,new ClauseDescription[]{
new UnitaryClause(idField,recID)});
performUpdate(map,"WHERE "+query,list,null);
+ TrackerClass.noteRecordEvent(recID, newStatus, "Update or hopcount remove");
return rval;
}
@@ -847,6 +869,7 @@ public class JobQueue extends org.apache
newStatus = STATUS_ACTIVEPURGATORY;
break;
default:
+ TrackerClass.printForensics(id, currentStatus);
throw new ManifoldCFException("Unexpected status value for jobqueue record "+id.toString()+"; got "+Integer.toString(currentStatus));
}
@@ -857,6 +880,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, newStatus, "Make active");
}
/** Set the status on a record, including check time and priority.
@@ -888,6 +912,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, status, "Set status");
}
/** Set the status of a document to "being deleted".
@@ -902,6 +927,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, STATUS_BEINGDELETED, "Set deleting status");
}
/** Set the status of a document to be "no longer deleting" */
@@ -919,6 +945,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, STATUS_ELIGIBLEFORDELETE, "Set undeleting status");
}
/** Set the status of a document to "being cleaned".
@@ -933,6 +960,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, STATUS_BEINGCLEANED, "Set cleaning status");
}
/** Set the status of a document to be "no longer cleaning" */
@@ -950,6 +978,7 @@ public class JobQueue extends org.apache
new UnitaryClause(idField,id)});
performUpdate(map,"WHERE "+query,list,null);
noteModifications(0,1,0);
+ TrackerClass.noteRecordEvent(id, STATUS_PURGATORY, "Set uncleaning status");
}
/** Remove multiple records entirely.
@@ -1040,6 +1069,7 @@ public class JobQueue extends org.apache
case STATUS_PURGATORY:
// Set the status and time both
map.put(statusField,statusToString(STATUS_PENDINGPURGATORY));
+ TrackerClass.noteRecordEvent(recordID, STATUS_PENDINGPURGATORY, "Update existing record initial");
if (desiredExecuteTime == -1L)
map.put(checkTimeField,new Long(0L));
else
@@ -1130,6 +1160,7 @@ public class JobQueue extends org.apache
performInsert(map,null);
prereqEventManager.addRows(recordID,prereqEvents);
noteModifications(1,0,0);
+ TrackerClass.noteRecordEvent(recordID, STATUS_PENDING, "Create initial");
}
/** Note the remaining documents that do NOT need to be queued. These are noted so that the
@@ -1316,6 +1347,7 @@ public class JobQueue extends org.apache
case STATUS_PURGATORY:
// Set the status and time both
map.put(statusField,statusToString(STATUS_PENDINGPURGATORY));
+ TrackerClass.noteRecordEvent(recordID, STATUS_PENDINGPURGATORY, "Update existing");
map.put(checkTimeField,new Long(desiredExecuteTime));
map.put(checkActionField,actionToString(ACTION_RESCAN));
map.put(failTimeField,null);
@@ -1333,6 +1365,7 @@ public class JobQueue extends org.apache
// The document has been processed before, so it has to go into PENDINGPURGATORY.
// Set the status and time both
map.put(statusField,statusToString(STATUS_PENDINGPURGATORY));
+ TrackerClass.noteRecordEvent(recordID, STATUS_PENDINGPURGATORY, "Update existing");
map.put(checkTimeField,new Long(desiredExecuteTime));
map.put(checkActionField,actionToString(ACTION_RESCAN));
map.put(failTimeField,null);
@@ -1362,6 +1395,7 @@ public class JobQueue extends org.apache
// Flip the state to the new one, and set the document priority at this time too - it will be preserved when the
// processing is completed.
map.put(statusField,statusToString(STATUS_ACTIVENEEDRESCAN));
+ TrackerClass.noteRecordEvent(recordID, STATUS_ACTIVENEEDRESCAN, "Update existing");
map.put(checkTimeField,new Long(desiredExecuteTime));
map.put(checkActionField,actionToString(ACTION_RESCAN));
map.put(failTimeField,null);
@@ -1386,6 +1420,7 @@ public class JobQueue extends org.apache
// Flip the state to the new one, and set the document priority at this time too - it will be preserved when the
// processing is completed.
map.put(statusField,statusToString(STATUS_ACTIVENEEDRESCANPURGATORY));
+ TrackerClass.noteRecordEvent(recordID, STATUS_ACTIVENEEDRESCANPURGATORY, "Update existing");
map.put(checkTimeField,new Long(desiredExecuteTime));
map.put(checkActionField,actionToString(ACTION_RESCAN));
map.put(failTimeField,null);
@@ -1453,6 +1488,8 @@ public class JobQueue extends org.apache
performInsert(map,null);
prereqEventManager.addRows(recordID,prereqEvents);
noteModifications(1,0,0);
+ TrackerClass.noteRecordEvent(recordID, STATUS_PENDING, "Create new");
+
}
// Methods to convert status strings to integers and back
Added: manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java?rev=1426134&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java (added)
+++ manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java Thu Dec 27 07:03:49 2012
@@ -0,0 +1,279 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.manifoldcf.crawler.jobs;
+
+import java.util.*;
+
+/** Debugging class to keep track of recent modifications to the jobqueue table,
+* along with context as to where it occurred. If a jobqueue state error occurs,
+* we can then print out all of the pertinent history and find the culprit.
+*/
+public class TrackerClass
+{
+ // The goal of this class is to keep track of at least the last two events
+ // potentially affecting each record.
+
+ // Active transaction
+ protected final static Map<String,TransactionData> transactionData = new HashMap<String,TransactionData>();
+
+ // Modification history
+ protected final static List<TransactionData> history = new ArrayList<TransactionData>();
+
+ // Place where we keep track of individual modifications
+ private TrackerClass()
+ {
+ }
+
+ /** Add a single record event, as yet uncommitted */
+ public static void noteRecordEvent(Long recordID, int newStatus, String description)
+ {
+ addEvent(new RecordEvent(recordID, newStatus, new Exception(description)));
+ }
+
+ /** Add a global event, as yet uncommitted, which has the potential
+ * to affect any record's state in a given job.
+ */
+ public static void noteJobEvent(Long jobID, String description)
+ {
+ addEvent(new JobEvent(jobID, new Exception(description)));
+ }
+
+ /** Add a global event, as yet uncommitted, which has the potential
+ * to affect the state of any record.
+ */
+ public static void noteGlobalEvent(String description)
+ {
+ addEvent(new GlobalEvent(new Exception(description)));
+ }
+
+ protected static void addEvent(HistoryRecord hr)
+ {
+ String threadName = Thread.currentThread().getName();
+ TransactionData td;
+ synchronized (transactionData)
+ {
+ td = transactionData.get(threadName);
+ if (td == null)
+ {
+ td = new TransactionData();
+ transactionData.put(threadName,td);
+ }
+ }
+ td.addEvent(hr);
+ }
+
+ /** Note a commit operation.
+ */
+ public static void noteCommit()
+ {
+ long currentTime = System.currentTimeMillis();
+ String threadName = Thread.currentThread().getName();
+ TransactionData td;
+ synchronized (transactionData)
+ {
+ td = transactionData.get(threadName);
+ transactionData.remove(threadName);
+ }
+ if (td == null)
+ return;
+ // Only keep stuff around for an hour
+ long removalCutoff = currentTime - (60000 * 60);
+ synchronized (history)
+ {
+ history.add(td);
+ // Clean out older records
+ while (history.size() > 0)
+ {
+ TransactionData td2 = history.get(0);
+ if (td2.isFlushable(removalCutoff))
+ history.remove(0);
+ }
+ }
+
+ }
+
+ /** Note a rollback operation.
+ */
+ public static void noteRollback()
+ {
+ String threadName = Thread.currentThread().getName();
+ synchronized (transactionData)
+ {
+ transactionData.remove(threadName);
+ }
+ }
+
+ public static void printForensics(Long recordID, int existingStatus)
+ {
+ synchronized (transactionData)
+ {
+ synchronized (history)
+ {
+ System.out.println("---- Forensics for record "+recordID+", current status: "+existingStatus+" ----");
+ System.out.println("--Current stack trace--");
+ new Exception("Unexpected jobqueue status").printStackTrace();
+ System.out.println("--Active transactions--");
+ for (String threadName : transactionData.keySet())
+ {
+ for (HistoryRecord hr : transactionData.get(threadName).getEvents())
+ {
+ if (hr.applies(recordID))
+ {
+ System.out.println("Thread '"+threadName+"' was active:");
+ hr.print();
+ }
+ }
+ }
+ System.out.println("--Pertinent History--");
+ for (TransactionData td : history)
+ {
+ for (HistoryRecord hr : td.getEvents())
+ {
+ if (hr.applies(recordID))
+ {
+ hr.print();
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ protected static class TransactionData
+ {
+ protected final List<HistoryRecord> transactionEvents = new ArrayList<HistoryRecord>();
+ protected long timestamp;
+
+ public TransactionData()
+ {
+ timestamp = System.currentTimeMillis();
+ }
+
+ public void addEvent(HistoryRecord event)
+ {
+ transactionEvents.add(event);
+ }
+
+ public List<HistoryRecord> getEvents()
+ {
+ return transactionEvents;
+ }
+
+ public boolean isFlushable(long cutoffTime)
+ {
+ return cutoffTime > timestamp;
+ }
+ }
+
+ protected abstract static class HistoryRecord
+ {
+ protected long timestamp;
+ protected Exception trace;
+
+ public HistoryRecord(Exception trace)
+ {
+ this.trace = trace;
+ this.timestamp = System.currentTimeMillis();
+ }
+
+ public void print()
+ {
+ System.out.println(" at "+new Long(timestamp)+", location: ");
+ trace.printStackTrace();
+ }
+
+ public abstract boolean applies(Long recordID);
+
+ }
+
+ protected static class RecordEvent extends HistoryRecord
+ {
+ protected Long recordID;
+ protected int newStatus;
+
+ public RecordEvent(Long recordID, int newStatus, Exception trace)
+ {
+ super(trace);
+ this.recordID = recordID;
+ this.newStatus = newStatus;
+ }
+
+ @Override
+ public void print()
+ {
+ System.out.println("Record "+recordID+" status modified to "+newStatus);
+ super.print();
+ }
+
+ @Override
+ public boolean applies(Long recordID)
+ {
+ return this.recordID.equals(recordID);
+ }
+
+ }
+
+ protected static class JobEvent extends HistoryRecord
+ {
+ protected Long jobID;
+
+ public JobEvent(Long jobID, Exception trace)
+ {
+ super(trace);
+ this.jobID = jobID;
+ }
+
+ @Override
+ public void print()
+ {
+ System.out.println("All job related records modified for job "+jobID);
+ super.print();
+ }
+
+ @Override
+ public boolean applies(Long recordID)
+ {
+ return true;
+ }
+ }
+
+ protected static class GlobalEvent extends HistoryRecord
+ {
+ public GlobalEvent(Exception trace)
+ {
+ super(trace);
+ }
+
+ @Override
+ public void print()
+ {
+ System.out.println("All records modified");
+ super.print();
+ }
+
+ @Override
+ public boolean applies(Long recordID)
+ {
+ return true;
+ }
+ }
+
+}
Propchange: manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: manifoldcf/branches/CONNECTORS-590/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/TrackerClass.java
------------------------------------------------------------------------------
svn:keywords = Id