You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by dr...@apache.org on 2022/08/22 12:12:14 UTC
[ratis] 01/03: RATIS-1586. Set useCacheForAllThreads default to false. (#651)
This is an automated email from the ASF dual-hosted git repository.
dragonyliu pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/ratis.git
commit ef3b9b1248052bac2c58d780f04e3a39f0cbd835
Author: Tsz-Wo Nicholas Sze <sz...@apache.org>
AuthorDate: Thu Aug 18 08:45:02 2022 -0700
RATIS-1586. Set useCacheForAllThreads default to false. (#651)
(cherry picked from commit e5ee38ab0d38f5e785880a504d39c671c1b4d533)
---
.../main/java/org/apache/ratis/util/JavaUtils.java | 47 +++++++++++++++++++++-
.../java/org/apache/ratis/grpc/GrpcFactory.java | 24 ++++++++---
.../org/apache/ratis/grpc/TestGrpcFactory.java | 33 +++++++++++++++
3 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java b/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
index b3a8f7e99..80162e101 100644
--- a/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
+++ b/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
@@ -25,6 +25,8 @@ import org.slf4j.LoggerFactory;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
@@ -49,7 +51,7 @@ import java.util.function.Supplier;
public interface JavaUtils {
Logger LOG = LoggerFactory.getLogger(JavaUtils.class);
- CompletableFuture[] EMPTY_COMPLETABLE_FUTURE_ARRAY = {};
+ CompletableFuture<?>[] EMPTY_COMPLETABLE_FUTURE_ARRAY = {};
ConcurrentMap<Class<?>, String> CLASS_SIMPLE_NAMES = new ConcurrentHashMap<>();
static String getClassSimpleName(Class<?> clazz) {
@@ -120,6 +122,49 @@ public interface JavaUtils {
}
}
+ static <T> T doPrivileged(Supplier<T> action, Function<SecurityException, T> exceptionHandler) {
+ try {
+ return System.getSecurityManager() == null? action.get()
+ : AccessController.doPrivileged((PrivilegedAction<T>) action::get);
+ } catch (SecurityException e) {
+ return exceptionHandler.apply(e);
+ }
+ }
+
+ static <T> T doPrivileged(Supplier<T> action, Supplier<String> name) {
+ return doPrivileged(action, e -> {
+ LOG.warn("Failed to " + name.get(), e);
+ return null;
+ });
+ }
+
+ /**
+ * Similar to {@link System#getProperty(String)}
+ * except that this method may invoke {@link AccessController#doPrivileged(PrivilegedAction)}
+ * if there is a {@link SecurityManager}.
+ *
+ * @return null if either the property is not set or there is a {@link SecurityException};
+ * otherwise, return system property value.
+ */
+ static String getSystemProperty(final String key) {
+ Preconditions.assertNotNull(key, "key");
+ Preconditions.assertTrue(!key.isEmpty(), "key is empty.");
+ return doPrivileged(() -> System.getProperty(key), () -> "get system property " + key);
+ }
+
+ /**
+ * Similar to {@link System#setProperty(String, String)}
+ * except that this method may invoke {@link AccessController#doPrivileged(PrivilegedAction)}
+ * if there is a {@link SecurityManager}.
+ * When there is a {@link SecurityException}, this becomes a NOOP.
+ */
+ static void setSystemProperty(String key, String value) {
+ Preconditions.assertNotNull(key, "key");
+ Preconditions.assertTrue(!key.isEmpty(), "key is empty.");
+ Preconditions.assertNotNull(value, "value");
+ doPrivileged(() -> System.setProperty(key, value), () -> "set system property " + key + " to " + value);
+ }
+
/**
* Create a memoized supplier which gets a value by invoking the initializer once
* and then keeps returning the same value as its supplied results.
diff --git a/ratis-grpc/src/main/java/org/apache/ratis/grpc/GrpcFactory.java b/ratis-grpc/src/main/java/org/apache/ratis/grpc/GrpcFactory.java
index 5da5fc5c9..75eb34a2d 100644
--- a/ratis-grpc/src/main/java/org/apache/ratis/grpc/GrpcFactory.java
+++ b/ratis-grpc/src/main/java/org/apache/ratis/grpc/GrpcFactory.java
@@ -31,6 +31,7 @@ import org.apache.ratis.server.ServerFactory;
import org.apache.ratis.server.leader.FollowerInfo;
import org.apache.ratis.server.leader.LeaderState;
import org.apache.ratis.thirdparty.io.netty.buffer.PooledByteBufAllocator;
+import org.apache.ratis.util.JavaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,16 +41,27 @@ public class GrpcFactory implements ServerFactory, ClientFactory {
public static final Logger LOG = LoggerFactory.getLogger(GrpcFactory.class);
- private void checkPooledByteBufAllocatorUseCacheForAllThreads(Consumer<String> log) {
- final String name = "useCacheForAllThreads";
- final String key = "org.apache.ratis.thirdparty.io.netty.allocator." + name;
+ static final String USE_CACHE_FOR_ALL_THREADS_NAME = "useCacheForAllThreads";
+ static final String USE_CACHE_FOR_ALL_THREADS_KEY = "org.apache.ratis.thirdparty.io.netty.allocator."
+ + USE_CACHE_FOR_ALL_THREADS_NAME;
+ static {
+ // see org.apache.ratis.thirdparty.io.netty.buffer.PooledByteBufAllocator.DEFAULT_USE_CACHE_FOR_ALL_THREADS
+ final String value = JavaUtils.getSystemProperty(USE_CACHE_FOR_ALL_THREADS_KEY);
+ if (value == null) {
+ // Set the property to false, when it is not set.
+ JavaUtils.setSystemProperty(USE_CACHE_FOR_ALL_THREADS_KEY, Boolean.FALSE.toString());
+ }
+ }
+
+ static boolean checkPooledByteBufAllocatorUseCacheForAllThreads(Consumer<String> log) {
final boolean value = PooledByteBufAllocator.defaultUseCacheForAllThreads();
if (value) {
- log.accept("PERFORMANCE WARNING: " + name + " is " + value
+ log.accept("PERFORMANCE WARNING: " + USE_CACHE_FOR_ALL_THREADS_NAME + " is " + true
+ " that may cause Netty to create a lot garbage objects and, as a result, trigger GC.\n"
- + "\tIt is recommended to disable " + name + " by setting -D" + key
- + "=" + !value + " in command line.");
+ + "\tIt is recommended to disable " + USE_CACHE_FOR_ALL_THREADS_NAME
+ + " by setting -D" + USE_CACHE_FOR_ALL_THREADS_KEY + "=" + false + " in command line.");
}
+ return value;
}
private final GrpcTlsConfig tlsConfig;
diff --git a/ratis-test/src/test/java/org/apache/ratis/grpc/TestGrpcFactory.java b/ratis-test/src/test/java/org/apache/ratis/grpc/TestGrpcFactory.java
new file mode 100644
index 000000000..76fbcee5e
--- /dev/null
+++ b/ratis-test/src/test/java/org/apache/ratis/grpc/TestGrpcFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 org.apache.ratis.grpc;
+
+import org.apache.ratis.BaseTest;
+import org.apache.ratis.util.JavaUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestGrpcFactory extends BaseTest {
+ @Test
+ public void testUseCacheForAllThreads() {
+ // trigger GrpcFactory static initializer
+ final boolean value = GrpcFactory.checkPooledByteBufAllocatorUseCacheForAllThreads(LOG::info);
+ Assert.assertFalse(value);
+ LOG.info("value is {}", value);
+ }
+}
\ No newline at end of file