From 98c76da614b649ad53201476c332c91be5e7bb06 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 19 Nov 2008 00:27:14 +0000 Subject: Fix resync when query is known to return one entry. --- .../repo/replicated/ReplicatedRepository.java | 76 +++++++++++++++------- 1 file changed, 52 insertions(+), 24 deletions(-) (limited to 'src/main/java/com/amazon/carbonado/repo/replicated') diff --git a/src/main/java/com/amazon/carbonado/repo/replicated/ReplicatedRepository.java b/src/main/java/com/amazon/carbonado/repo/replicated/ReplicatedRepository.java index 8f0e45d..d3414af 100644 --- a/src/main/java/com/amazon/carbonado/repo/replicated/ReplicatedRepository.java +++ b/src/main/java/com/amazon/carbonado/repo/replicated/ReplicatedRepository.java @@ -470,7 +470,18 @@ class ReplicatedRepository Cursor masterCursor = null; try { - replicaCursor = replicaQuery.fetch(); + while (replicaCursor == null) { + try { + replicaCursor = replicaQuery.fetch(); + } catch (CorruptEncodingException e) { + S replicaWithKeyOnly = recoverReplicaKey(replicaStorage, e); + if (!deleteCorruptEntry(replicationTrigger, replicaWithKeyOnly, e)) { + // Cannot delete it, so just give up. + throw e; + } + } + } + masterCursor = masterQuery.fetch(); S lastReplicaEntry = null; @@ -512,29 +523,10 @@ class ReplicatedRepository replicaCursor.close(); replicaCursor = null; - boolean skip = true; - - Storable withKey = e.getStorableWithPrimaryKey(); - S replicaWithKeyOnly = null; + S replicaWithKeyOnly = recoverReplicaKey(replicaStorage, e); - if (withKey != null && - withKey.storableType() == replicaStorage.getStorableType()) - { - replicaWithKeyOnly = (S) withKey; - } - - if (replicaWithKeyOnly != null) { - // Delete corrupt replica entry. - try { - replicationTrigger.deleteReplica(replicaWithKeyOnly); - log.info("Deleted corrupt replica entry: " + - replicaWithKeyOnly.toStringKeyOnly(), e); - skip = false; - } catch (PersistException e2) { - log.warn("Unable to delete corrupt replica entry: " + - replicaWithKeyOnly.toStringKeyOnly(), e2); - } - } + boolean deleted = deleteCorruptEntry + (replicationTrigger, replicaWithKeyOnly, e); // Re-open (if we can) if (lastReplicaEntry == null) { @@ -542,7 +534,8 @@ class ReplicatedRepository } replicaCursor = replicaQuery.fetchAfter(lastReplicaEntry); - if (skip) { + if (deleted) { + // Skip if it cannot be deleted. try { skippedCount = replicaCursor.skipNext(++skippedCount); log.info("Skipped corrupt replica entry", e); @@ -644,6 +637,41 @@ class ReplicatedRepository } } + private S recoverReplicaKey(Storage replicaStorage, + CorruptEncodingException e) + { + Storable withKey = e.getStorableWithPrimaryKey(); + if (withKey != null && withKey.storableType() == replicaStorage.getStorableType()) { + return (S) withKey; + } + return null; + } + + private boolean deleteCorruptEntry + (ReplicationTrigger replicationTrigger, + S replicaWithKeyOnly, + CorruptEncodingException e) + throws RepositoryException + { + if (replicaWithKeyOnly == null) { + return false; + } + + final Log log = LogFactory.getLog(ReplicatedRepository.class); + + // Delete corrupt replica entry. + try { + replicationTrigger.deleteReplica(replicaWithKeyOnly); + log.info("Deleted corrupt replica entry: " + + replicaWithKeyOnly.toStringKeyOnly(), e); + return true; + } catch (PersistException e2) { + log.warn("Unable to delete corrupt replica entry: " + + replicaWithKeyOnly.toStringKeyOnly(), e2); + return false; + } + } + private Runnable prepareResyncTask (final ReplicationTrigger replicationTrigger, final ResyncCapability.Listener listener, -- cgit v1.2.3