Enable larger rules.pl files

Allow administrators to boost the internal limits on rules.pl files.

Change-Id: I667d18d032cc51b6dabfe7c45268e995f728a2dd
This commit is contained in:
Shawn Pearce
2015-11-21 09:47:32 -08:00
parent 80bde79e0d
commit a2b985276c
2 changed files with 31 additions and 14 deletions

View File

@@ -3134,6 +3134,26 @@ compiling source code to internal Prolog machine code.
+ +
Default is 10x reductionLimit (1,000,000). Default is 10x reductionLimit (1,000,000).
[[rules.maxSourceBytes]]rules.maxSourceBytes::
+
Maximum input size (in bytes) of a Prolog rules.pl file. Larger
source files may need a larger rules.compileReductionLimit. Consider
using link:pgm-rulec.html[rulec] to precompile larger rule files.
+
A size of 0 bytes disables rules, same as rules.enable = false.
+
Default is 128 KiB.
[[rules.maxPrologDatabaseSize]]rules.maxPrologDatabaseSize::
+
Number of predicate clauses allowed to be defined in the Prolog
database by project rules. Very complex rules may need more than the
default 256 limit, but cost more memory and may need more time to
evaluate. Consider using link:pgm-rulec.html[rulec] to precompile
larger rule files.
+
Default is 256.
[[execution]] [[execution]]
=== Section execution === Section execution

View File

@@ -75,20 +75,9 @@ import java.util.Map;
*/ */
@Singleton @Singleton
public class RulesCache { public class RulesCache {
/** Maximum size of a dynamic Prolog script, in bytes. */
private static final int SRC_LIMIT = 128 * 1024;
/** Default size of the internal Prolog database within each interpreter. */
private static final int DB_MAX = 256;
private static final List<String> PACKAGE_LIST = ImmutableList.of( private static final List<String> PACKAGE_LIST = ImmutableList.of(
Prolog.BUILTIN, "gerrit"); Prolog.BUILTIN, "gerrit");
private final Map<ObjectId, MachineRef> machineCache = new HashMap<>();
private final ReferenceQueue<PrologMachineCopy> dead =
new ReferenceQueue<>();
private static final class MachineRef extends WeakReference<PrologMachineCopy> { private static final class MachineRef extends WeakReference<PrologMachineCopy> {
final ObjectId key; final ObjectId key;
@@ -100,17 +89,25 @@ public class RulesCache {
} }
private final boolean enableProjectRules; private final boolean enableProjectRules;
private final int maxDbSize;
private final int maxSrcBytes;
private final Path cacheDir; private final Path cacheDir;
private final Path rulesDir; private final Path rulesDir;
private final GitRepositoryManager gitMgr; private final GitRepositoryManager gitMgr;
private final DynamicSet<PredicateProvider> predicateProviders; private final DynamicSet<PredicateProvider> predicateProviders;
private final ClassLoader systemLoader; private final ClassLoader systemLoader;
private final PrologMachineCopy defaultMachine; private final PrologMachineCopy defaultMachine;
private final Map<ObjectId, MachineRef> machineCache = new HashMap<>();
private final ReferenceQueue<PrologMachineCopy> dead =
new ReferenceQueue<>();
@Inject @Inject
protected RulesCache(@GerritServerConfig Config config, SitePaths site, protected RulesCache(@GerritServerConfig Config config, SitePaths site,
GitRepositoryManager gm, DynamicSet<PredicateProvider> predicateProviders) { GitRepositoryManager gm, DynamicSet<PredicateProvider> predicateProviders) {
enableProjectRules = config.getBoolean("rules", null, "enable", true); maxDbSize = config.getInt("rules", null, "maxPrologDatabaseSize", 256);
maxSrcBytes = config.getInt("rules", null, "maxSourceBytes", 128 << 10);
enableProjectRules = config.getBoolean("rules", null, "enable", true)
&& maxSrcBytes > 0;
cacheDir = site.resolve(config.getString("cache", null, "directory")); cacheDir = site.resolve(config.getString("cache", null, "directory"));
rulesDir = cacheDir != null ? cacheDir.resolve("rules") : null; rulesDir = cacheDir != null ? cacheDir.resolve("rules") : null;
gitMgr = gm; gitMgr = gm;
@@ -267,7 +264,7 @@ public class RulesCache {
try (Repository git = gitMgr.openRepository(project)) { try (Repository git = gitMgr.openRepository(project)) {
try { try {
ObjectLoader ldr = git.open(rulesId, Constants.OBJ_BLOB); ObjectLoader ldr = git.open(rulesId, Constants.OBJ_BLOB);
byte[] raw = ldr.getCachedBytes(SRC_LIMIT); byte[] raw = ldr.getCachedBytes(maxSrcBytes);
return RawParseUtils.decode(raw); return RawParseUtils.decode(raw);
} catch (LargeObjectException e) { } catch (LargeObjectException e) {
throw new CompileException("rules of " + project + " are too large", e); throw new CompileException("rules of " + project + " are too large", e);
@@ -281,7 +278,7 @@ public class RulesCache {
private BufferingPrologControl newEmptyMachine(ClassLoader cl) { private BufferingPrologControl newEmptyMachine(ClassLoader cl) {
BufferingPrologControl ctl = new BufferingPrologControl(); BufferingPrologControl ctl = new BufferingPrologControl();
ctl.setMaxDatabaseSize(DB_MAX); ctl.setMaxDatabaseSize(maxDbSize);
ctl.setPrologClassLoader(new PrologClassLoader(new PredicateClassLoader( ctl.setPrologClassLoader(new PrologClassLoader(new PredicateClassLoader(
predicateProviders, cl))); predicateProviders, cl)));
ctl.setEnabled(EnumSet.allOf(Prolog.Feature.class), false); ctl.setEnabled(EnumSet.allOf(Prolog.Feature.class), false);