Skip to content

Commit

Permalink
Properly lock solrInstances for reboot and restoration of embedded Solr
Browse files Browse the repository at this point in the history
Putting a synchronization lock directly on the solrInstances property
was ineffective as it is assigned a new (unlocked) instance in these
operations.
  • Loading branch information
luccioman committed Jul 8, 2018
1 parent 9630f81 commit f467601
Showing 1 changed file with 47 additions and 11 deletions.
58 changes: 47 additions & 11 deletions source/net/yacy/search/index/Fulltext.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.util.Set; import java.util.Set;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
Expand Down Expand Up @@ -96,6 +97,10 @@ public final class Fulltext {
private final File archivePath; private final File archivePath;
private Export exportthread; // will have a export thread assigned if exporter is running private Export exportthread; // will have a export thread assigned if exporter is running
private InstanceMirror solrInstances; private InstanceMirror solrInstances;

/** Synchronization lock for solrInstances property */
private ReentrantLock solrInstancesLock;

private final CollectionConfiguration collectionConfiguration; private final CollectionConfiguration collectionConfiguration;
private final WebgraphConfiguration webgraphConfiguration; private final WebgraphConfiguration webgraphConfiguration;
private boolean writeWebgraph; private boolean writeWebgraph;
Expand All @@ -106,6 +111,7 @@ protected Fulltext(final File segmentPath, final File archivePath,
this.archivePath = archivePath; this.archivePath = archivePath;
this.exportthread = null; // will have a export thread assigned if exporter is running this.exportthread = null; // will have a export thread assigned if exporter is running
this.solrInstances = new InstanceMirror(); this.solrInstances = new InstanceMirror();
this.solrInstancesLock = new ReentrantLock();
this.collectionConfiguration = collectionConfiguration; this.collectionConfiguration = collectionConfiguration;
this.webgraphConfiguration = webgraphConfiguration; this.webgraphConfiguration = webgraphConfiguration;
this.writeWebgraph = false; this.writeWebgraph = false;
Expand Down Expand Up @@ -198,22 +204,35 @@ public RemoteSolrConnector getDefaultRemoteSolrConnector() {
} }


public EmbeddedInstance getEmbeddedInstance() { public EmbeddedInstance getEmbeddedInstance() {
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
if (this.solrInstances.isConnectedEmbedded()) return this.solrInstances.getEmbedded(); try {
if (this.solrInstances.isConnectedEmbedded()) {
return this.solrInstances.getEmbedded();
}
return null; return null;
} finally {
this.solrInstancesLock.unlock();
} }
} }


public SolrConnector getDefaultConnector() { public SolrConnector getDefaultConnector() {
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
try {
return this.solrInstances.getDefaultMirrorConnector(); return this.solrInstances.getDefaultMirrorConnector();
} finally {
this.solrInstancesLock.unlock();
} }
} }


public SolrConnector getWebgraphConnector() { public SolrConnector getWebgraphConnector() {
if (!this.writeWebgraph) return null; if (!this.writeWebgraph) {
synchronized (this.solrInstances) { return null;
}
this.solrInstancesLock.lock();
try {
return this.solrInstances.getGenericMirrorConnector(WebgraphSchema.CORE_NAME); return this.solrInstances.getGenericMirrorConnector(WebgraphSchema.CORE_NAME);
} finally {
this.solrInstancesLock.unlock();
} }
} }


Expand All @@ -232,8 +251,11 @@ public void clearCaches() {
} }


