You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2012/08/31 00:43:59 UTC
svn commit: r1379200 [10/11] - in /lucene/dev/branches/lucene3312: ./
dev-tools/ dev-tools/eclipse/ dev-tools/idea/.idea/libraries/
dev-tools/maven/ dev-tools/maven/lucene/core/
dev-tools/maven/lucene/test-framework/ dev-tools/scripts/ lucene/ lucene/a...
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java Thu Aug 30 22:43:41 2012
@@ -2,6 +2,8 @@ package org.apache.solr.cloud;
import java.io.IOException;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
@@ -15,7 +17,6 @@ import org.apache.solr.core.CoreContaine
import org.apache.solr.core.SolrCore;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,31 +83,26 @@ class ShardLeaderElectionContextBase ext
}
@Override
- void runLeaderProcess(boolean weAreReplacement)
- throws KeeperException, InterruptedException, IOException {
-
- try {
- zkClient.makePath(leaderPath,
- leaderProps == null ? null : ZkStateReader.toJSON(leaderProps),
- CreateMode.EPHEMERAL, true);
- } catch (NodeExistsException e) {
- // if a previous leader ephemeral still exists for some reason, try and
- // remove it
- zkClient.delete(leaderPath, -1, true);
- zkClient.makePath(leaderPath,
- leaderProps == null ? null : ZkStateReader.toJSON(leaderProps),
- CreateMode.EPHEMERAL, true);
- }
+ void runLeaderProcess(boolean weAreReplacement) throws KeeperException,
+ InterruptedException, IOException {
+ // this pause is important (and seems to work also at 100ms to 1 second in
+ // many cases),
+ // but I don't know why yet :*( - it must come before this publish call
+ // and can happen at the start of leader election process even
+ Thread.sleep(500);
+
+ zkClient.makePath(leaderPath, ZkStateReader.toJSON(leaderProps),
+ CreateMode.EPHEMERAL, true);
- // TODO: above we make it looks like leaderProps could be true, but here
- // you would get an NPE if it was.
- ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION,
- "leader", ZkStateReader.SHARD_ID_PROP, shardId,
- ZkStateReader.COLLECTION_PROP, collection, ZkStateReader.BASE_URL_PROP,
- leaderProps.getProperties().get(ZkStateReader.BASE_URL_PROP),
- ZkStateReader.CORE_NAME_PROP, leaderProps.getProperties().get(ZkStateReader.CORE_NAME_PROP));
+ ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION, "leader",
+ ZkStateReader.SHARD_ID_PROP, shardId, ZkStateReader.COLLECTION_PROP,
+ collection, ZkStateReader.BASE_URL_PROP, leaderProps.getProperties()
+ .get(ZkStateReader.BASE_URL_PROP), ZkStateReader.CORE_NAME_PROP,
+ leaderProps.getProperties().get(ZkStateReader.CORE_NAME_PROP),
+ ZkStateReader.STATE_PROP, ZkStateReader.ACTIVE);
Overseer.getInQueue(zkClient).offer(ZkStateReader.toJSON(m));
- }
+
+ }
}
@@ -117,66 +113,182 @@ final class ShardLeaderElectionContext e
private ZkController zkController;
private CoreContainer cc;
private SyncStrategy syncStrategy = new SyncStrategy();
+
+ private boolean afterExpiration;
public ShardLeaderElectionContext(LeaderElector leaderElector,
final String shardId, final String collection,
- final String shardZkNodeName, ZkNodeProps props, ZkController zkController, CoreContainer cc) {
+ final String shardZkNodeName, ZkNodeProps props, ZkController zkController, CoreContainer cc, boolean afterExpiration) {
super(leaderElector, shardId, collection, shardZkNodeName, props,
zkController.getZkStateReader());
this.zkController = zkController;
this.cc = cc;
+ this.afterExpiration = afterExpiration;
}
@Override
- void runLeaderProcess(boolean weAreReplacement)
- throws KeeperException, InterruptedException, IOException {
- if (cc != null) {
- String coreName = leaderProps.get(ZkStateReader.CORE_NAME_PROP);
- SolrCore core = null;
+ void runLeaderProcess(boolean weAreReplacement) throws KeeperException,
+ InterruptedException, IOException {
+ String coreName = leaderProps.get(ZkStateReader.CORE_NAME_PROP);
+
+ // clear the leader in clusterstate
+ ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION, "leader",
+ ZkStateReader.SHARD_ID_PROP, shardId, ZkStateReader.COLLECTION_PROP,
+ collection);
+ Overseer.getInQueue(zkClient).offer(ZkStateReader.toJSON(m));
+
+ waitForReplicasToComeUp(weAreReplacement);
+
+ // wait for local leader state to clear...
+ // int tries = 0;
+ // while (zkController.getClusterState().getLeader(collection, shardId) !=
+ // null) {
+ // System.out.println("leader still shown " + tries + " " +
+ // zkController.getClusterState().getLeader(collection, shardId));
+ // Thread.sleep(1000);
+ // tries++;
+ // if (tries == 30) {
+ // break;
+ // }
+ // }
+ // Thread.sleep(1000);
+
+ SolrCore core = null;
+ try {
+
+ core = cc.getCore(coreName);
+
+ if (core == null) {
+ cancelElection();
+ throw new SolrException(ErrorCode.SERVER_ERROR,
+ "Fatal Error, SolrCore not found:" + coreName + " in "
+ + cc.getCoreNames());
+ }
+
+ // should I be leader?
+ if (weAreReplacement && !shouldIBeLeader(leaderProps, core)) {
+ // System.out.println("there is a better leader candidate it appears");
+ rejoinLeaderElection(leaderSeqPath, core);
+ return;
+ }
+
+ if (weAreReplacement) {
+ log.info("I may be the new leader - try and sync");
+ // we are going to attempt to be the leader
+ // first cancel any current recovery
+ core.getUpdateHandler().getSolrCoreState().cancelRecovery();
+ boolean success = syncStrategy.sync(zkController, core, leaderProps);
+ // solrcloud_debug
+ // try {
+ // RefCounted<SolrIndexSearcher> searchHolder =
+ // core.getNewestSearcher(false);
+ // SolrIndexSearcher searcher = searchHolder.get();
+ // try {
+ // System.out.println(core.getCoreDescriptor().getCoreContainer().getZkController().getNodeName()
+ // + " synched "
+ // + searcher.search(new MatchAllDocsQuery(), 1).totalHits);
+ // } finally {
+ // searchHolder.decref();
+ // }
+ // } catch (Exception e) {
+ //
+ // }
+ if (!success && anyoneElseActive()) {
+ rejoinLeaderElection(leaderSeqPath, core);
+ return;
+ }
+ }
+
+ log.info("I am the new leader: "
+ + ZkCoreNodeProps.getCoreUrl(leaderProps));
+
+ } finally {
+ if (core != null) {
+ core.close();
+ }
+ }
+
+ try {
+ super.runLeaderProcess(weAreReplacement);
+ } catch (Throwable t) {
+ cancelElection();
try {
-
core = cc.getCore(coreName);
-
- if (core == null) {
- cancelElection();
- throw new SolrException(ErrorCode.SERVER_ERROR, "Fatal Error, SolrCore not found:" + coreName + " in " + cc.getCoreNames());
+ core.getCoreDescriptor().getCloudDescriptor().isLeader = false;
+ if (!cc.isShutDown()) {
+ // we could not publish ourselves as leader - rejoin election
+ rejoinLeaderElection(coreName, core);
}
- // should I be leader?
- if (weAreReplacement && !shouldIBeLeader(leaderProps)) {
- // System.out.println("there is a better leader candidate it appears");
- rejoinLeaderElection(leaderSeqPath, core);
- return;
+ } finally {
+ if (core != null) {
+ core.close();
}
+ }
+
+ }
+
+ try {
+ core = cc.getCore(coreName);
+ // we do this after the above super. call so that we don't
+ // briefly think we are the leader and then end up not being
+ // able to publish that we are the leader.
+ core.getCoreDescriptor().getCloudDescriptor().isLeader = true;
+ } finally {
+ if (core != null) {
+ core.close();
+ }
+ }
+
+ }
- if (weAreReplacement) {
- if (zkClient.exists(leaderPath, true)) {
- zkClient.delete(leaderPath, -1, true);
+ private void waitForReplicasToComeUp(boolean weAreReplacement)
+ throws InterruptedException {
+ int retries = 300; // ~ 5 min
+ boolean tryAgain = true;
+ Slice slices = zkController.getClusterState().getSlice(collection, shardId);
+ log.info("Running the leader process. afterExperiation=" + afterExpiration);
+ while (tryAgain || slices == null) {
+
+ // wait for everyone to be up
+ if (slices != null) {
+ Map<String,ZkNodeProps> shards = slices.getShards();
+ Set<Entry<String,ZkNodeProps>> entrySet = shards.entrySet();
+ int found = 0;
+ tryAgain = false;
+ for (Entry<String,ZkNodeProps> entry : entrySet) {
+ ZkCoreNodeProps props = new ZkCoreNodeProps(entry.getValue());
+ if (props.getState().equals(ZkStateReader.ACTIVE)
+ && zkController.getClusterState().liveNodesContain(
+ props.getNodeName())) {
+ found++;
}
- log.info("I may be the new leader - try and sync");
- // we are going to attempt to be the leader
- // first cancel any current recovery
- core.getUpdateHandler().getSolrCoreState().cancelRecovery();
- boolean success = syncStrategy.sync(zkController, core, leaderProps);
- if (!success && anyoneElseActive()) {
- rejoinLeaderElection(leaderSeqPath, core);
- return;
- }
}
- log.info("I am the new leader: " + ZkCoreNodeProps.getCoreUrl(leaderProps));
- // If I am going to be the leader I have to be active
- core.getUpdateHandler().getSolrCoreState().cancelRecovery();
- zkController.publish(core.getCoreDescriptor(), ZkStateReader.ACTIVE);
+ // on startup and after connection timeout, wait for all known shards
+ if ((afterExpiration || !weAreReplacement)
+ && found >= slices.getShards().size()) {
+ log.info("Enough replicas found to continue.");
+ tryAgain = false;
+ } else if (!afterExpiration && found >= slices.getShards().size() - 1) {
+ // a previous leader went down - wait for one less than the total
+ // known shards
+ log.info("Enough replicas found to continue.");
+ tryAgain = false;
+ } else {
+ log.info("Waiting until we see more replicas up");
+ }
- } finally {
- if (core != null ) {
- core.close();
+ retries--;
+ if (retries == 0) {
+ log.info("Was waiting for replicas to come up, but they are taking too long - assuming they won't come back till later");
+ break;
}
}
-
+ if (tryAgain) {
+ Thread.sleep(1000);
+ slices = zkController.getClusterState().getSlice(collection, shardId);
+ }
}
-
- super.runLeaderProcess(weAreReplacement);
}
private void rejoinLeaderElection(String leaderSeqPath, SolrCore core)
@@ -195,7 +307,8 @@ final class ShardLeaderElectionContext e
leaderElector.joinElection(this);
}
- private boolean shouldIBeLeader(ZkNodeProps leaderProps) {
+ private boolean shouldIBeLeader(ZkNodeProps leaderProps, SolrCore core) {
+ log.info("Checking if I should try and be the leader.");
ClusterState clusterState = zkController.getZkStateReader().getClusterState();
Map<String,Slice> slices = clusterState.getSlices(this.collection);
Slice slice = slices.get(shardId);
@@ -210,6 +323,7 @@ final class ShardLeaderElectionContext e
&& clusterState.liveNodesContain(shard.getValue().get(
ZkStateReader.NODE_NAME_PROP))) {
// we are alive
+ log.info("I am Active and live, it's okay to be the leader.");
return true;
}
}
@@ -222,7 +336,19 @@ final class ShardLeaderElectionContext e
foundSomeoneElseActive = true;
}
}
-
+ if (!foundSomeoneElseActive) {
+ log.info("I am not Active but no one else is either, it's okay to be the leader");
+ try {
+ zkController.publish(core.getCoreDescriptor(), ZkStateReader.ACTIVE);
+ } catch (KeeperException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ }
+ } else {
+ log.info("I am not Active and someone else appears to be a better leader candidate.");
+ }
return !foundSomeoneElseActive;
}
@@ -261,24 +387,16 @@ final class OverseerElectionContext exte
}
@Override
- void runLeaderProcess(boolean weAreReplacement) throws KeeperException, InterruptedException {
+ void runLeaderProcess(boolean weAreReplacement) throws KeeperException,
+ InterruptedException {
- final String id = leaderSeqPath.substring(leaderSeqPath.lastIndexOf("/")+1);
+ final String id = leaderSeqPath
+ .substring(leaderSeqPath.lastIndexOf("/") + 1);
ZkNodeProps myProps = new ZkNodeProps("id", id);
-
- try {
- zkClient.makePath(leaderPath,
- ZkStateReader.toJSON(myProps),
- CreateMode.EPHEMERAL, true);
- } catch (NodeExistsException e) {
- // if a previous leader ephemeral still exists for some reason, try and
- // remove it
- zkClient.delete(leaderPath, -1, true);
- zkClient.makePath(leaderPath,
- ZkStateReader.toJSON(myProps),
- CreateMode.EPHEMERAL, true);
- }
-
+
+ zkClient.makePath(leaderPath, ZkStateReader.toJSON(myProps),
+ CreateMode.EPHEMERAL, true);
+
overseer.start(id);
}
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java Thu Aug 30 22:43:41 2012
@@ -93,6 +93,13 @@ public class LeaderElector {
sortSeqs(seqs);
List<Integer> intSeqs = getSeqs(seqs);
if (seq <= intSeqs.get(0)) {
+ // first we delete the node advertising the old leader in case the ephem is still there
+ try {
+ zkClient.delete(context.leaderPath, -1, true);
+ } catch(Exception e) {
+ // fine
+ }
+
runIamLeaderProcess(context, replacement);
} else {
// I am not the leader - watch the node below me
@@ -138,6 +145,7 @@ public class LeaderElector {
} catch (KeeperException.SessionExpiredException e) {
throw e;
} catch (KeeperException e) {
+ SolrException.log(log, "Failed setting watch", e);
// we couldn't set our watch - the node before us may already be down?
// we need to check if we are the leader again
checkIfIamLeader(seq, context, true);
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/Overseer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/Overseer.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/Overseer.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/Overseer.java Thu Aug 30 22:43:41 2012
@@ -126,8 +126,8 @@ public class Overseer {
final String operation = message.get(QUEUE_OPERATION);
clusterState = processMessage(clusterState, message, operation);
- byte[] processed = stateUpdateQueue.remove();
- workQueue.offer(processed);
+ workQueue.offer(head);
+ stateUpdateQueue.remove();
head = stateUpdateQueue.peek();
}
zkClient.setData(ZkStateReader.CLUSTER_STATE,
@@ -166,17 +166,19 @@ public class Overseer {
} else if (DELETECORE.equals(operation)) {
clusterState = removeCore(clusterState, message);
} else if (ZkStateReader.LEADER_PROP.equals(operation)) {
+
StringBuilder sb = new StringBuilder();
String baseUrl = message.get(ZkStateReader.BASE_URL_PROP);
String coreName = message.get(ZkStateReader.CORE_NAME_PROP);
sb.append(baseUrl);
- if (!baseUrl.endsWith("/")) sb.append("/");
+ if (baseUrl != null && !baseUrl.endsWith("/")) sb.append("/");
sb.append(coreName == null ? "" : coreName);
- if (!(sb.substring(sb.length() - 1).equals("/"))) sb
- .append("/");
+ if (!(sb.substring(sb.length() - 1).equals("/"))) sb.append("/");
clusterState = setShardLeader(clusterState,
message.get(ZkStateReader.COLLECTION_PROP),
- message.get(ZkStateReader.SHARD_ID_PROP), sb.toString());
+ message.get(ZkStateReader.SHARD_ID_PROP),
+ sb.length() > 0 ? sb.toString() : null);
+
} else {
throw new RuntimeException("unknown operation:" + operation
+ " contents:" + message.getProperties());
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java Thu Aug 30 22:43:41 2012
@@ -185,6 +185,7 @@ public class RecoveryStrategy extends Th
prepCmd.setCoreNodeName(coreZkNodeName);
prepCmd.setState(ZkStateReader.RECOVERING);
prepCmd.setCheckLive(true);
+ prepCmd.setOnlyIfLeader(true);
prepCmd.setPauseFor(6000);
server.request(prepCmd);
@@ -239,6 +240,7 @@ public class RecoveryStrategy extends Th
return;
}
+ boolean firstTime = true;
List<Long> recentVersions;
UpdateLog.RecentUpdates recentUpdates = null;
@@ -273,9 +275,6 @@ public class RecoveryStrategy extends Th
log.info("###### startupVersions=" + startingVersions);
}
-
- boolean firstTime = true;
-
if (recoveringAfterStartup) {
// if we're recovering after startup (i.e. we have been down), then we need to know what the last versions were
// when we went down. We may have received updates since then.
@@ -305,7 +304,10 @@ public class RecoveryStrategy extends Th
String ourUrl = ZkCoreNodeProps.getCoreUrl(baseUrl, coreName);
boolean isLeader = leaderUrl.equals(ourUrl);
- if (isLeader) {
+ if (isLeader && !cloudDesc.isLeader) {
+ throw new SolrException(ErrorCode.SERVER_ERROR, "Cloud state still says we are leader.");
+ }
+ if (cloudDesc.isLeader) {
// we are now the leader - no one else must have been suitable
log.warn("We have not yet recovered - but we are now the leader! core=" + coreName);
log.info("Finished recovery process. core=" + coreName);
@@ -333,9 +335,6 @@ public class RecoveryStrategy extends Th
new ModifiableSolrParams());
core.getUpdateHandler().commit(new CommitUpdateCommand(req, false));
log.info("PeerSync Recovery was successful - registering as Active. core=" + coreName);
- // System.out
- // .println("Sync Recovery was successful - registering as Active "
- // + zkController.getNodeName());
// solrcloud_debug
// try {
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java Thu Aug 30 22:43:41 2012
@@ -108,7 +108,8 @@ public class SyncStrategy {
if (!success
&& !areAnyOtherReplicasActive(zkController, leaderProps, collection,
shardId)) {
- log.info("Sync was not a success but no on else i active! I am the leader");
+ log.info("Sync was not a success but no one else is active! I am the leader");
+ zkController.publish(core.getCoreDescriptor(), ZkStateReader.ACTIVE);
success = true;
}
@@ -224,14 +225,14 @@ public class SyncStrategy {
requestRecovery(((ShardCoreRequest)srsp.getShardRequest()).baseUrl, ((ShardCoreRequest)srsp.getShardRequest()).coreName);
- } catch (Exception e) {
- SolrException.log(log, ZkCoreNodeProps.getCoreUrl(leaderProps) + ": Could not tell a replica to recover", e);
+ } catch (Throwable t) {
+ SolrException.log(log, ZkCoreNodeProps.getCoreUrl(leaderProps) + ": Could not tell a replica to recover", t);
}
} else {
log.info(ZkCoreNodeProps.getCoreUrl(leaderProps) + ": " + " sync completed with " + srsp.getShardAddress());
}
+
}
-
}
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/cloud/ZkController.java Thu Aug 30 22:43:41 2012
@@ -41,6 +41,7 @@ import org.apache.solr.common.SolrExcept
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.OnReconnect;
import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkClientConnectionStrategy;
import org.apache.solr.common.cloud.ZkCmdExecutor;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkNodeProps;
@@ -112,8 +113,12 @@ public final class ZkController {
private final String nodeName; // example: 127.0.0.1:54065_solr
private final String baseURL; // example: http://127.0.0.1:54065/solr
+
private LeaderElector overseerElector;
+
+ // for now, this can be null in tests, in which case recovery will be inactive, and other features
+ // may accept defaults or use mocks rather than pulling things from a CoreContainer
private CoreContainer cc;
protected volatile Overseer overseer;
@@ -181,7 +186,11 @@ public final class ZkController {
// TODO: we need to think carefully about what happens when it was
// a leader that was expired - as well as what to do about leaders/overseers
// with connection loss
- register(descriptor.getName(), descriptor, true);
+ try {
+ register(descriptor.getName(), descriptor, true, true);
+ } catch (Throwable t) {
+ SolrException.log(log, "Error registering SolrCore", t);
+ }
}
}
@@ -200,6 +209,45 @@ public final class ZkController {
});
+
+ zkClient.getZkClientConnectionStrategy().addDisconnectedListener(new ZkClientConnectionStrategy.DisconnectedListener() {
+
+ @Override
+ public void disconnected() {
+ List<CoreDescriptor> descriptors = registerOnReconnect.getCurrentDescriptors();
+ // re register all descriptors
+ if (descriptors != null) {
+ for (CoreDescriptor descriptor : descriptors) {
+ descriptor.getCloudDescriptor().isLeader = false;
+ }
+ }
+ }
+ });
+
+ zkClient.getZkClientConnectionStrategy().addConnectedListener(new ZkClientConnectionStrategy.ConnectedListener() {
+
+ @Override
+ public void connected() {
+ List<CoreDescriptor> descriptors = registerOnReconnect.getCurrentDescriptors();
+ if (descriptors != null) {
+ for (CoreDescriptor descriptor : descriptors) {
+ CloudDescriptor cloudDesc = descriptor.getCloudDescriptor();
+ String leaderUrl;
+ try {
+ leaderUrl = getLeaderProps(cloudDesc.getCollectionName(), cloudDesc.getShardId())
+ .getCoreUrl();
+ } catch (InterruptedException e) {
+ throw new RuntimeException();
+ }
+ String ourUrl = ZkCoreNodeProps.getCoreUrl(getBaseUrl(), descriptor.getName());
+ boolean isLeader = leaderUrl.equals(ourUrl);
+ log.info("SolrCore connected to ZooKeeper - we are " + ourUrl + " and leader is " + leaderUrl);
+ cloudDesc.isLeader = isLeader;
+ }
+ }
+ }
+ });
+
this.overseerJobQueue = Overseer.getInQueue(zkClient);
this.overseerCollectionQueue = Overseer.getCollectionQueue(zkClient);
cmdExecutor = new ZkCmdExecutor();
@@ -468,7 +516,7 @@ public final class ZkController {
* @throws Exception
*/
public String register(String coreName, final CoreDescriptor desc) throws Exception {
- return register(coreName, desc, false);
+ return register(coreName, desc, false, false);
}
@@ -478,10 +526,11 @@ public final class ZkController {
* @param coreName
* @param desc
* @param recoverReloadedCores
+ * @param afterExpiration
* @return the shardId for the SolrCore
* @throws Exception
*/
- public String register(String coreName, final CoreDescriptor desc, boolean recoverReloadedCores) throws Exception {
+ public String register(String coreName, final CoreDescriptor desc, boolean recoverReloadedCores, boolean afterExpiration) throws Exception {
final String baseUrl = getBaseUrl();
final CloudDescriptor cloudDesc = desc.getCloudDescriptor();
@@ -506,7 +555,7 @@ public final class ZkController {
ZkNodeProps leaderProps = new ZkNodeProps(props);
try {
- joinElection(desc);
+ joinElection(desc, afterExpiration);
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
@@ -517,25 +566,7 @@ public final class ZkController {
throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e);
}
- // rather than look in the cluster state file, we go straight to the zknodes
- // here, because on cluster restart there could be stale leader info in the
- // cluster state node that won't be updated for a moment
- String leaderUrl = getLeaderProps(collection, cloudDesc.getShardId()).getCoreUrl();
-
- // now wait until our currently cloud state contains the latest leader
- String clusterStateLeader = zkStateReader.getLeaderUrl(collection, shardId, 30000);
- int tries = 0;
- while (!leaderUrl.equals(clusterStateLeader)) {
- if (tries == 60) {
- throw new SolrException(ErrorCode.SERVER_ERROR,
- "There is conflicting information about the leader of shard: "
- + cloudDesc.getShardId() + " our state says:" + clusterStateLeader + " but zookeeper says:" + leaderUrl);
- }
- Thread.sleep(1000);
- tries++;
- clusterStateLeader = zkStateReader.getLeaderUrl(collection, shardId, 30000);
- leaderUrl = getLeaderProps(collection, cloudDesc.getShardId()).getCoreUrl();
- }
+ String leaderUrl = getLeader(cloudDesc);
String ourUrl = ZkCoreNodeProps.getCoreUrl(baseUrl, coreName);
log.info("We are " + ourUrl + " and leader is " + leaderUrl);
@@ -568,8 +599,7 @@ public final class ZkController {
} else {
log.info("No LogReplay needed for core="+core.getName() + " baseURL=" + baseUrl);
}
- }
-
+ }
boolean didRecovery = checkRecovery(coreName, desc, recoverReloadedCores, isLeader, cloudDesc,
collection, coreZkNodeName, shardId, leaderProps, core, cc);
if (!didRecovery) {
@@ -580,12 +610,52 @@ public final class ZkController {
core.close();
}
}
+
// make sure we have an update cluster state right away
zkStateReader.updateClusterState(true);
return shardId;
}
+
+ private String getLeader(final CloudDescriptor cloudDesc) {
+
+ String collection = cloudDesc.getCollectionName();
+ String shardId = cloudDesc.getShardId();
+ // rather than look in the cluster state file, we go straight to the zknodes
+ // here, because on cluster restart there could be stale leader info in the
+ // cluster state node that won't be updated for a moment
+ String leaderUrl;
+ try {
+ leaderUrl = getLeaderProps(collection, cloudDesc.getShardId())
+ .getCoreUrl();
+
+ // now wait until our currently cloud state contains the latest leader
+ String clusterStateLeader = zkStateReader.getLeaderUrl(collection,
+ shardId, 30000);
+ int tries = 0;
+ while (!leaderUrl.equals(clusterStateLeader)) {
+ if (tries == 60) {
+ throw new SolrException(ErrorCode.SERVER_ERROR,
+ "There is conflicting information about the leader of shard: "
+ + cloudDesc.getShardId() + " our state says:"
+ + clusterStateLeader + " but zookeeper says:" + leaderUrl);
+ }
+ Thread.sleep(1000);
+ tries++;
+ clusterStateLeader = zkStateReader.getLeaderUrl(collection, shardId,
+ 30000);
+ leaderUrl = getLeaderProps(collection, cloudDesc.getShardId())
+ .getCoreUrl();
+ }
+
+ } catch (Exception e) {
+ log.error("Error getting leader from zk", e);
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "Error getting leader from zk", e);
+ }
+ return leaderUrl;
+ }
/**
* Get leader props directly from zk nodes.
@@ -597,8 +667,9 @@ public final class ZkController {
* @throws InterruptedException
*/
private ZkCoreNodeProps getLeaderProps(final String collection,
- final String slice) throws KeeperException, InterruptedException {
+ final String slice) throws InterruptedException {
int iterCount = 60;
+ Exception exp = null;
while (iterCount-- > 0) {
try {
byte[] data = zkClient.getData(
@@ -607,15 +678,21 @@ public final class ZkController {
ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(
ZkNodeProps.load(data));
return leaderProps;
- } catch (NoNodeException e) {
+ } catch (InterruptedException e) {
+ throw e;
+ } catch (Exception e) {
+ exp = e;
Thread.sleep(500);
}
+ if (cc.isShutDown()) {
+ throw new RuntimeException("CoreContainer is shutdown");
+ }
}
- throw new RuntimeException("Could not get leader props");
+ throw new RuntimeException("Could not get leader props", exp);
}
- private void joinElection(CoreDescriptor cd) throws InterruptedException, KeeperException, IOException {
+ private void joinElection(CoreDescriptor cd, boolean afterExpiration) throws InterruptedException, KeeperException, IOException {
String shardId = cd.getCloudDescriptor().getShardId();
@@ -631,7 +708,7 @@ public final class ZkController {
.getCollectionName();
ElectionContext context = new ShardLeaderElectionContext(leaderElector, shardId,
- collection, coreZkNodeName, ourProps, this, cc);
+ collection, coreZkNodeName, ourProps, this, cc, afterExpiration);
leaderElector.setup(context);
electionContexts.put(coreZkNodeName, context);
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/CoreContainer.java Thu Aug 30 22:43:41 2012
@@ -598,15 +598,16 @@ public class CoreContainer
}
cores.clear();
} finally {
+ if (shardHandlerFactory != null) {
+ shardHandlerFactory.close();
+ }
+ // we want to close zk stuff last
if(zkController != null) {
zkController.close();
}
if (zkServer != null) {
zkServer.stop();
}
- if (shardHandlerFactory != null) {
- shardHandlerFactory.close();
- }
}
}
}
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/SolrCore.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/core/SolrCore.java Thu Aug 30 22:43:41 2012
@@ -65,6 +65,7 @@ import org.apache.solr.search.ValueSourc
import org.apache.solr.update.DirectUpdateHandler2;
import org.apache.solr.update.SolrIndexWriter;
import org.apache.solr.update.UpdateHandler;
+import org.apache.solr.update.VersionInfo;
import org.apache.solr.update.processor.DistributedUpdateProcessorFactory;
import org.apache.solr.update.processor.LogUpdateProcessorFactory;
import org.apache.solr.update.processor.RunUpdateProcessorFactory;
@@ -593,6 +594,25 @@ public final class SolrCore implements S
schema = new IndexSchema(config, IndexSchema.DEFAULT_SCHEMA_FILE, null);
}
+ if (null != cd && null != cd.getCloudDescriptor()) {
+ // we are evidently running in cloud mode.
+ //
+ // In cloud mode, version field is required for correct consistency
+ // ideally this check would be more fine grained, and individual features
+ // would assert it when they initialize, but DistribuedUpdateProcessor
+ // is currently a big ball of wax that does more then just distributing
+ // updates (ie: partial document updates), so it needs to work in no cloud
+ // mode as well, and can't assert version field support on init.
+
+ try {
+ Object ignored = VersionInfo.getAndCheckVersionField(schema);
+ } catch (SolrException e) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "Schema will not work with SolrCloud mode: " +
+ e.getMessage(), e);
+ }
+ }
+
//Initialize JMX
if (config.jmxConfig.enabled) {
infoRegistry = new JmxMonitoredMap<String, SolrInfoMBean>(name, String.valueOf(this.hashCode()), config.jmxConfig);
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java Thu Aug 30 22:43:41 2012
@@ -19,10 +19,13 @@ package org.apache.solr.handler.admin;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -36,6 +39,7 @@ import org.apache.solr.cloud.ZkControlle
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.HashPartitioner;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -57,6 +61,7 @@ import org.apache.solr.request.SolrQuery
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.update.MergeIndexesCommand;
+import org.apache.solr.update.SplitIndexCommand;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.util.NumberUtils;
@@ -171,6 +176,11 @@ public class CoreAdminHandler extends Re
break;
}
+ case SPLIT: {
+ doPersist = this.handleSplitAction(req, rsp);
+ break;
+ }
+
case PREPRECOVERY: {
this.handleWaitForStateAction(req, rsp);
break;
@@ -202,6 +212,62 @@ public class CoreAdminHandler extends Re
rsp.setHttpCaching(false);
}
+
+ protected boolean handleSplitAction(SolrQueryRequest adminReq, SolrQueryResponse rsp) throws IOException {
+ SolrParams params = adminReq.getParams();
+ // partitions=N (split into N partitions, leaving it up to solr what the ranges are and where to put them)
+ // path - multiValued param, or comma separated param? Only creates indexes, not cores
+
+ List<HashPartitioner.Range> ranges = null;
+ // boolean closeDirectories = true;
+ // DirectoryFactory dirFactory = null;
+
+
+ String cname = params.get(CoreAdminParams.CORE, "");
+ SolrCore core = coreContainer.getCore(cname);
+ SolrQueryRequest req = new LocalSolrQueryRequest(core, params);
+ try {
+
+ String[] pathsArr = params.getParams("path");
+ List<String> paths = null;
+
+ String rangesStr = params.get("ranges"); // ranges=a-b,c-d,e-f
+
+
+ // dirFactory = core.getDirectoryFactory();
+
+
+ if (pathsArr != null) {
+
+ paths = Arrays.asList(pathsArr);
+
+ if (rangesStr == null) {
+ HashPartitioner hp = new HashPartitioner();
+ // should this be static?
+ // TODO: use real range if we know it. If we don't know it, we should prob
+ // split on every other doc rather than on a hash?
+ ranges = hp.partitionRange(pathsArr.length, Integer.MIN_VALUE, Integer.MAX_VALUE);
+ }
+
+ }
+
+
+ SplitIndexCommand cmd = new SplitIndexCommand(req, paths, ranges);
+ core.getUpdateHandler().split(cmd);
+
+ } catch (Exception e) {
+ log.error("ERROR executing split:", e);
+ throw new RuntimeException(e);
+
+ } finally {
+ if (req != null) req.close();
+ if (core != null) core.close();
+ }
+
+ return false;
+ }
+
+
protected boolean handleMergeAction(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
SolrParams params = req.getParams();
String cname = params.required().get(CoreAdminParams.CORE);
@@ -721,6 +787,21 @@ public class CoreAdminHandler extends Re
props.put(ZkStateReader.NODE_NAME_PROP, zkController.getNodeName());
boolean success = syncStrategy.sync(zkController, core, new ZkNodeProps(props));
+ // solrcloud_debug
+// try {
+// RefCounted<SolrIndexSearcher> searchHolder =
+// core.getNewestSearcher(false);
+// SolrIndexSearcher searcher = searchHolder.get();
+// try {
+// System.out.println(core.getCoreDescriptor().getCoreContainer().getZkController().getNodeName()
+// + " synched "
+// + searcher.search(new MatchAllDocsQuery(), 1).totalHits);
+// } finally {
+// searchHolder.decref();
+// }
+// } catch (Exception e) {
+//
+// }
if (!success) {
throw new SolrException(ErrorCode.SERVER_ERROR, "Sync Failed");
}
@@ -750,8 +831,11 @@ public class CoreAdminHandler extends Re
String coreNodeName = params.get("coreNodeName");
String waitForState = params.get("state");
Boolean checkLive = params.getBool("checkLive");
+ Boolean onlyIfLeader = params.getBool("onlyIfLeader");
int pauseFor = params.getInt("pauseFor", 0);
+
+
String state = null;
boolean live = false;
int retry = 0;
@@ -764,6 +848,12 @@ public class CoreAdminHandler extends Re
+ cname);
}
if (core != null) {
+ if (onlyIfLeader != null && onlyIfLeader) {
+ if (!core.getCoreDescriptor().getCloudDescriptor().isLeader()) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, "We are not the leader");
+ }
+ }
+
// wait until we are sure the recovering node is ready
// to accept updates
CloudDescriptor cloudDescriptor = core.getCoreDescriptor()
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/CircularList.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/CircularList.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/CircularList.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/CircularList.java Thu Aug 30 22:43:41 2012
@@ -1,154 +1,154 @@
-/*
- * 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.solr.logging;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * FIFO Circular List.
- *
- * Once the size is reached, it will overwrite previous entries
- *
- */
-public class CircularList<T> implements Iterable<T>
-{
- private T[] data;
- private int head=0;
- private int tail=0;
- private int size=0;
-
- @SuppressWarnings("unchecked")
- public CircularList(int size) {
- data = (T[])new Object[size];
- }
-
- @SuppressWarnings("unchecked")
- public synchronized void resize(int newsize) {
- if(newsize==this.size) return;
-
- T[] vals = (T[])new Object[newsize];
- int i = 0;
- if(newsize>size) {
- for(i=0; i<size; i++) {
- vals[i] = data[convert(i)];
- }
- }
- else {
- int off=size-newsize;
- for(i=0; i<newsize; i++) {
- vals[i] = data[convert(i+off)];
- }
- }
- data = vals;
- head = 0;
- tail = i;
- }
-
- private int convert(int index) {
- return (index + head) % data.length;
- }
-
- public boolean isEmpty() {
- return head == tail; // or size == 0
- }
-
- public int size() {
- return size;
- }
-
- public int getBufferSize() {
- return data.length;
- }
-
- private void checkIndex(int index) {
- if (index >= size || index < 0)
- throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
- }
-
- public T get(int index) {
- checkIndex(index);
- return data[convert(index)];
- }
-
- public synchronized void add(T o) {
- data[tail] = o;
- tail = (tail+1)%data.length;
- if( size == data.length ) {
- head = (head+1)%data.length;
- }
- size++;
- if( size > data.length ) {
- size = data.length;
- }
- }
-
- public synchronized void clear() {
- for( int i=0; i<data.length; i++ ) {
- data[i] = null; // for GC
- }
- head = tail = size = 0;
- }
-
- public List<T> toList()
- {
- ArrayList<T> list = new ArrayList<T>( size );
- for( int i=0; i<size; i++ ) {
- list.add( data[convert(i)] );
- }
- return list;
- }
-
- @Override
- public String toString()
- {
- StringBuilder str = new StringBuilder();
- str.append( "[" );
- for( int i=0; i<size; i++ ) {
- if( i > 0 ) {
- str.append( "," );
- }
- str.append( data[convert(i)] );
- }
- str.append( "]" );
- return str.toString();
- }
-
- @Override
- public Iterator<T> iterator() {
- return new Iterator<T>() {
- int idx = 0;
-
- @Override
- public boolean hasNext() {
- return idx<size;
- }
-
- @Override
- public T next() {
- return get( idx++ );
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-}
+/*
+ * 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.solr.logging;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * FIFO Circular List.
+ *
+ * Once the size is reached, it will overwrite previous entries
+ *
+ */
+public class CircularList<T> implements Iterable<T>
+{
+ private T[] data;
+ private int head=0;
+ private int tail=0;
+ private int size=0;
+
+ @SuppressWarnings("unchecked")
+ public CircularList(int size) {
+ data = (T[])new Object[size];
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void resize(int newsize) {
+ if(newsize==this.size) return;
+
+ T[] vals = (T[])new Object[newsize];
+ int i = 0;
+ if(newsize>size) {
+ for(i=0; i<size; i++) {
+ vals[i] = data[convert(i)];
+ }
+ }
+ else {
+ int off=size-newsize;
+ for(i=0; i<newsize; i++) {
+ vals[i] = data[convert(i+off)];
+ }
+ }
+ data = vals;
+ head = 0;
+ tail = i;
+ }
+
+ private int convert(int index) {
+ return (index + head) % data.length;
+ }
+
+ public boolean isEmpty() {
+ return head == tail; // or size == 0
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public int getBufferSize() {
+ return data.length;
+ }
+
+ private void checkIndex(int index) {
+ if (index >= size || index < 0)
+ throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
+ }
+
+ public T get(int index) {
+ checkIndex(index);
+ return data[convert(index)];
+ }
+
+ public synchronized void add(T o) {
+ data[tail] = o;
+ tail = (tail+1)%data.length;
+ if( size == data.length ) {
+ head = (head+1)%data.length;
+ }
+ size++;
+ if( size > data.length ) {
+ size = data.length;
+ }
+ }
+
+ public synchronized void clear() {
+ for( int i=0; i<data.length; i++ ) {
+ data[i] = null; // for GC
+ }
+ head = tail = size = 0;
+ }
+
+ public List<T> toList()
+ {
+ ArrayList<T> list = new ArrayList<T>( size );
+ for( int i=0; i<size; i++ ) {
+ list.add( data[convert(i)] );
+ }
+ return list;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.append( "[" );
+ for( int i=0; i<size; i++ ) {
+ if( i > 0 ) {
+ str.append( "," );
+ }
+ str.append( data[convert(i)] );
+ }
+ str.append( "]" );
+ return str.toString();
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ int idx = 0;
+
+ @Override
+ public boolean hasNext() {
+ return idx<size;
+ }
+
+ @Override
+ public T next() {
+ return get( idx++ );
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+}
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LogWatcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LogWatcher.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LogWatcher.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LogWatcher.java Thu Aug 30 22:43:41 2012
@@ -1,107 +1,107 @@
-/*
- * 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.solr.logging;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.core.CoreContainer;
-
-/**
- * A Class to monitor Logging events and hold N events in memory
- *
- * This is abstract so we can support both JUL and Log4j (and other logging platforms)
- */
-public abstract class LogWatcher<E> {
-
- protected CircularList<E> history;
- protected long last = -1;
-
- /**
- * @return The implementation name
- */
- public abstract String getName();
-
- /**
- * @return The valid level names for this framework
- */
- public abstract List<String> getAllLevels();
-
- /**
- * Sets the log level within this framework
- */
- public abstract void setLogLevel(String category, String level);
-
- /**
- * @return all registered loggers
- */
- public abstract Collection<LoggerInfo> getAllLoggers();
-
- public abstract void setThreshold(String level);
- public abstract String getThreshold();
-
- public void add(E event, long timstamp) {
- history.add(event);
- last = timstamp;
- }
-
- public long getLastEvent() {
- return last;
- }
-
- public int getHistorySize() {
- return (history==null) ? -1 : history.getBufferSize();
- }
-
- public SolrDocumentList getHistory(long since, AtomicBoolean found) {
- if(history==null) {
- return null;
- }
-
- SolrDocumentList docs = new SolrDocumentList();
- Iterator<E> iter = history.iterator();
- while(iter.hasNext()) {
- E e = iter.next();
- long ts = getTimestamp(e);
- if(ts == since) {
- if(found!=null) {
- found.set(true);
- }
- }
- if(ts>since) {
- docs.add(toSolrDocument(e));
- }
- }
- docs.setNumFound(docs.size()); // make it not look too funny
- return docs;
- }
-
- public abstract long getTimestamp(E event);
- public abstract SolrDocument toSolrDocument(E event);
-
- public abstract void registerListener(ListenerConfig cfg, CoreContainer container);
-
- public void reset() {
- history.clear();
- last = -1;
- }
+/*
+ * 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.solr.logging;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.core.CoreContainer;
+
+/**
+ * A Class to monitor Logging events and hold N events in memory
+ *
+ * This is abstract so we can support both JUL and Log4j (and other logging platforms)
+ */
+public abstract class LogWatcher<E> {
+
+ protected CircularList<E> history;
+ protected long last = -1;
+
+ /**
+ * @return The implementation name
+ */
+ public abstract String getName();
+
+ /**
+ * @return The valid level names for this framework
+ */
+ public abstract List<String> getAllLevels();
+
+ /**
+ * Sets the log level within this framework
+ */
+ public abstract void setLogLevel(String category, String level);
+
+ /**
+ * @return all registered loggers
+ */
+ public abstract Collection<LoggerInfo> getAllLoggers();
+
+ public abstract void setThreshold(String level);
+ public abstract String getThreshold();
+
+ public void add(E event, long timstamp) {
+ history.add(event);
+ last = timstamp;
+ }
+
+ public long getLastEvent() {
+ return last;
+ }
+
+ public int getHistorySize() {
+ return (history==null) ? -1 : history.getBufferSize();
+ }
+
+ public SolrDocumentList getHistory(long since, AtomicBoolean found) {
+ if(history==null) {
+ return null;
+ }
+
+ SolrDocumentList docs = new SolrDocumentList();
+ Iterator<E> iter = history.iterator();
+ while(iter.hasNext()) {
+ E e = iter.next();
+ long ts = getTimestamp(e);
+ if(ts == since) {
+ if(found!=null) {
+ found.set(true);
+ }
+ }
+ if(ts>since) {
+ docs.add(toSolrDocument(e));
+ }
+ }
+ docs.setNumFound(docs.size()); // make it not look too funny
+ return docs;
+ }
+
+ public abstract long getTimestamp(E event);
+ public abstract SolrDocument toSolrDocument(E event);
+
+ public abstract void registerListener(ListenerConfig cfg, CoreContainer container);
+
+ public void reset() {
+ history.clear();
+ last = -1;
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LoggerInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LoggerInfo.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LoggerInfo.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/LoggerInfo.java Thu Aug 30 22:43:41 2012
@@ -1,68 +1,68 @@
-/*
- * 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.solr.logging;
-
-import org.apache.solr.common.util.SimpleOrderedMap;
-
-/**
- * Wrapper class for Logger implementaions
- */
-public abstract class LoggerInfo implements Comparable<LoggerInfo> {
- public static final String ROOT_NAME = "root";
-
- protected final String name;
- protected String level;
-
- public LoggerInfo(String name) {
- this.name = name;
- }
-
- public String getLevel() {
- return level;
- }
-
- public String getName() {
- return name;
- }
-
- public abstract boolean isSet();
-
- public SimpleOrderedMap<?> getInfo() {
- SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>();
- info.add("name", getName());
- info.add("level", getLevel());
- info.add("set", isSet());
- return info;
- }
-
- @Override
- public int compareTo(LoggerInfo other) {
- if (this.equals(other))
- return 0;
-
- String tN = this.getName();
- String oN = other.getName();
-
- if(ROOT_NAME.equals(tN))
- return -1;
- if(ROOT_NAME.equals(oN))
- return 1;
-
- return tN.compareTo(oN);
- }
+/*
+ * 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.solr.logging;
+
+import org.apache.solr.common.util.SimpleOrderedMap;
+
+/**
+ * Wrapper class for Logger implementaions
+ */
+public abstract class LoggerInfo implements Comparable<LoggerInfo> {
+ public static final String ROOT_NAME = "root";
+
+ protected final String name;
+ protected String level;
+
+ public LoggerInfo(String name) {
+ this.name = name;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public abstract boolean isSet();
+
+ public SimpleOrderedMap<?> getInfo() {
+ SimpleOrderedMap<Object> info = new SimpleOrderedMap<Object>();
+ info.add("name", getName());
+ info.add("level", getLevel());
+ info.add("set", isSet());
+ return info;
+ }
+
+ @Override
+ public int compareTo(LoggerInfo other) {
+ if (this.equals(other))
+ return 0;
+
+ String tN = this.getName();
+ String oN = other.getName();
+
+ if(ROOT_NAME.equals(tN))
+ return -1;
+ if(ROOT_NAME.equals(oN))
+ return 1;
+
+ return tN.compareTo(oN);
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulInfo.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulInfo.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulInfo.java Thu Aug 30 22:43:41 2012
@@ -1,70 +1,70 @@
-/*
- * 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.solr.logging.jul;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.solr.logging.LoggerInfo;
-
-public class JulInfo extends LoggerInfo {
- private static final Level[] LEVELS = {
- null, // aka unset
- Level.FINEST,
- Level.FINE,
- Level.CONFIG,
- Level.INFO,
- Level.WARNING,
- Level.SEVERE,
- Level.OFF
- // Level.ALL -- ignore. It is useless.
- };
-
- final Logger logger;
-
- public JulInfo(String name, Logger logger) {
- super(name);
- this.logger = logger;
- }
-
- @Override
- public String getLevel() {
- if(logger==null) {
- return null;
- }
- Level level = logger.getLevel();
- if (level != null) {
- return level.getName();
- }
- for (Level l : LEVELS) {
- if (l == null) {
- // avoid NPE
- continue;
- }
- if (logger.isLoggable(l)) {
- // return first level loggable
- return l.getName();
- }
- }
- return Level.OFF.getName();
- }
-
- @Override
- public boolean isSet() {
- return (logger!=null && logger.getLevel()!=null);
- }
+/*
+ * 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.solr.logging.jul;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.solr.logging.LoggerInfo;
+
+public class JulInfo extends LoggerInfo {
+ private static final Level[] LEVELS = {
+ null, // aka unset
+ Level.FINEST,
+ Level.FINE,
+ Level.CONFIG,
+ Level.INFO,
+ Level.WARNING,
+ Level.SEVERE,
+ Level.OFF
+ // Level.ALL -- ignore. It is useless.
+ };
+
+ final Logger logger;
+
+ public JulInfo(String name, Logger logger) {
+ super(name);
+ this.logger = logger;
+ }
+
+ @Override
+ public String getLevel() {
+ if(logger==null) {
+ return null;
+ }
+ Level level = logger.getLevel();
+ if (level != null) {
+ return level.getName();
+ }
+ for (Level l : LEVELS) {
+ if (l == null) {
+ // avoid NPE
+ continue;
+ }
+ if (logger.isLoggable(l)) {
+ // return first level loggable
+ return l.getName();
+ }
+ }
+ return Level.OFF.getName();
+ }
+
+ @Override
+ public boolean isSet() {
+ return (logger!=null && logger.getLevel()!=null);
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulWatcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulWatcher.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulWatcher.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/JulWatcher.java Thu Aug 30 22:43:41 2012
@@ -1,169 +1,169 @@
-/*
- * 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.solr.logging.jul;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.LogManager;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.core.CoreContainer;
-import org.apache.solr.logging.CircularList;
-import org.apache.solr.logging.ListenerConfig;
-import org.apache.solr.logging.LoggerInfo;
-import org.apache.solr.logging.LogWatcher;
-
-import com.google.common.base.Throwables;
-
-public class JulWatcher extends LogWatcher<LogRecord> {
-
- final String name;
- RecordHandler handler = null;
-
- public JulWatcher(String name) {
- this.name = name;
- }
-
- @Override
- public String getName() {
- return "JUL ("+name+")";
- }
-
-
- @Override
- public List<String> getAllLevels() {
- return Arrays.asList(
- Level.FINEST.getName(),
- Level.FINER.getName(),
- Level.FINE.getName(),
- Level.CONFIG.getName(),
- Level.INFO.getName(),
- Level.WARNING.getName(),
- Level.SEVERE.getName(),
- Level.OFF.getName() );
- }
-
- @Override
- public void setLogLevel(String category, String level) {
- if(LoggerInfo.ROOT_NAME.equals(category)) {
- category = "";
- }
-
- Logger log = LogManager.getLogManager().getLogger(category);
- if(level==null||"unset".equals(level)||"null".equals(level)) {
- if(log!=null) {
- log.setLevel(null);
- }
- }
- else {
- if(log==null) {
- log = Logger.getLogger(category); // create it
- }
- log.setLevel(Level.parse(level));
- }
- }
-
- @Override
- public Collection<LoggerInfo> getAllLoggers() {
- LogManager manager = LogManager.getLogManager();
-
- Logger root = manager.getLogger("");
- Map<String,LoggerInfo> map = new HashMap<String,LoggerInfo>();
- Enumeration<String> names = manager.getLoggerNames();
- while (names.hasMoreElements()) {
- String name = names.nextElement();
- Logger logger = Logger.getLogger(name);
- if( logger == root) {
- continue;
- }
- map.put(name, new JulInfo(name, logger));
-
- while (true) {
- int dot = name.lastIndexOf(".");
- if (dot < 0)
- break;
- name = name.substring(0, dot);
- if(!map.containsKey(name)) {
- map.put(name, new JulInfo(name, null));
- }
- }
- }
- map.put(LoggerInfo.ROOT_NAME, new JulInfo(LoggerInfo.ROOT_NAME, root));
- return map.values();
- }
-
- @Override
- public void setThreshold(String level) {
- if(handler==null) {
- throw new IllegalStateException("Must have an handler");
- }
- handler.setLevel( Level.parse(level) );
- }
-
- @Override
- public String getThreshold() {
- if(handler==null) {
- throw new IllegalStateException("Must have an handler");
- }
- return handler.getLevel().toString();
- }
-
- @Override
- public void registerListener(ListenerConfig cfg, CoreContainer container) {
- if(history!=null) {
- throw new IllegalStateException("History already registered");
- }
- history = new CircularList<LogRecord>(cfg.size);
- handler = new RecordHandler(this);
- if(cfg.threshold != null) {
- handler.setLevel(Level.parse(cfg.threshold));
- }
- else {
- handler.setLevel(Level.WARNING);
- }
-
- Logger log = LogManager.getLogManager().getLogger("");
- log.addHandler(handler);
- }
-
- @Override
- public long getTimestamp(LogRecord event) {
- return event.getMillis();
- }
-
- @Override
- public SolrDocument toSolrDocument(LogRecord event) {
- SolrDocument doc = new SolrDocument();
- doc.setField("time", new Date(event.getMillis()));
- doc.setField("level", event.getLevel().toString());
- doc.setField("logger", event.getLoggerName());
- doc.setField("message", event.getMessage().toString());
- Throwable t = event.getThrown();
- if(t!=null) {
- doc.setField("trace", Throwables.getStackTraceAsString(t));
- }
- return doc;
- }
+/*
+ * 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.solr.logging.jul;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.logging.CircularList;
+import org.apache.solr.logging.ListenerConfig;
+import org.apache.solr.logging.LoggerInfo;
+import org.apache.solr.logging.LogWatcher;
+
+import com.google.common.base.Throwables;
+
+public class JulWatcher extends LogWatcher<LogRecord> {
+
+ final String name;
+ RecordHandler handler = null;
+
+ public JulWatcher(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return "JUL ("+name+")";
+ }
+
+
+ @Override
+ public List<String> getAllLevels() {
+ return Arrays.asList(
+ Level.FINEST.getName(),
+ Level.FINER.getName(),
+ Level.FINE.getName(),
+ Level.CONFIG.getName(),
+ Level.INFO.getName(),
+ Level.WARNING.getName(),
+ Level.SEVERE.getName(),
+ Level.OFF.getName() );
+ }
+
+ @Override
+ public void setLogLevel(String category, String level) {
+ if(LoggerInfo.ROOT_NAME.equals(category)) {
+ category = "";
+ }
+
+ Logger log = LogManager.getLogManager().getLogger(category);
+ if(level==null||"unset".equals(level)||"null".equals(level)) {
+ if(log!=null) {
+ log.setLevel(null);
+ }
+ }
+ else {
+ if(log==null) {
+ log = Logger.getLogger(category); // create it
+ }
+ log.setLevel(Level.parse(level));
+ }
+ }
+
+ @Override
+ public Collection<LoggerInfo> getAllLoggers() {
+ LogManager manager = LogManager.getLogManager();
+
+ Logger root = manager.getLogger("");
+ Map<String,LoggerInfo> map = new HashMap<String,LoggerInfo>();
+ Enumeration<String> names = manager.getLoggerNames();
+ while (names.hasMoreElements()) {
+ String name = names.nextElement();
+ Logger logger = Logger.getLogger(name);
+ if( logger == root) {
+ continue;
+ }
+ map.put(name, new JulInfo(name, logger));
+
+ while (true) {
+ int dot = name.lastIndexOf(".");
+ if (dot < 0)
+ break;
+ name = name.substring(0, dot);
+ if(!map.containsKey(name)) {
+ map.put(name, new JulInfo(name, null));
+ }
+ }
+ }
+ map.put(LoggerInfo.ROOT_NAME, new JulInfo(LoggerInfo.ROOT_NAME, root));
+ return map.values();
+ }
+
+ @Override
+ public void setThreshold(String level) {
+ if(handler==null) {
+ throw new IllegalStateException("Must have an handler");
+ }
+ handler.setLevel( Level.parse(level) );
+ }
+
+ @Override
+ public String getThreshold() {
+ if(handler==null) {
+ throw new IllegalStateException("Must have an handler");
+ }
+ return handler.getLevel().toString();
+ }
+
+ @Override
+ public void registerListener(ListenerConfig cfg, CoreContainer container) {
+ if(history!=null) {
+ throw new IllegalStateException("History already registered");
+ }
+ history = new CircularList<LogRecord>(cfg.size);
+ handler = new RecordHandler(this);
+ if(cfg.threshold != null) {
+ handler.setLevel(Level.parse(cfg.threshold));
+ }
+ else {
+ handler.setLevel(Level.WARNING);
+ }
+
+ Logger log = LogManager.getLogManager().getLogger("");
+ log.addHandler(handler);
+ }
+
+ @Override
+ public long getTimestamp(LogRecord event) {
+ return event.getMillis();
+ }
+
+ @Override
+ public SolrDocument toSolrDocument(LogRecord event) {
+ SolrDocument doc = new SolrDocument();
+ doc.setField("time", new Date(event.getMillis()));
+ doc.setField("level", event.getLevel().toString());
+ doc.setField("logger", event.getLoggerName());
+ doc.setField("message", event.getMessage().toString());
+ Throwable t = event.getThrown();
+ if(t!=null) {
+ doc.setField("trace", Throwables.getStackTraceAsString(t));
+ }
+ return doc;
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/RecordHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/RecordHandler.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/RecordHandler.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/logging/jul/RecordHandler.java Thu Aug 30 22:43:41 2012
@@ -1,47 +1,47 @@
-/*
- * 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.solr.logging.jul;
-
-
-import java.util.logging.LogRecord;
-
-import org.apache.solr.logging.LogWatcher;
-
-public final class RecordHandler extends java.util.logging.Handler {
- final LogWatcher<LogRecord> framework;
-
- public RecordHandler(LogWatcher<LogRecord> framework) {
- this.framework = framework;
- }
-
- @Override
- public void close() throws SecurityException {
- //history.reset();
- }
-
- @Override
- public void flush() {
- // nothing
- }
-
- @Override
- public void publish(LogRecord r) {
- if(isLoggable(r)) {
- framework.add(r, r.getMillis());
- }
- }
+/*
+ * 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.solr.logging.jul;
+
+
+import java.util.logging.LogRecord;
+
+import org.apache.solr.logging.LogWatcher;
+
+public final class RecordHandler extends java.util.logging.Handler {
+ final LogWatcher<LogRecord> framework;
+
+ public RecordHandler(LogWatcher<LogRecord> framework) {
+ this.framework = framework;
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ //history.reset();
+ }
+
+ @Override
+ public void flush() {
+ // nothing
+ }
+
+ @Override
+ public void publish(LogRecord r) {
+ if(isLoggable(r)) {
+ framework.add(r, r.getMillis());
+ }
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/BoolField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/BoolField.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/BoolField.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/BoolField.java Thu Aug 30 22:43:41 2012
@@ -72,9 +72,8 @@ public class BoolField extends Primitive
boolean done = false;
@Override
- public void setReader(Reader input) throws IOException {
+ public void reset() throws IOException {
done = false;
- super.setReader(input);
}
@Override
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java Thu Aug 30 22:43:41 2012
@@ -83,13 +83,8 @@ public class PreAnalyzedField extends Fi
return new SolrAnalyzer() {
@Override
- protected TokenStreamComponents createComponents(String fieldName,
- Reader reader) {
- try {
- return new TokenStreamComponents(new PreAnalyzedTokenizer(reader, parser));
- } catch (IOException e) {
- return null;
- }
+ protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+ return new TokenStreamComponents(new PreAnalyzedTokenizer(reader, parser));
}
};
@@ -171,6 +166,7 @@ public class PreAnalyzedField extends Fi
return null;
}
PreAnalyzedTokenizer parse = new PreAnalyzedTokenizer(new StringReader(val), parser);
+ parse.reset(); // consume
Field f = (Field)super.createField(field, val, boost);
if (parse.getStringValue() != null) {
f.setStringValue(parse.getStringValue());
@@ -197,11 +193,11 @@ public class PreAnalyzedField extends Fi
private String stringValue = null;
private byte[] binaryValue = null;
private PreAnalyzedParser parser;
+ private Reader lastReader;
- public PreAnalyzedTokenizer(Reader reader, PreAnalyzedParser parser) throws IOException {
+ public PreAnalyzedTokenizer(Reader reader, PreAnalyzedParser parser) {
super(reader);
this.parser = parser;
- setReader(reader);
}
public boolean hasTokenStream() {
@@ -231,24 +227,30 @@ public class PreAnalyzedField extends Fi
return true;
}
- public final void reset() {
+ @Override
+ public final void reset() throws IOException {
+ // NOTE: this acts like rewind if you call it again
+ if (input != lastReader) {
+ lastReader = input;
+ cachedStates.clear();
+ stringValue = null;
+ binaryValue = null;
+ ParseResult res = parser.parse(input, this);
+ if (res != null) {
+ stringValue = res.str;
+ binaryValue = res.bin;
+ if (res.states != null) {
+ cachedStates.addAll(res.states);
+ }
+ }
+ }
it = cachedStates.iterator();
}
@Override
- public void setReader(Reader input) throws IOException {
- super.setReader(input);
- cachedStates.clear();
- stringValue = null;
- binaryValue = null;
- ParseResult res = parser.parse(input, this);
- if (res != null) {
- stringValue = res.str;
- binaryValue = res.bin;
- if (res.states != null) {
- cachedStates.addAll(res.states);
- }
- }
+ public void close() throws IOException {
+ super.close();
+ lastReader = null; // just a ref, null for gc
}
}
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java Thu Aug 30 22:43:41 2012
@@ -242,10 +242,14 @@ public final class DefaultSolrCoreState
synchronized (recoveryLock) {
if (recoveryStrat != null) {
recoveryStrat.close();
- try {
- recoveryStrat.join();
- } catch (InterruptedException e) {
-
+ while (true) {
+ try {
+ recoveryStrat.join();
+ } catch (InterruptedException e) {
+ // not interruptible - keep waiting
+ continue;
+ }
+ break;
}
recoveryRunning = false;
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java Thu Aug 30 22:43:41 2012
@@ -738,6 +738,13 @@ public class DirectUpdateHandler2 extend
}
}
+ @Override
+ public void split(SplitIndexCommand cmd) throws IOException {
+ // TODO: do a commit first?
+ SolrIndexSplitter splitter = new SolrIndexSplitter(cmd);
+ splitter.split();
+ }
+
/////////////////////////////////////////////////////////////////////
// SolrInfoMBean stuff: Statistics and Module Info
/////////////////////////////////////////////////////////////////////
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java Thu Aug 30 22:43:41 2012
@@ -166,6 +166,8 @@ public class SolrCmdDistributor {
addCommit(ureq, cmd);
+ log.info("Distrib commit to:" + nodes);
+
for (Node node : nodes) {
submit(ureq, node);
}
@@ -345,7 +347,8 @@ public class SolrCmdDistributor {
try {
semaphore.acquire();
} catch (InterruptedException e) {
- throw new RuntimeException();
+ Thread.currentThread().interrupt();
+ throw new RuntimeException("Update thread interrupted");
}
pending.add(completionService.submit(task));
Modified: lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/UpdateHandler.java?rev=1379200&r1=1379199&r2=1379200&view=diff
==============================================================================
--- lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/UpdateHandler.java (original)
+++ lucene/dev/branches/lucene3312/solr/core/src/java/org/apache/solr/update/UpdateHandler.java Thu Aug 30 22:43:41 2012
@@ -179,4 +179,6 @@ public abstract class UpdateHandler impl
{
optimizeCallbacks.add( listener );
}
+
+ public abstract void split(SplitIndexCommand cmd) throws IOException;
}