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).
[[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]]
=== Section execution

View File

@@ -75,20 +75,9 @@ import java.util.Map;
*/
@Singleton
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(
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> {
final ObjectId key;
@@ -100,17 +89,25 @@ public class RulesCache {
}
private final boolean enableProjectRules;
private final int maxDbSize;
private final int maxSrcBytes;
private final Path cacheDir;
private final Path rulesDir;
private final GitRepositoryManager gitMgr;
private final DynamicSet<PredicateProvider> predicateProviders;
private final ClassLoader systemLoader;
private final PrologMachineCopy defaultMachine;
private final Map<ObjectId, MachineRef> machineCache = new HashMap<>();
private final ReferenceQueue<PrologMachineCopy> dead =
new ReferenceQueue<>();
@Inject
protected RulesCache(@GerritServerConfig Config config, SitePaths site,
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"));
rulesDir = cacheDir != null ? cacheDir.resolve("rules") : null;
gitMgr = gm;
@@ -267,7 +264,7 @@ public class RulesCache {
try (Repository git = gitMgr.openRepository(project)) {
try {
ObjectLoader ldr = git.open(rulesId, Constants.OBJ_BLOB);
byte[] raw = ldr.getCachedBytes(SRC_LIMIT);
byte[] raw = ldr.getCachedBytes(maxSrcBytes);
return RawParseUtils.decode(raw);
} catch (LargeObjectException e) {
throw new CompileException("rules of " + project + " are too large", e);
@@ -281,7 +278,7 @@ public class RulesCache {
private BufferingPrologControl newEmptyMachine(ClassLoader cl) {
BufferingPrologControl ctl = new BufferingPrologControl();
ctl.setMaxDatabaseSize(DB_MAX);
ctl.setMaxDatabaseSize(maxDbSize);
ctl.setPrologClassLoader(new PrologClassLoader(new PredicateClassLoader(
predicateProviders, cl)));
ctl.setEnabled(EnumSet.allOf(Prolog.Feature.class), false);