public void clearLocalSolr() throws IOException { public void clearLocalSolr() throws IOException {
if (this.exportthread != null) this.exportthread.interrupt(); if (this.exportthread != null) {
synchronized (this.solrInstances) { this.exportthread.interrupt();
}
this.solrInstancesLock.lock();
try {
EmbeddedInstance instance = this.solrInstances.getEmbedded(); EmbeddedInstance instance = this.solrInstances.getEmbedded();
if (instance != null) { if (instance != null) {
for (String name: instance.getCoreNames()) { for (String name: instance.getCoreNames()) {
Expand All @@ -242,18 +264,23 @@ public void clearLocalSolr() throws IOException {
this.commit(false); this.commit(false);
} }
this.solrInstances.clearCaches(); this.solrInstances.clearCaches();
} finally {
this.solrInstancesLock.unlock();
} }
} }


public void clearRemoteSolr() throws IOException { public void clearRemoteSolr() throws IOException {
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
try {
ShardInstance instance = this.solrInstances.getRemote(); ShardInstance instance = this.solrInstances.getRemote();
if (instance != null) { if (instance != null) {
for (String name: instance.getCoreNames()) { for (String name: instance.getCoreNames()) {
this.solrInstances.getRemoteConnector(name).clear(); this.solrInstances.getRemoteConnector(name).clear();
} }
} }
this.solrInstances.clearCaches(); this.solrInstances.clearCaches();
} finally {
this.solrInstancesLock.unlock();
} }
} }


Expand Down Expand Up @@ -593,7 +620,8 @@ public File dumpEmbeddedSolr() throws SolrException {
} }
final File storagePath = esc.getContainerPath(); final File storagePath = esc.getContainerPath();
final File zipOut = new File(this.archivePath, storagePath.getName() + "_" + GenericFormatter.SHORT_DAY_FORMATTER.format() + ".zip"); final File zipOut = new File(this.archivePath, storagePath.getName() + "_" + GenericFormatter.SHORT_DAY_FORMATTER.format() + ".zip");
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
try {
this.disconnectLocalSolr(); this.disconnectLocalSolr();
try { try {
ZIPWriter.zip(storagePath, zipOut); ZIPWriter.zip(storagePath, zipOut);
Expand All @@ -606,6 +634,8 @@ public File dumpEmbeddedSolr() throws SolrException {
ConcurrentLog.logException(e); ConcurrentLog.logException(e);
} }
} }
} finally {
this.solrInstancesLock.unlock();
} }
return zipOut; return zipOut;
} }
Expand All @@ -621,7 +651,8 @@ public void restoreEmbeddedSolr(final File solrDumpZipFile) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "No embedded Solr available."); throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "No embedded Solr available.");
} }
final File storagePath = esc.getContainerPath(); final File storagePath = esc.getContainerPath();
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
try {
// this.disconnectLocalSolr(); // moved to (InstanceMirror) sorlInstances.close() // this.disconnectLocalSolr(); // moved to (InstanceMirror) sorlInstances.close()
this.solrInstances.close(); this.solrInstances.close();
try { try {
Expand All @@ -636,6 +667,8 @@ public void restoreEmbeddedSolr(final File solrDumpZipFile) {
ConcurrentLog.logException(e); ConcurrentLog.logException(e);
} }
} }
} finally {
this.solrInstancesLock.unlock();
} }
} }


Expand All @@ -654,7 +687,8 @@ public void optimize(final int size) {
* Please check before that the local embedded Solr is enabled and no external remote Solr is attached. * Please check before that the local embedded Solr is enabled and no external remote Solr is attached.
*/ */
public void rebootEmbeddedLocalSolr() { public void rebootEmbeddedLocalSolr() {
synchronized (this.solrInstances) { this.solrInstancesLock.lock();
try {
this.disconnectLocalSolr(); this.disconnectLocalSolr();
// this.solrInstances.close(); // moved to (InstanceMirror) sorlInstances.close() // this.solrInstances.close(); // moved to (InstanceMirror) sorlInstances.close()
this.solrInstances = new InstanceMirror(); this.solrInstances = new InstanceMirror();
Expand All @@ -663,6 +697,8 @@ public void rebootEmbeddedLocalSolr() {
} catch (final IOException e) { } catch (final IOException e) {
ConcurrentLog.logException(e); ConcurrentLog.logException(e);
} }
} finally {
this.solrInstancesLock.unlock();
} }
} }


Expand Down

0 comments on commit f467601

Please sign in to comment.