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 &mdash; 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]

Reply via email to