Smalyshev has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/330822 )

Change subject: Do not try to process same change ID twice
......................................................................

Do not try to process same change ID twice

Bug: T153932
Change-Id: I5c970930b0da99f6567279ce0ebfbba040bd7f91
---
M tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
M 
tools/src/main/java/org/wikidata/query/rdf/tool/change/RecentChangesPoller.java
M 
tools/src/test/java/org/wikidata/query/rdf/tool/change/RecentChangesPollerUnitTest.java
3 files changed, 46 insertions(+), 29 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikidata/query/rdf 
refs/changes/22/330822/1

diff --git a/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java 
b/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
index 611dc55..b93a952 100644
--- a/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
+++ b/tools/src/main/java/org/wikidata/query/rdf/tool/Update.java
@@ -315,6 +315,7 @@
             }
         } while (batch == null);
         log.debug("{} changes in batch", batch.changes().size());
+        Date oldDate = null;
         while (true) {
             try {
                 handleChanges(batch);
@@ -326,7 +327,11 @@
                      * have some updates.
                      */
                     leftOffDate = new Date(batch.leftOffDate().getTime() - 
SECONDS.toMillis(1));
-                    rdfRepository.updateLeftOffTime(leftOffDate);
+                    if (oldDate == null || !oldDate.equals(leftOffDate)) {
+                        // Do not update repo with the same date
+                        oldDate = leftOffDate;
+                        rdfRepository.updateLeftOffTime(leftOffDate);
+                    }
                 }
                 // TODO wrap all retry-able exceptions in a special exception
                 batchAdvanced.mark(batch.advanced());
@@ -435,10 +440,11 @@
      * @throws InterruptedException if the process was interrupted while 
waiting
      *             during the pollDelay or waiting on something else
      */
-    private B nextBatch(B batch) throws InterruptedException {
+    private B nextBatch(B prevBatch) throws InterruptedException {
+        B batch;
         while (true) {
             try {
-                batch = changeSource.nextBatch(batch);
+                batch = changeSource.nextBatch(prevBatch);
             } catch (RetryableException e) {
                 log.warn("Retryable error fetching next batch.  Retrying.", e);
                 continue;
diff --git 
a/tools/src/main/java/org/wikidata/query/rdf/tool/change/RecentChangesPoller.java
 
b/tools/src/main/java/org/wikidata/query/rdf/tool/change/RecentChangesPoller.java
index 489ef9c..09ca176 100644
--- 
a/tools/src/main/java/org/wikidata/query/rdf/tool/change/RecentChangesPoller.java
+++ 
b/tools/src/main/java/org/wikidata/query/rdf/tool/change/RecentChangesPoller.java
@@ -4,8 +4,10 @@
 
 import java.text.DateFormat;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
@@ -51,7 +53,7 @@
 
     @Override
     public Batch nextBatch(Batch lastBatch) throws RetryableException {
-        return batch(lastBatch.leftOffDate, lastBatch.nextContinue);
+        return batch(lastBatch.leftOffDate, lastBatch);
     }
 
     /**
@@ -62,20 +64,21 @@
          * The date where we last left off.
          */
         private final Date leftOffDate;
+
         /**
-         * The continue object that must be sent to wikibase to continue where
-         * we left off.
+         * The set of the rcid's this batch seen.
+         * Note that some IDs may be seen but not processed
+         * due to duplicates, etc.
          */
-        private final JSONObject nextContinue;
+        private final Set<Long> seenIDs;
 
         /**
          * A batch that will next continue using the continue parameter.
          */
-        private Batch(ImmutableList<Change> changes, long advanced, String 
leftOff, Date nextStartTime,
-                JSONObject nextContinue) {
+        private Batch(ImmutableList<Change> changes, long advanced, String 
leftOff, Date nextStartTime, Set<Long> seenIDs) {
             super(changes, advanced, leftOff);
             leftOffDate = nextStartTime;
-            this.nextContinue = nextContinue;
+            this.seenIDs = seenIDs;
         }
 
         @Override
@@ -90,8 +93,16 @@
 
         @Override
         public String leftOffHuman() {
-            return leftOffDate.toString() + " (next: " + 
nextContinue.get("rccontinue").toString()
-                    + ")";
+            return WikibaseRepository.inputDateFormat().format(leftOffDate);
+            // + " (next: " + nextContinue.get("rccontinue").toString() + ")";
+        }
+
+        /**
+         * Get the list of IDs this batch has seen.
+         * @return
+         */
+        public Set<Long> getSeenIDs() {
+            return seenIDs;
         }
     }
 
@@ -101,10 +112,9 @@
      * @throws RetryableException on parse failure
      */
     @SuppressWarnings("checkstyle:cyclomaticcomplexity")
-    private Batch batch(Date lastNextStartTime, JSONObject lastNextContinue) 
throws RetryableException {
+    private Batch batch(Date lastNextStartTime, Batch lastBatch) throws 
RetryableException {
         try {
             @SuppressWarnings("unchecked")
-            final Change continueChange = 
wikibase.getChangeFromContinue((Map<String, Object>)lastNextContinue);
             JSONObject recentChanges = 
wikibase.fetchRecentChangesBackoff(lastNextStartTime, batchSize, true);
             // Using LinkedHashMap here so that changes came out sorted by 
order of arrival
             Map<String, Change> changesByTitle = new LinkedHashMap<>();
@@ -112,6 +122,8 @@
             long nextStartTime = lastNextStartTime.getTime();
             JSONArray result = (JSONArray) ((JSONObject) 
recentChanges.get("query")).get("recentchanges");
             DateFormat df = inputDateFormat();
+            Set<Long> seenIds = new HashSet<>();
+
             for (Object rco : result) {
                 JSONObject rc = (JSONObject) rco;
                 long namespace = (long) rc.get("ns");
@@ -121,7 +133,13 @@
                     continue;
                 }
                 if (!wikibase.isValidEntity(rc.get("title").toString())) {
-                    log.info("Skipping change with bogus id:  {}", 
rc.get("title").toString());
+                    log.info("Skipping change with bogus title:  {}", 
rc.get("title").toString());
+                    continue;
+                }
+                seenIds.add(rcid);
+                if (lastBatch != null && 
lastBatch.getSeenIDs().contains(rcid)) {
+                    // This change was in the last batch
+                    log.debug("Skipping repeated change with rcid {}", rcid);
                     continue;
                 }
 // Looks like we can not rely on changes appearing in order, so we have to 
take them all and let SPARQL
@@ -152,19 +170,11 @@
                 nextStartTime = Math.max(nextStartTime, timestamp.getTime());
             }
             ImmutableList<Change> changes = 
ImmutableList.copyOf(changesByTitle.values());
-            if (nextContinue == null) {
-                if (changes.size() != 0) {
-                    // Create fake rccontinue so we continue from last known 
change
-                    nextContinue = 
wikibase.getContinueObject(changes.get(changes.size() - 1));
-                } else {
-                    if (result.size() >= batchSize) {
-                        // We have a problem here - due to backoff, we did not 
fetch any new items
-                        // Try to advance one second, even though we risk to 
lose a change
-                        log.info("Backoff overflow, advancing one second");
-                        nextStartTime += 1000;
-                    }
-                    nextContinue = lastNextContinue;
-                }
+            if (nextContinue == null && changes.size() == 0 && result.size() 
>= batchSize) {
+                // We have a problem here - due to backoff, we did not fetch 
any new items
+                // Try to advance one second, even though we risk to lose a 
change
+                log.info("Backoff overflow, advancing one second");
+                nextStartTime += 1000;
             }
 
             if (changes.size() != 0) {
@@ -179,7 +189,7 @@
             // be sure we got the whole second
             String upTo = inputDateFormat().format(new Date(nextStartTime - 
1000));
             long advanced = nextStartTime - lastNextStartTime.getTime();
-            return new Batch(changes, advanced, upTo, new Date(nextStartTime), 
nextContinue);
+            return new Batch(changes, advanced, upTo, new Date(nextStartTime), 
seenIds);
         } catch (java.text.ParseException e) {
             throw new RetryableException("Parse error from api", e);
         }
diff --git 
a/tools/src/test/java/org/wikidata/query/rdf/tool/change/RecentChangesPollerUnitTest.java
 
b/tools/src/test/java/org/wikidata/query/rdf/tool/change/RecentChangesPollerUnitTest.java
index 170e1c3..8d19629 100644
--- 
a/tools/src/test/java/org/wikidata/query/rdf/tool/change/RecentChangesPollerUnitTest.java
+++ 
b/tools/src/test/java/org/wikidata/query/rdf/tool/change/RecentChangesPollerUnitTest.java
@@ -122,6 +122,7 @@
         Batch batch = poller.firstBatch();
         assertThat(batch.changes(), hasSize(2));
         assertEquals(7, batch.changes().get(1).rcid());
+        assertEquals(date, batch.leftOffHuman());
 
         ArgumentCaptor<Date> argument = ArgumentCaptor.forClass(Date.class);
 

-- 
To view, visit https://gerrit.wikimedia.org/r/330822
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5c970930b0da99f6567279ce0ebfbba040bd7f91
Gerrit-PatchSet: 1
Gerrit-Project: wikidata/query/rdf
Gerrit-Branch: master
Gerrit-Owner: Smalyshev <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to