Skip to content

Commit 1a0291e

Browse files
authored
Merge pull request #1936 from idodeclare/feature/deferred_ops
Feature/deferred ops
2 parents 974ca47 + 6048a8e commit 1a0291e

40 files changed

+1760
-332
lines changed

OpenGrok

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
# options for CTags program (for its --options
4545
# switch), default is DATA_ROOT/etc/ctags.config
4646
# - OPENGROK_MANDOC Full path to mandoc(1) binary
47+
# - OPENGROK_LOCKING Locking mode on|off|simple|native (default off)
48+
# ("on" is an alias for "simple")
4749
# - JAVA_HOME Full Path to Java Installation Root
4850
# - JAVA Full Path to java binary (to enable 64bit JDK)
4951
# - JAVA_OPTS Java options (e.g. for JVM memory increase
@@ -109,6 +111,8 @@
109111
# increase it to 256MB, but do increase JVM to
110112
# 4/8/16GB ! Lucene defaults to 8 threads.
111113
# Increase JVM memory as noted using JAVA_OPTS
114+
# - OPENGROK_PARALLELISM Default is 0, meaning that parallelism is
115+
# determined from available processors.
112116
# - OPENGROK_LOGGER_CONFIG_PATH Set path to custom logging.properties file.
113117
# - OPENGROK_SUBVERSION_USERNAME name of the user that should be used for
114118
# fetching the history from subversion
@@ -861,10 +865,12 @@ CommonInvocation()
861865
${RENAMED_FILES_HISTORY} \
862866
${SCAN_DEPTH} \
863867
${PROGRESS} \
868+
${OPENGROK_LOCKING:+--lock} ${OPENGROK_LOCKING} \
864869
${OPENGROK_CTAGS:+-c} ${OPENGROK_CTAGS} \
865870
${OPENGROK_MANDOC:+--mandoc} ${OPENGROK_MANDOC} \
866871
${CTAGS_OPTIONS_FILE:+-o} ${CTAGS_OPTIONS_FILE} \
867872
${OPENGROK_FLUSH_RAM_BUFFER_SIZE} ${SKIN} ${LEADING_WILDCARD} \
873+
${OPENGROK_PARALLELISM:+--threads} ${OPENGROK_PARALLELISM} \
868874
${READ_XML_CONF} \
869875
${WEBAPP_CONFIG} \
870876
${WEBAPP_CONTEXT} \
@@ -1039,17 +1045,15 @@ case "${1}" in
10391045
update)
10401046
ValidateConfiguration
10411047
CreateRuntimeRequirements
1042-
UpdateGeneratedData
1043-
UpdateDescriptionCache
1048+
UpdateGeneratedData && UpdateDescriptionCache
10441049
;;
10451050

10461051
updateQuietly)
10471052
ValidateConfiguration
10481053
CreateRuntimeRequirements
10491054
QUIET="-q"
10501055
VERBOSE=""
1051-
UpdateGeneratedData
1052-
UpdateDescriptionCache
1056+
UpdateGeneratedData && UpdateDescriptionCache
10531057
;;
10541058

10551059
updateDesc)
@@ -1073,8 +1077,7 @@ case "${1}" in
10731077
fi
10741078
ValidateConfiguration
10751079
CreateRuntimeRequirements
1076-
UpdateGeneratedData
1077-
UpdateDescriptionCache
1080+
UpdateGeneratedData && UpdateDescriptionCache
10781081
;;
10791082

10801083
indexpart)
@@ -1112,3 +1115,4 @@ case "${1}" in
11121115
Usage
11131116
;;
11141117
esac
1118+
exit $?

