From 1c9f467680aa12f4ef6e06ae7380b2cbf5bd01d4 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Fri, 24 Feb 2012 19:35:18 +0000 Subject: [PATCH] SOLR-3080: separate sync for publishing coreStates git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1293391 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/cloud/ZkController.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 28619260c9b..609cc951ef0 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -88,6 +88,10 @@ public final class ZkController { public final static String CONFIGNAME_PROP="configName"; private Map coreStates = null; + private long coreStatesVersion; // bumped by 1 each time we serialize coreStates... sync on coreStates + private long coreStatesPublishedVersion; // last version published to ZK... sync on coreStatesPublishLock + private Object coreStatesPublishLock = new Object(); // only publish one at a time + private final Map electionContexts = Collections.synchronizedMap(new HashMap()); private SolrZkClient zkClient; @@ -951,11 +955,23 @@ public final class ZkController { private void publishState() { final String nodePath = "/node_states/" + getNodeName(); + long version; + byte[] coreStatesData; synchronized (coreStates) { + version = ++coreStatesVersion; + coreStatesData = ZkStateReader.toJSON(coreStates.values()); + } + + // if multiple threads are trying to publish state, make sure that we never write + // an older version after a newer version. + synchronized (coreStatesPublishLock) { try { - zkClient.setData(nodePath, ZkStateReader.toJSON(coreStates.values()), - true); - + if (version < coreStatesPublishedVersion) { + log.info("Another thread already published a newer coreStates: ours="+version + " lastPublished=" + coreStatesPublishedVersion); + } else { + zkClient.setData(nodePath, coreStatesData, true); + coreStatesPublishedVersion = version; // put it after so it won't be set if there's an exception + } } catch (KeeperException e) { throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "could not publish node state", e);