Merge branch 'stable-2.16' into stable-3.0 * stable-2.16: Add batchThreadPoolSize to high-availability.config Use dedicated Executor Service for batch indexing Change-Id: Iac5a645e367684245a0cb406b33d5b6d39efe494
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java index 4743bee..093628e 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java
@@ -53,6 +53,7 @@ // common parameters to cache and index sections static final String THREAD_POOL_SIZE_KEY = "threadPoolSize"; + static final String BATCH_THREAD_POOL_SIZE_KEY = "batchThreadPoolSize"; static final int DEFAULT_INDEX_MAX_TRIES = 2; static final int DEFAULT_INDEX_RETRY_INTERVAL = 30000; static final int DEFAULT_THREAD_POOL_SIZE = 4; @@ -453,6 +454,7 @@ static final boolean DEFAULT_SYNCHRONIZE_FORCED = true; private final int threadPoolSize; + private final int batchThreadPoolSize; private final int retryInterval; private final int maxTries; private final int numStripedLocks; @@ -461,6 +463,7 @@ private Index(Config cfg) { super(cfg, INDEX_SECTION); threadPoolSize = getInt(cfg, INDEX_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE); + batchThreadPoolSize = getInt(cfg, INDEX_SECTION, BATCH_THREAD_POOL_SIZE_KEY, threadPoolSize); numStripedLocks = getInt(cfg, INDEX_SECTION, NUM_STRIPED_LOCKS, DEFAULT_NUM_STRIPED_LOCKS); retryInterval = getInt(cfg, INDEX_SECTION, RETRY_INTERVAL_KEY, DEFAULT_INDEX_RETRY_INTERVAL); maxTries = getInt(cfg, INDEX_SECTION, MAX_TRIES_KEY, DEFAULT_INDEX_MAX_TRIES); @@ -472,6 +475,10 @@ return threadPoolSize; } + public int batchThreadPoolSize() { + return batchThreadPoolSize; + } + public int numStripedLocks() { return numStripedLocks; }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexBatchChangeHandler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexBatchChangeHandler.java new file mode 100644 index 0000000..dee8876 --- /dev/null +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexBatchChangeHandler.java
@@ -0,0 +1,38 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed 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. + +package com.ericsson.gerrit.plugins.highavailability.forwarder; + +import com.ericsson.gerrit.plugins.highavailability.Configuration; +import com.ericsson.gerrit.plugins.highavailability.index.ChangeCheckerImpl.Factory; +import com.ericsson.gerrit.plugins.highavailability.index.ForwardedBatchIndexExecutor; +import com.google.gerrit.server.index.change.ChangeIndexer; +import com.google.gerrit.server.util.OneOffRequestContext; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.util.concurrent.ScheduledExecutorService; + +@Singleton +public class ForwardedIndexBatchChangeHandler extends ForwardedIndexChangeHandler { + + @Inject + ForwardedIndexBatchChangeHandler( + ChangeIndexer indexer, + Configuration config, + @ForwardedBatchIndexExecutor ScheduledExecutorService indexExecutor, + OneOffRequestContext oneOffCtx, + Factory changeCheckerFactory) { + super(indexer, config, indexExecutor, oneOffCtx, changeCheckerFactory); + } +}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/IndexBatchChangeRestApiServlet.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/IndexBatchChangeRestApiServlet.java index c8518eb..6613ee6 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/IndexBatchChangeRestApiServlet.java +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/IndexBatchChangeRestApiServlet.java
@@ -14,7 +14,7 @@ package com.ericsson.gerrit.plugins.highavailability.forwarder.rest; -import com.ericsson.gerrit.plugins.highavailability.forwarder.ForwardedIndexChangeHandler; +import com.ericsson.gerrit.plugins.highavailability.forwarder.ForwardedIndexBatchChangeHandler; import com.google.gerrit.extensions.restapi.Url; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -24,7 +24,7 @@ private static final long serialVersionUID = -1L; @Inject - IndexBatchChangeRestApiServlet(ForwardedIndexChangeHandler handler) { + IndexBatchChangeRestApiServlet(ForwardedIndexBatchChangeHandler handler) { super(handler, IndexName.CHANGE, true); }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutor.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutor.java new file mode 100644 index 0000000..06da9f0 --- /dev/null +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutor.java
@@ -0,0 +1,24 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed 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. + +package com.ericsson.gerrit.plugins.highavailability.index; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.inject.BindingAnnotation; +import java.lang.annotation.Retention; + +@Retention(RUNTIME) +@BindingAnnotation +@interface BatchIndexExecutor {}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutorProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutorProvider.java new file mode 100644 index 0000000..cfbd4fb --- /dev/null +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/BatchIndexExecutorProvider.java
@@ -0,0 +1,30 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed 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. + +package com.ericsson.gerrit.plugins.highavailability.index; + +import com.ericsson.gerrit.plugins.highavailability.Configuration; +import com.ericsson.gerrit.plugins.highavailability.ExecutorProvider; +import com.google.gerrit.server.git.WorkQueue; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +class BatchIndexExecutorProvider extends ExecutorProvider { + + @Inject + BatchIndexExecutorProvider(WorkQueue workQueue, Configuration config) { + super(workQueue, config.index().batchThreadPoolSize(), "Forward-BatchIndex-Event"); + } +}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutor.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutor.java new file mode 100644 index 0000000..b5b6aab --- /dev/null +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutor.java
@@ -0,0 +1,24 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed 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. + +package com.ericsson.gerrit.plugins.highavailability.index; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.inject.BindingAnnotation; +import java.lang.annotation.Retention; + +@Retention(RUNTIME) +@BindingAnnotation +public @interface ForwardedBatchIndexExecutor {}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutorProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutorProvider.java new file mode 100644 index 0000000..f5bc85e --- /dev/null +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/ForwardedBatchIndexExecutorProvider.java
@@ -0,0 +1,30 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed 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. + +package com.ericsson.gerrit.plugins.highavailability.index; + +import com.ericsson.gerrit.plugins.highavailability.Configuration; +import com.ericsson.gerrit.plugins.highavailability.ExecutorProvider; +import com.google.gerrit.server.git.WorkQueue; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +class ForwardedBatchIndexExecutorProvider extends ExecutorProvider { + + @Inject + ForwardedBatchIndexExecutorProvider(WorkQueue workQueue, Configuration config) { + super(workQueue, config.index().batchThreadPoolSize(), "Forwarded-BatchIndex-Event"); + } +}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java index 2344b06..73e842f 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java
@@ -40,6 +40,7 @@ ProjectIndexedListener { private static final FluentLogger log = FluentLogger.forEnclosingClass(); private final ScheduledExecutorService executor; + private final ScheduledExecutorService batchExecutor; private final Forwarder forwarder; private final String pluginName; private final Set<IndexTask> queuedTasks = Collections.newSetFromMap(new ConcurrentHashMap<>()); @@ -53,6 +54,7 @@ @Inject IndexEventHandler( @IndexExecutor ScheduledExecutorService executor, + @BatchIndexExecutor ScheduledExecutorService batchExecutor, @PluginName String pluginName, Forwarder forwarder, ChangeCheckerImpl.Factory changeChecker, @@ -61,6 +63,7 @@ IndexEventLocks locks) { this.forwarder = forwarder; this.executor = executor; + this.batchExecutor = batchExecutor; this.pluginName = pluginName; this.changeChecker = changeChecker; this.currCtx = currCtx; @@ -105,7 +108,11 @@ .ifPresent( task -> { if (queuedTasks.add(task)) { - executor.execute(task); + if (task instanceof BatchIndexChangeTask) { + batchExecutor.execute(task); + } else { + executor.execute(task); + } } }); } catch (Exception e) {
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexModule.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexModule.java index 4a25fc8..3bcc34f 100644 --- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexModule.java +++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexModule.java
@@ -35,6 +35,12 @@ .annotatedWith(ForwardedIndexExecutor.class) .toProvider(ForwardedIndexExecutorProvider.class); bind(IndexEventLocks.class).in(Scopes.SINGLETON); + bind(ScheduledExecutorService.class) + .annotatedWith(BatchIndexExecutor.class) + .toProvider(BatchIndexExecutorProvider.class); + bind(ScheduledExecutorService.class) + .annotatedWith(ForwardedBatchIndexExecutor.class) + .toProvider(ForwardedBatchIndexExecutorProvider.class); listener().to(IndexExecutorProvider.class); DynamicSet.bind(binder(), ChangeIndexedListener.class) .to(IndexEventHandler.class)
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md index 489c9f4..360218d 100644 --- a/src/main/resources/Documentation/config.md +++ b/src/main/resources/Documentation/config.md
@@ -196,6 +196,11 @@ : Maximum number of threads used to send index events to the target instance. Defaults to 4. +```index.batchThreadPoolSize``` +: Maximum number of threads used to send batch index events to the target instance + and not associated to an interactive action performed by a user. + Defaults equal index.threadPoolSize. + ```index.maxTries``` : Maximum number of times the plugin should attempt to reindex changes. Setting this value to 0 will disable retries. After this number of failed tries,
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java index a9537bd..3444625 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
@@ -14,6 +14,7 @@ package com.ericsson.gerrit.plugins.highavailability; +import static com.ericsson.gerrit.plugins.highavailability.Configuration.BATCH_THREAD_POOL_SIZE_KEY; import static com.ericsson.gerrit.plugins.highavailability.Configuration.Cache.CACHE_SECTION; import static com.ericsson.gerrit.plugins.highavailability.Configuration.Cache.PATTERN_KEY; import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_NUM_STRIPED_LOCKS; @@ -266,6 +267,19 @@ } @Test + public void testGetBatchIndexThreadPoolSize() throws Exception { + assertThat(getConfiguration().index().batchThreadPoolSize()) + .isEqualTo(DEFAULT_THREAD_POOL_SIZE); + + globalPluginConfig.setInt(INDEX_SECTION, null, BATCH_THREAD_POOL_SIZE_KEY, THREAD_POOL_SIZE); + assertThat(getConfiguration().index().batchThreadPoolSize()).isEqualTo(THREAD_POOL_SIZE); + + globalPluginConfig.setString(INDEX_SECTION, null, BATCH_THREAD_POOL_SIZE_KEY, INVALID_INT); + assertThat(getConfiguration().index().batchThreadPoolSize()) + .isEqualTo(DEFAULT_THREAD_POOL_SIZE); + } + + @Test public void testGetIndexSynchronize() throws Exception { assertThat(getConfiguration().index().synchronize()).isEqualTo(DEFAULT_SYNCHRONIZE);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java index 0f21ff7..5f08cc5 100644 --- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java +++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java
@@ -85,6 +85,7 @@ private Account.Id accountId; private AccountGroup.UUID accountGroupUUID; private ScheduledExecutorService executor = new CurrentThreadScheduledExecutorService(); + private ScheduledExecutorService batchExecutor = new CurrentThreadScheduledExecutorService(); private ScheduledExecutorService testExecutor = Executors.newScheduledThreadPool(MAX_TEST_PARALLELISM); @Mock private RequestContext mockCtx; @@ -142,6 +143,7 @@ indexEventHandler = new IndexEventHandler( executor, + batchExecutor, PLUGIN_NAME, forwarder, changeCheckerFactoryMock, @@ -387,9 +389,11 @@ @Test public void duplicateChangeEventOfAQueuedEventShouldGetDiscarded() { ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class); + ScheduledThreadPoolExecutor poolBatchMock = mock(ScheduledThreadPoolExecutor.class); indexEventHandler = new IndexEventHandler( poolMock, + poolBatchMock, PLUGIN_NAME, forwarder, changeCheckerFactoryMock, @@ -405,9 +409,11 @@ @Test public void duplicateAccountEventOfAQueuedEventShouldGetDiscarded() { ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class); + ScheduledThreadPoolExecutor poolBatchMock = mock(ScheduledThreadPoolExecutor.class); indexEventHandler = new IndexEventHandler( poolMock, + poolBatchMock, PLUGIN_NAME, forwarder, changeCheckerFactoryMock, @@ -422,9 +428,11 @@ @Test public void duplicateGroupEventOfAQueuedEventShouldGetDiscarded() { ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class); + ScheduledThreadPoolExecutor poolBatchMock = mock(ScheduledThreadPoolExecutor.class); indexEventHandler = new IndexEventHandler( poolMock, + poolBatchMock, PLUGIN_NAME, forwarder, changeCheckerFactoryMock,