src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,11 @@ public static FileAnalyzer getAnalyzer(InputStream in, String file) throws IOExc
393393
* @param fa The analyzer to use on the file
394394
* @param xrefOut Where to write the xref (possibly {@code null})
395395
* @throws IOException If an exception occurs while collecting the data
396+
* @throws InterruptedException if a timeout occurs
396397
*/
397398
public void populateDocument(Document doc, File file, String path,
398-
FileAnalyzer fa, Writer xrefOut)
399-
throws IOException {
399+
FileAnalyzer fa, Writer xrefOut) throws IOException,
400+
InterruptedException {
400401

401402
String date = DateTools.timeToString(file.lastModified(),
402403
DateTools.Resolution.MILLISECOND);

src/org/opensolaris/opengrok/analysis/Ctags.java

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opensolaris.opengrok.analysis;
2525

@@ -39,25 +39,40 @@
3939
import org.opensolaris.opengrok.util.IOUtils;
4040

4141
/**
42-
* Provides Ctags by having a running instance of ctags
42+
* Provides Ctags by having a running subprocess of ctags.
4343
*
4444
* @author Chandan
4545
*/
4646
public class Ctags {
4747

4848
private static final Logger LOGGER = LoggerFactory.getLogger(Ctags.class);
4949

50+
private volatile boolean closing;
5051
private Process ctags;
52+
private Thread errThread;
5153
private OutputStreamWriter ctagsIn;
5254
private BufferedReader ctagsOut;
5355
private static final String CTAGS_FILTER_TERMINATOR = "__ctags_done_with_file__";
5456
//default: setCtags(System.getProperty("org.opensolaris.opengrok.analysis.Ctags", "ctags"));
5557
private String binary;
5658
private String CTagsExtraOptionsFile = null;
57-
private ProcessBuilder processBuilder;
5859

5960
private boolean junit_testing = false;
6061

62+
/**
63+
* Gets a value indicating if a subprocess of ctags was started and it is
64+
* not alive.
65+
* @return {@code true} if the instance should be considered closed and no
66+
* longer usable.
67+
*/
68+
public boolean isClosed() {
69+
return ctags != null && !ctags.isAlive();
70+
}
71+
72+
public String getBinary() {
73+
return binary;
74+
}
75+
6176
public void setBinary(String binary) {
6277
this.binary = binary;
6378
}
@@ -69,14 +84,16 @@ public void setCTagsExtraOptionsFile(String CTagsExtraOptionsFile) {
6984
public void close() throws IOException {
7085
IOUtils.close(ctagsIn);
7186
if (ctags != null) {
87+
closing = true;
7288
LOGGER.log(Level.FINE, "Destroying ctags command");
73-
ctags.destroy();
89+
ctags.destroyForcibly();
7490
}
7591
}
7692

7793
private void initialize() throws IOException {
7894
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
79-
if (processBuilder == null) {
95+
ProcessBuilder processBuilder;
96+
if (true) {
8097
List<String> command = new ArrayList<>();
8198

8299
command.add(binary);
@@ -284,58 +301,65 @@ private void initialize() throws IOException {
284301
ctagsIn = new OutputStreamWriter(ctags.getOutputStream());
285302
ctagsOut = new BufferedReader(new InputStreamReader(ctags.getInputStream()));
286303

287-
Thread errThread = new Thread(new Runnable() {
304+
errThread = new Thread(new Runnable() {
288305

289306
@Override
290307
public void run() {
291-
StringBuilder sb = new StringBuilder();
292308
try (BufferedReader error = new BufferedReader(
293309
new InputStreamReader(ctags.getErrorStream()))) {
294310
String s;
295311
while ((s = error.readLine()) != null) {
296-
sb.append(s);
297-
sb.append('\n');
312+
if (s.length() > 0) {
313+
LOGGER.log(Level.WARNING, "Error from ctags: {0}",
314+
s);
315+
}
316+
if (closing) break;
298317
}
299318
} catch (IOException exp) {
300319
LOGGER.log(Level.WARNING, "Got an exception reading ctags error stream: ", exp);
301320
}
302-
if (sb.length() > 0) {
303-
LOGGER.log(Level.WARNING, "Error from ctags: {0}", sb.toString());
304-
}
305321
}
306322
});
307323
errThread.setDaemon(true);
308324
errThread.start();
309325
}
310326

311-
public Definitions doCtags(String file) throws IOException {
312-
boolean ctagsRunning = false;
327+
public Definitions doCtags(String file) throws IOException,
328+
InterruptedException {
329+
if (file.length() < 1 || "\n".equals(file)) return null;
330+
313331
if (ctags != null) {
314332
try {
315333
int exitValue = ctags.exitValue();
316334
// If it is possible to retrieve exit value without exception
317-
// this means the ctags process is dead so we must restart it.
318-
ctagsRunning = false;
335+
// this means the ctags process is dead.
319336
LOGGER.log(Level.WARNING, "Ctags process exited with exit value {0}",
320337
exitValue);
338+
// Throw the following to indicate non-I/O error for retry.
339+
throw new InterruptedException("ctags died");
321340
} catch (IllegalThreadStateException exp) {
322-
ctagsRunning = true;
323341
// The ctags process is still running.
324342
}
325-
}
326-
327-
if (!ctagsRunning) {
343+
} else {
328344
initialize();
329345
}
330346

331-
Definitions ret = null;
332-
if (file.length() > 0 && !"\n".equals(file)) {
333-
//log.fine("doing >" + file + "<");
347+
CtagsReader rdr = new CtagsReader();
348+
Definitions ret;
349+
try {
334350
ctagsIn.write(file);
351+
if (Thread.interrupted()) throw new InterruptedException("write()");
335352
ctagsIn.flush();
336-
CtagsReader rdr = new CtagsReader();
353+
if (Thread.interrupted()) throw new InterruptedException("flush()");
337354
readTags(rdr);
338355
ret = rdr.getDefinitions();
356+
} catch (IOException ex) {
357+
/*
358+
* In case the ctags process had to be destroyed, possibly pre-empt
359+
* the IOException with an InterruptedException.
360+
*/
361+
if (Thread.interrupted()) throw new InterruptedException("I/O");
362+
throw ex;
339363
}
340364

341365
return ret;
@@ -383,15 +407,23 @@ public void destroy() {
383407
};
384408

385409
CtagsReader rdr = new CtagsReader();
386-
readTags(rdr);
410+
try {
411+
readTags(rdr);
412+
} catch (InterruptedException ex) {
413+
LOGGER.log(Level.SEVERE, "readTags() test", ex);
414+
}
387415
Definitions ret = rdr.getDefinitions();
388416
return ret;
389417
}
390418

391-
private void readTags(CtagsReader reader) {
419+
private void readTags(CtagsReader reader) throws InterruptedException {
392420
try {
393421
do {
394422
String tagLine = ctagsOut.readLine();
423+
if (Thread.interrupted()) {
424+
throw new InterruptedException("readLine()");
425+
}
426+
395427
//log.fine("Tagline:-->" + tagLine+"<----ONELINE");
396428
if (tagLine == null) {
397429
if (!junit_testing) {
@@ -421,6 +453,8 @@ private void readTags(CtagsReader reader) {
421453

422454
reader.readLine(tagLine);
423455
} while (true);
456+
} catch (InterruptedException e) {
457+
throw e;
424458
} catch (Exception e) {
425459
LOGGER.log(Level.WARNING, "CTags parsing problem: ", e);
426460
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2017, Chris Fraire <[email protected]>.
22+
*/
23+
24+
package org.opensolaris.opengrok.analysis;
25+
26+
import java.io.IOException;
27+
import java.util.logging.Level;
28+
import java.util.logging.Logger;
29+
import org.opensolaris.opengrok.logger.LoggerFactory;
30+
import org.opensolaris.opengrok.util.ObjectValidator;
31+
32+
public final class CtagsValidator implements ObjectValidator<Ctags> {
33+
34+
private static final Logger LOGGER = LoggerFactory.getLogger(
35+
CtagsValidator.class);
36+
37+
public boolean isValid(Ctags ctags) {
38+
return ctags != null && !ctags.isClosed();
39+
}
40+
41+
public void invalidate(Ctags ctags) {
42+
try {
43+
if (ctags != null) ctags.close();
44+
} catch (IOException ex) {
45+
LOGGER.log(Level.FINE, "Error closing ctags", ex);
46+
}
47+
}
48+
}

src/org/opensolaris/opengrok/analysis/FileAnalyzer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,10 @@ public String getFileTypeName() {
201201
* @param src the input data source
202202
* @param xrefOut where to write the xref (may be {@code null})
203203
* @throws IOException if any I/O error
204+
* @throws InterruptedException if a timeout occurs
204205
*/
205-
public void analyze(Document doc, StreamSource src, Writer xrefOut) throws IOException {
206+
public void analyze(Document doc, StreamSource src, Writer xrefOut)
207+
throws IOException, InterruptedException {
206208
// not used
207209
}
208210

src/org/opensolaris/opengrok/analysis/archive/BZip2Analyzer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.analysis.archive;
2425

@@ -57,7 +58,8 @@ protected BZip2Analyzer(FileAnalyzerFactory factory) {
5758
private FileAnalyzer fa;
5859

5960
@Override
60-
public void analyze(Document doc, StreamSource src, Writer xrefOut) throws IOException {
61+
public void analyze(Document doc, StreamSource src, Writer xrefOut)
62+
throws IOException, InterruptedException {
6163
StreamSource bzSrc = wrap(src);
6264
String path = doc.get("path");
6365
if (path != null

src/org/opensolaris/opengrok/analysis/archive/GZIPAnalyzer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.analysis.archive;
2425

@@ -63,7 +64,8 @@ protected GZIPAnalyzer(FileAnalyzerFactory factory) {
6364
private FileAnalyzer fa;
6465

6566
@Override
66-
public void analyze(Document doc, StreamSource src, Writer xrefOut) throws IOException {
67+
public void analyze(Document doc, StreamSource src, Writer xrefOut)
68+
throws IOException, InterruptedException {
6769
StreamSource gzSrc = wrap(src);
6870
String path = doc.get("path");
6971
if (path != null

src/org/opensolaris/opengrok/analysis/plain/AbstractSourceCodeAnalyzer.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2012, 2017 Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.analysis.plain;
2425

@@ -69,9 +70,4 @@ protected AbstractSourceCodeAnalyzer(FileAnalyzerFactory factory,
6970
*/
7071
@Override
7172
protected abstract JFlexXref newXref(Reader reader);
72-
73-
@Override
74-
public void analyze(Document doc, StreamSource src, Writer xrefOut) throws IOException {
75-
super.analyze(doc, src, xrefOut);
76-
}
7773
}

src/org/opensolaris/opengrok/analysis/plain/PlainAnalyzer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ protected Reader getReader(InputStream stream) throws IOException {
8585
}
8686

8787
@Override
88-
public void analyze(Document doc, StreamSource src, Writer xrefOut) throws IOException {
88+
public void analyze(Document doc, StreamSource src, Writer xrefOut)
89+
throws IOException, InterruptedException {
8990
Definitions defs = null;
9091

9192
doc.add(new TextField(QueryBuilder.FULL, getReader(src.getStream())));

0 commit comments

Comments
 (0)