This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 607928c9e2 [PERF] Thread configuration for WebAdmin, redis and some
reactor improvments (#950)
607928c9e2 is described below
commit 607928c9e2f94d2a0925ee4e41721503e747469b
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Apr 8 08:37:08 2022 +0700
[PERF] Thread configuration for WebAdmin, redis and some reactor
improvments (#950)
* [PERF] Reactor: reduce context switches upon event eecutions
* [PERF] Configure webadmin threading
* [PERF] Configure redis driver threading
---
.../org/apache/james/events/EventDispatcher.java | 4 +-
.../james/events/GroupRegistrationHandler.java | 6 +-
.../james/events/KeyRegistrationHandler.java | 1 -
.../distributed-app/docs/modules/ROOT/nav.adoc | 1 +
.../docs/modules/ROOT/pages/configure/index.adoc | 2 +
.../docs/modules/ROOT/pages/configure/redis.adoc | 26 +++++++++
.../modules/ROOT/pages/configure/webadmin.adoc | 6 ++
.../james/modules/server/WebAdminServerModule.java | 2 +
.../rate/limiter/redis/RedisRateLimiter.scala | 9 ++-
.../redis/RedisRateLimiterConfiguration.scala | 12 ++--
.../james/webadmin/WebAdminConfiguration.java | 36 ++++++++++--
.../org/apache/james/webadmin/WebAdminServer.java | 2 +
src/site/site.xml | 1 +
src/site/xdoc/server/config-redis.xml | 65 ++++++++++++++++++++++
src/site/xdoc/server/config-webadmin.xml | 4 ++
15 files changed, 160 insertions(+), 17 deletions(-)
diff --git
a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index 536daf3f92..6270c645ac 100644
---
a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++
b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -46,7 +46,6 @@ import com.rabbitmq.client.AMQP;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import reactor.core.publisher.MonoProcessor;
import reactor.core.scheduler.Schedulers;
import reactor.rabbitmq.BindingSpecification;
import reactor.rabbitmq.ExchangeSpecification;
@@ -114,8 +113,7 @@ public class EventDispatcher {
dispatchToLocalListeners(event, keys),
dispatchToRemoteListeners(event, keys))
.doOnError(throwable -> LOGGER.error("error while dispatching
event", throwable))
- .then()
- .subscribeWith(MonoProcessor.create());
+ .then();
}
private Mono<Void> dispatchToLocalListeners(Event event,
Set<RegistrationKey> keys) {
diff --git
a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
index 9914cab1f5..2a76665af1 100644
---
a/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
+++
b/event-bus/distributed/src/main/java/org/apache/james/events/GroupRegistrationHandler.java
@@ -123,7 +123,6 @@ class GroupRegistrationHandler {
receiverProvider::createReceiver,
receiver -> receiver.consumeManualAck(queueName.asString(), new
ConsumeOptions().qos(EventBus.EXECUTION_RATE)),
Receiver::close)
- .publishOn(Schedulers.parallel())
.filter(delivery -> Objects.nonNull(delivery.getBody()))
.flatMap(this::deliver, EventBus.EXECUTION_RATE)
.subscribeOn(Schedulers.elastic())
@@ -139,7 +138,7 @@ class GroupRegistrationHandler {
.map(group -> Pair.of(group, aa))
.collect(ImmutableList.toImmutableList()))
.flatMap(event ->
event.getLeft().runListenerReliably(DEFAULT_RETRY_COUNT, event.getRight()))
-
.then(Mono.<Void>fromRunnable(acknowledgableDelivery::ack).subscribeOn(Schedulers.elastic()))
+
.then(Mono.<Void>fromRunnable(acknowledgableDelivery::ack).subscribeOn(Schedulers.elastic()))
.then()
.onErrorResume(e -> {
LOGGER.error("Unable to process delivery for group {}", GROUP,
e);
@@ -150,8 +149,7 @@ class GroupRegistrationHandler {
}
private Mono<Event> deserializeEvent(byte[] eventAsBytes) {
- return Mono.fromCallable(() -> eventSerializer.fromBytes(eventAsBytes))
- .subscribeOn(Schedulers.parallel());
+ return Mono.fromCallable(() ->
eventSerializer.fromBytes(eventAsBytes));
}
void stop() {
diff --git
a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
index ae693fc9e5..d41a7ced88 100644
---
a/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
+++
b/event-bus/distributed/src/main/java/org/apache/james/events/KeyRegistrationHandler.java
@@ -97,7 +97,6 @@ class KeyRegistrationHandler {
receiverProvider::createReceiver,
receiver -> receiver.consumeAutoAck(registrationQueue.asString(),
new ConsumeOptions().qos(EventBus.EXECUTION_RATE)),
Receiver::close)
- .subscribeOn(Schedulers.parallel())
.flatMap(this::handleDelivery, EventBus.EXECUTION_RATE)
.subscribeOn(Schedulers.elastic())
.subscribe();
diff --git a/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
b/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
index d0693d076d..6d253ef265 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/nav.adoc
@@ -27,6 +27,7 @@
**** xref:configure/cassandra.adoc[cassandra.properties]
**** xref:configure/elasticsearch.adoc[elasticsearch.properties]
**** xref:configure/rabbitmq.adoc[rabbitmq.properties]
+**** xref:configure/redis.adoc[redis.properties]
**** xref:configure/tika.adoc[tika.properties]
*** Core components
**** xref:configure/batchsizes.adoc[batchsizes.properties]
diff --git
a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/index.adoc
b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/index.adoc
index dd346576c5..4ea46ef5a0 100644
--- a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/index.adoc
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/index.adoc
@@ -33,6 +33,8 @@ Except specific documented cases, these files are required,
at least to establis
** xref:configure/cassandra.adoc[*cassandra.properties*] allows to configure
the Cassandra driver
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/cassandra.properties[example]
** xref:configure/elasticsearch.adoc[*elasticsearch.properties*] allows to
configure ElasticSearch driver
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/elasticsearch.properties[example]
** xref:configure/rabbitmq.adoc[*rabbitmq.properties*] allows configuration
for the RabbitMQ driver
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/rabbitmq.properties[example]
+** xref:configure/redis.adoc[*redis.properties*] allows configuration for the
Redis driver
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/redis.properties[example],
that is used by optional
+distributed rate limiting component.
** xref:configure/tika.adoc[*tika.properties*] allows configuring Tika as a
backend for text extraction
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/tika.properties[example]
== For core components
diff --git
a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/redis.adoc
b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/redis.adoc
new file mode 100644
index 0000000000..92ce1e8e2e
--- /dev/null
+++ b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/redis.adoc
@@ -0,0 +1,26 @@
+= Distributed James Server — redis.properties
+:navtitle: redis.properties
+
+This configuration helps you configure components using Redis. This so far
only includes optional rate limiting component.
+
+Consult this
link:https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/redis.properties[example]
+to get some examples and hints.
+
+== Redis Configuration
+
+.redis.properties content
+|===
+| Property name | explanation
+
+| redisURL
+| the Redis URI pointing to Redis server. Compulsory.
+
+| cluster.enabled
+| Whether we should attempt connections to Redis as a cluster.Defaults to
false.
+
+| redis.ioThreads
+| IO threads to be using for the underlying Netty networking resources. If
unspecified driver defaults applies.
+
+| redis.workerThreads
+| Worker threads to be using for the underlying driver. If unspecified driver
defaults applies.
+|===
diff --git
a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/webadmin.adoc
b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/webadmin.adoc
index ff18ee684a..110cb3e37c 100644
---
a/server/apps/distributed-app/docs/modules/ROOT/pages/configure/webadmin.adoc
+++
b/server/apps/distributed-app/docs/modules/ROOT/pages/configure/webadmin.adoc
@@ -63,6 +63,12 @@ Defaults to the `jwt.publickeypem.url` value of
`jmap.properties` file if unspec
needs to be on the classpath or in the ./extensions-jars folder. Read mode
about
xref:extending/webadmin-routes.adoc[creating you own webadmin routes].
+| maxThreadCount
+| Maximum threads used by the underlying Jetty server. Optional.
+
+| minThreadCount
+| Minimum threads used by the underlying Jetty server. Optional.
+
|===
== Generating a JWT key pair
diff --git
a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
index 1fb22e0fe4..a47afbeae0 100644
---
a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
+++
b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
@@ -135,6 +135,8 @@ public class WebAdminServerModule extends AbstractModule {
.additionalRoutes(additionalRoutes)
.jwtPublicKeyPEM(loadPublicKey(fileSystem,
Optional.ofNullable(configurationFile.getString("jwt.publickeypem.url", null))))
+
.maxThreadCount(Optional.ofNullable(configurationFile.getInteger("maxThreadCount",
null)))
+
.minThreadCount(Optional.ofNullable(configurationFile.getInteger("minThreadCount",
null)))
.build();
} catch (FileNotFoundException e) {
LOGGER.info("No webadmin.properties file. Disabling WebAdmin
interface.");
diff --git
a/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiter.scala
b/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiter.scala
index 0012372c5f..26a0d7b8ed 100644
---
a/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiter.scala
+++
b/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiter.scala
@@ -26,9 +26,11 @@ import
es.moki.ratelimitj.core.limiter.request.{AbstractRequestRateLimiterFactor
import es.moki.ratelimitj.redis.request.{RedisClusterRateLimiterFactory,
RedisSlidingWindowRequestRateLimiter, RedisRateLimiterFactory =>
RedisSingleInstanceRateLimitjFactory}
import io.lettuce.core.RedisClient
import io.lettuce.core.cluster.RedisClusterClient
+import io.lettuce.core.resource.ClientResources
import javax.inject.Inject
import org.apache.james.rate.limiter.api.Increment.Increment
import org.apache.james.rate.limiter.api.{AcceptableRate, RateExceeded,
RateLimiter, RateLimiterFactory, RateLimitingKey, RateLimitingResult, Rule,
Rules}
+import org.apache.james.util.concurrent.NamedThreadFactory
import org.apache.james.utils.PropertiesProvider
import org.reactivestreams.Publisher
import reactor.core.scala.publisher.SMono
@@ -48,7 +50,12 @@ class RedisRateLimiterModule() extends AbstractModule {
class RedisRateLimiterFactory @Inject()(redisConfiguration:
RedisRateLimiterConfiguration) extends RateLimiterFactory {
val rateLimitjFactory:
AbstractRequestRateLimiterFactory[RedisSlidingWindowRequestRateLimiter] =
if (redisConfiguration.isCluster) {
- new
RedisClusterRateLimiterFactory(RedisClusterClient.create(redisConfiguration.redisURI.value.asJava))
+ val resourceBuilder = ClientResources.builder()
+ .threadFactoryProvider(poolName =>
NamedThreadFactory.withName(s"redis-driver-$poolName"))
+ redisConfiguration.ioThreads.foreach(value =>
resourceBuilder.ioThreadPoolSize(value))
+ redisConfiguration.workerThreads.foreach(value
=>resourceBuilder.computationThreadPoolSize(value))
+ new
RedisClusterRateLimiterFactory(RedisClusterClient.create(resourceBuilder.build(),
+ redisConfiguration.redisURI.value.asJava))
} else {
new
RedisSingleInstanceRateLimitjFactory(RedisClient.create(redisConfiguration.redisURI.value.last))
}
diff --git
a/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiterConfiguration.scala
b/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiterConfiguration.scala
index 592b34fba7..4ef22434c9 100644
---
a/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiterConfiguration.scala
+++
b/server/mailet/rate-limiter-redis/src/main/scala/org/apache/james/rate/limiter/redis/RedisRateLimiterConfiguration.scala
@@ -32,13 +32,17 @@ object RedisRateLimiterConfiguration {
def from(config: Configuration): RedisRateLimiterConfiguration =
from(config.getString("redisURL"),
- config.getBoolean("cluster.enabled", CLUSTER_ENABLED_DEFAULT))
+ config.getBoolean("cluster.enabled", CLUSTER_ENABLED_DEFAULT),
+ Option(config.getInteger("redis.ioThreads", null)).map(Integer2int),
+ Option(config.getInteger("redis.workerThreads", null)).map(Integer2int))
- def from(redisUri: String, isCluster: Boolean):
RedisRateLimiterConfiguration = {
+ def from(redisUri: String, isCluster: Boolean, ioThreads: Option[Int],
workerThreads:Option[Int]): RedisRateLimiterConfiguration = {
Preconditions.checkArgument(redisUri != null && !redisUri.isBlank)
Preconditions.checkNotNull(isCluster)
- RedisRateLimiterConfiguration(RedisUris.from(redisUri), isCluster)
+ RedisRateLimiterConfiguration(RedisUris.from(redisUri), isCluster,
ioThreads, workerThreads)
}
+
+ def from(redisUri: String, isCluster: Boolean):
RedisRateLimiterConfiguration = from(redisUri, isCluster, None, None)
}
object RedisUris {
@@ -60,4 +64,4 @@ object RedisUris {
def from(value: String): RedisUris =
liftOrThrow(value.split(',').toList.map(RedisURI.create))
}
-case class RedisRateLimiterConfiguration(redisURI: RedisUris, isCluster:
Boolean)
+case class RedisRateLimiterConfiguration(redisURI: RedisUris, isCluster:
Boolean, ioThreads: Option[Int], workerThreads:Option[Int])
diff --git
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
index f5d2279fed..45965abeb9 100644
---
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
+++
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java
@@ -59,6 +59,8 @@ public class WebAdminConfiguration {
private Optional<String> host = Optional.empty();
private ImmutableList.Builder<String> additionalRoutes =
ImmutableList.builder();
private Optional<String> jwtPublicKey = Optional.empty();
+ private Optional<Integer> maxThreadCount = Optional.empty();
+ private Optional<Integer> minThreadCount = Optional.empty();
public Builder jwtPublicKeyPEM(String jwtPublicKeyPEM) {
this.jwtPublicKey = Optional.of(jwtPublicKeyPEM);
@@ -131,6 +133,16 @@ public class WebAdminConfiguration {
return this;
}
+ public Builder minThreadCount(Optional<Integer> minThreadCount) {
+ this.minThreadCount = minThreadCount;
+ return this;
+ }
+
+ public Builder maxThreadCount(Optional<Integer> maxThreadCount) {
+ this.maxThreadCount = maxThreadCount;
+ return this;
+ }
+
public WebAdminConfiguration build() {
Preconditions.checkState(enabled.isPresent(), "You need to
explicitly enable or disable WebAdmin server");
Preconditions.checkState(!enabled.get() || port.isPresent(), "You
need to specify a port for WebAdminConfiguration");
@@ -142,7 +154,9 @@ public class WebAdminConfiguration {
urlCORSOrigin.orElse(CORS_ALL_ORIGINS),
host.orElse(DEFAULT_HOST),
additionalRoutes.build(),
- jwtPublicKey);
+ jwtPublicKey,
+ maxThreadCount,
+ minThreadCount);
}
}
@@ -154,10 +168,12 @@ public class WebAdminConfiguration {
private final String host;
private final List<String> additionalRoutes;
private final Optional<String> jwtPublicKey;
+ private final Optional<Integer> maxThreadCount;
+ private final Optional<Integer> minThreadCount;
@VisibleForTesting
WebAdminConfiguration(boolean enabled, Optional<PortSupplier> port,
Optional<TlsConfiguration> tlsConfiguration,
- boolean enableCORS, String urlCORSOrigin, String
host, List<String> additionalRoutes, Optional<String> jwtPublicKey) {
+ boolean enableCORS, String urlCORSOrigin, String
host, List<String> additionalRoutes, Optional<String> jwtPublicKey,
Optional<Integer> maxThreadCount, Optional<Integer> minThreadCount) {
this.enabled = enabled;
this.port = port;
this.tlsConfiguration = tlsConfiguration;
@@ -166,6 +182,16 @@ public class WebAdminConfiguration {
this.host = host;
this.additionalRoutes = additionalRoutes;
this.jwtPublicKey = jwtPublicKey;
+ this.maxThreadCount = maxThreadCount;
+ this.minThreadCount = minThreadCount;
+ }
+
+ public Optional<Integer> getMaxThreadCount() {
+ return maxThreadCount;
+ }
+
+ public Optional<Integer> getMinThreadCount() {
+ return minThreadCount;
}
public Optional<String> getJwtPublicKey() {
@@ -216,13 +242,15 @@ public class WebAdminConfiguration {
&& Objects.equals(this.jwtPublicKey, that.jwtPublicKey)
&& Objects.equals(this.urlCORSOrigin, that.urlCORSOrigin)
&& Objects.equals(this.host, that.host)
- && Objects.equals(this.additionalRoutes,
that.additionalRoutes);
+ && Objects.equals(this.additionalRoutes, that.additionalRoutes)
+ && Objects.equals(this.minThreadCount, that.minThreadCount)
+ && Objects.equals(this.maxThreadCount, that.maxThreadCount);
}
return false;
}
@Override
public final int hashCode() {
- return Objects.hash(enabled, port, tlsConfiguration, enableCORS,
jwtPublicKey, urlCORSOrigin, host, additionalRoutes);
+ return Objects.hash(enabled, port, tlsConfiguration, enableCORS,
jwtPublicKey, urlCORSOrigin, host, additionalRoutes, minThreadCount,
maxThreadCount);
}
}
diff --git
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
index 1c092aa396..cdad563f52 100644
---
a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
+++
b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/WebAdminServer.java
@@ -58,6 +58,7 @@ public class WebAdminServer implements Startable {
private static final Logger LOGGER =
LoggerFactory.getLogger(WebAdminServer.class);
public static final int DEFAULT_PORT = 8080;
+ private static final int DEFAULTS = -1;
private final WebAdminConfiguration configuration;
private final List<Routes> privateRoutes;
@@ -100,6 +101,7 @@ public class WebAdminServer implements Startable {
throw new RuntimeException(e);
});
if (configuration.isEnabled()) {
+
service.threadPool(configuration.getMaxThreadCount().orElse(DEFAULTS),
configuration.getMinThreadCount().orElse(DEFAULT_PORT), DEFAULTS);
service.ipAddress(listeningIP());
service.port(configuration.getPort().get().getValue());
configureExceptionHanding();
diff --git a/src/site/site.xml b/src/site/site.xml
index b308288288..e163337499 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -130,6 +130,7 @@
<item name="POP3" href="/server/config-pop3.html" />
<item name="Quota" href="/server/config-quota.html" />
<item name="RabbitMQ"
href="/server/config-rabbitmq.html" />
+ <item name="Redis" href="/server/config-redis.html" />
<item name="Recipient Rewrite"
href="/server/config-recipientrewritetable.html" />
<item name="SMTP LMTP"
href="/server/config-smtp-lmtp.html" />
<item name="Sieve" href="/server/config-sieve.html" />
diff --git a/src/site/xdoc/server/config-redis.xml
b/src/site/xdoc/server/config-redis.xml
new file mode 100644
index 0000000000..ef92149ae4
--- /dev/null
+++ b/src/site/xdoc/server/config-redis.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<document>
+
+ <properties>
+ <title>Apache James Server 3 - Redis Configuration</title>
+ </properties>
+
+<body>
+
+ <section name="Redis Server Configuration">
+ <p>
+ Redis is used in distributed James for the optional rate limiting
component.
+
+ This configuration helps you configure components using Redis in
case you want to setup a distributed James.
+ And it is only applicable with Guice products.
+ </p>
+ <p>
+ Consult <a
href="https://github.com/apache/james-project/blob/master/server/apps/distributed-app/sample-configuration/redis.properties">redis.properties</a>
+ in GIT to get some examples and hints.
+ </p>
+
+ <p>
+ RabbitMQ Configuration
+ </p>
+ <dl>
+ <dt><strong>redisURL</strong></dt>
+ <dd>
+ the Redis URI pointing to Redis server. Compulsory.
+ </dd>
+
+ <dt><strong>cluster.enabled</strong></dt>
+ <dd>
+ Whether we should attempt connections to Redis as a
cluster.Defaults to false.
+ </dd>
+
+ <dt><strong>redis.ioThreads</strong></dt>
+ <dd>IO threads to be using for the underlying Netty networking
resources. If unspecified driver defaults applies.</dd>
+
+ <dt><strong>redis.workerThreads</strong></dt>
+ <dd>Worker threads to be using for the underlying driver. If
unspecified driver defaults applies.</dd>
+
+ </dl>
+ </section>
+
+</body>
+
+</document>
diff --git a/src/site/xdoc/server/config-webadmin.xml
b/src/site/xdoc/server/config-webadmin.xml
index 6f57d1a5a9..1160758b96 100644
--- a/src/site/xdoc/server/config-webadmin.xml
+++ b/src/site/xdoc/server/config-webadmin.xml
@@ -57,6 +57,10 @@
<dt><strong>extensions.routes</strong></dt>
<dd>List of Routes specified as fully qualified class name that should
be loaded in addition to your product routes list. Routes
needs to be on the classpath or in the ./extensions-jars
folder.</dd>
+ <dt><strong>maxThreadCount</strong></dt>
+ <dd>Maximum threads used by the underlying Jetty server. Optional.</dd>
+ <dt><strong>minThreadCount</strong></dt>
+ <dd>Minimum threads used by the underlying Jetty server. Optional.</dd>
</dl>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]