Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); RATIS-1709 Support specify ThreadGroup for Daemon threads by jiacheliu3 · Pull Request #733 · apache/ratis · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
84af089
init commit
jiacheliu3 Sep 3, 2022
11c5469
improve API
jiacheliu3 Sep 3, 2022
7a75248
improve the todos somehow
jiacheliu3 Sep 3, 2022
17f7fc2
consolidate Daemon constructors to use Builder pattern
jiacheliu3 Sep 3, 2022
68f6a76
minor improvements
jiacheliu3 Sep 3, 2022
4ca2d87
add license
jiacheliu3 Sep 5, 2022
17d2e9e
fix some tests
jiacheliu3 Sep 5, 2022
f80a88b
improve builder
jiacheliu3 Sep 5, 2022
4777d5c
fix TimeoutScheduler test
jiacheliu3 Sep 5, 2022
705c4eb
fix tests
jiacheliu3 Sep 5, 2022
eb76c1a
remove extra prints
jiacheliu3 Sep 5, 2022
66cac90
checkstyle
jiacheliu3 Sep 5, 2022
ec50556
resolve some comments
jiacheliu3 Sep 9, 2022
c694ddf
supply uncaughtExceptionHandler from application
jiacheliu3 Sep 9, 2022
ae22a81
remove ErrorRecorded interface
jiacheliu3 Sep 9, 2022
119ec6b
attempt to add backward compatibility
jiacheliu3 Sep 9, 2022
77f92d8
checkstyle
jiacheliu3 Sep 9, 2022
574f5cf
remove unused var
jiacheliu3 Sep 9, 2022
b4a2019
Merge remote-tracking branch 'upstream/master' into store-error-in-da…
jiacheliu3 Sep 14, 2022
3ddcae9
resolve some comments
jiacheliu3 Sep 15, 2022
443a37e
remove extra methods from interfaces
jiacheliu3 Sep 15, 2022
9df4115
code format
jiacheliu3 Sep 15, 2022
7e5e012
a minor formatting
jiacheliu3 Sep 15, 2022
8197792
remove todos
jiacheliu3 Sep 15, 2022
9ce1281
use ThreadGroup instead of UncaughtExceptionHandler
jiacheliu3 Sep 16, 2022
00681d9
resolve a minor comment
jiacheliu3 Sep 16, 2022
53ba4b9
resolve comments
jiacheliu3 Sep 19, 2022
b824308
resolve comments
jiacheliu3 Sep 19, 2022
05575a7
comment
jiacheliu3 Sep 19, 2022
2ddce34
resolve comments
jiacheliu3 Sep 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ public class Daemon extends Thread {

/** Construct a daemon thread with flexible arguments. */
protected Daemon(Builder builder) {
super(builder.runnable);
super(builder.threadGroup, builder.runnable);
setName(builder.name);
}

Expand All@@ -38,6 +38,7 @@ public static Builder newBuilder() {
public static class Builder {
Comment thread
jiacheliu3 marked this conversation as resolved.
private String name;
private Runnable runnable;
private ThreadGroup threadGroup;

public Builder setName(String name) {
this.name = name;
Expand All@@ -49,6 +50,11 @@ public Builder setRunnable(Runnable runnable) {
return this;
}

public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}

public Daemon build() {
Objects.requireNonNull(name, "name == null");
return new Daemon(this);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -116,6 +116,9 @@ default RaftGroup getGroup() {
/** @return the internal {@link RaftClient} of this division. */
RaftClient getRaftClient();

/** @return the {@link ThreadGroup} the threads of this Division belong to. */
ThreadGroup getThreadGroup();

@Override
void close();
}
Expand DownExpand Up@@ -168,7 +171,7 @@ class Builder {
private static Method initNewRaftServerMethod() {
final String className = RaftServer.class.getPackage().getName() + ".impl.ServerImplUtils";
final Class<?>[] argClasses = {RaftPeerId.class, RaftGroup.class, RaftStorage.StartupOption.class,
StateMachine.Registry.class, RaftProperties.class, Parameters.class};
StateMachine.Registry.class, ThreadGroup.class, RaftProperties.class, Parameters.class};
try {
final Class<?> clazz = ReflectionUtils.getClassByName(className);
return clazz.getMethod("newRaftServer", argClasses);
Expand All@@ -178,11 +181,11 @@ private static Method initNewRaftServerMethod() {
}

private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, RaftStorage.StartupOption option,
StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
try {
return (RaftServer) NEW_RAFT_SERVER_METHOD.invoke(null,
serverId, group, option, stateMachineRegistry, properties, parameters);
serverId, group, option, stateMachineRegistry, threadGroup, properties, parameters);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to build " + serverId, e);
} catch (InvocationTargetException e) {
Expand All@@ -196,6 +199,7 @@ private static RaftServer newRaftServer(RaftPeerId serverId, RaftGroup group, Ra
private RaftStorage.StartupOption option = RaftStorage.StartupOption.FORMAT;
private RaftProperties properties;
private Parameters parameters;
private ThreadGroup threadGroup;

/** @return a {@link RaftServer} object. */
public RaftServer build() throws IOException {
Expand All@@ -205,6 +209,7 @@ public RaftServer build() throws IOException {
option,
Objects.requireNonNull(stateMachineRegistry , "Neither 'stateMachine' nor 'setStateMachineRegistry' " +
"is initialized."),
threadGroup,
Objects.requireNonNull(properties, "The 'properties' field is not initialized."),
parameters);
}
Expand DownExpand Up@@ -249,5 +254,15 @@ public Builder setParameters(Parameters parameters) {
this.parameters = parameters;
return this;
}

/**
* Set {@link ThreadGroup} so the application can control RaftServer threads consistently with the application.
* For example, configure {@link ThreadGroup#uncaughtException(Thread, Throwable)} for the whole thread group.
* If not set, the new thread will be put into the thread group of the caller thread.
*/
public Builder setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
return this;
}
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,9 @@ int update(AtomicInteger outstanding) {
private final AtomicInteger outstandingOp = new AtomicInteger();

FollowerState(RaftServerImpl server, Object reason) {
super(newBuilder().setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class)));
super(newBuilder()

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to get rid of the extra Daemon() no-arg constructor

.setName(server.getMemberId() + "-" + JavaUtils.getClassSimpleName(FollowerState.class))
.setThreadGroup(server.getThreadGroup()));
this.server = server;
this.reason = reason;
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -190,7 +190,8 @@ public String toString() {
LeaderElection(RaftServerImpl server, boolean skipPreVote) {
this.name = server.getMemberId() + "-" + JavaUtils.getClassSimpleName(getClass()) + COUNT.incrementAndGet();
this.lifeCycle = new LifeCycle(this);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.server = server;
this.skipPreVote = skipPreVote ||
!RaftServerConfigKeys.LeaderElection.preVote(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ boolean removeAll(Collection<LogAppender> c) {
this.currentTerm = state.getCurrentTerm();

this.eventQueue = new EventQueue();
processor = new EventProcessor(this.name);
processor = new EventProcessor(this.name, server);
raftServerMetrics = server.getRaftServerMetrics();
logAppenderMetrics = new LogAppenderMetrics(server.getMemberId());
this.pendingRequests = new PendingRequests(server.getMemberId(), properties, raftServerMetrics);
Expand DownExpand Up@@ -620,8 +620,9 @@ private void prepare() {
* state, such as changing to follower, or updating the committed index.
*/
private class EventProcessor extends Daemon {
public EventProcessor(String name) {
super(Daemon.newBuilder().setName(name));
public EventProcessor(String name, RaftServerImpl server) {
super(Daemon.newBuilder()
.setName(name).setThreadGroup(server.getThreadGroup()));
}
@Override
public void run() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,7 +97,7 @@

class RaftServerImpl implements RaftServer.Division,
RaftServerProtocol, RaftServerAsynchronousProtocol,
RaftClientProtocol, RaftClientAsynchronousProtocol{
RaftClientProtocol, RaftClientAsynchronousProtocol{
private static final String CLASS_NAME = JavaUtils.getClassSimpleName(RaftServerImpl.class);
static final String REQUEST_VOTE = CLASS_NAME + ".requestVote";
static final String APPEND_ENTRIES = CLASS_NAME + ".appendEntries";
Expand DownExpand Up@@ -189,6 +189,7 @@ public long[] getFollowerNextIndices() {
private final ExecutorService clientExecutor;

private final AtomicBoolean firstElectionSinceStartup = new AtomicBoolean(true);
private final ThreadGroup threadGroup;

RaftServerImpl(RaftGroup group, StateMachine stateMachine, RaftServerProxy proxy, RaftStorage.StartupOption option)
throws IOException {
Expand DownExpand Up@@ -216,6 +217,7 @@ public long[] getFollowerNextIndices() {
getMemberId(), () -> commitInfoCache::get, retryCache::getStatistics);

this.startComplete = new AtomicBoolean(false);
this.threadGroup = new ThreadGroup(proxy.getThreadGroup(), getMemberId().toString());

this.raftClient = JavaUtils.memoize(() -> RaftClient.newBuilder()
.setRaftGroup(group)
Expand DownExpand Up@@ -274,6 +276,11 @@ TimeDuration getSleepDeviationThreshold() {
return sleepDeviationThreshold;
}

@Override
public ThreadGroup getThreadGroup() {
Comment thread
jiacheliu3 marked this conversation as resolved.
return threadGroup;
}

@Override
public StateMachine getStateMachine() {
return stateMachine;
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,9 +196,10 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
private final ExecutorService executor;

private final JvmPauseMonitor pauseMonitor;
private final ThreadGroup threadGroup;

RaftServerProxy(RaftPeerId id, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) {
RaftProperties properties, Parameters parameters, ThreadGroup threadGroup) {
this.properties = properties;
this.stateMachineRegistry = stateMachineRegistry;

Expand All@@ -221,6 +222,7 @@ String toString(RaftGroupId groupId, CompletableFuture<RaftServerImpl> f) {
final TimeDuration leaderStepDownWaitTime = RaftServerConfigKeys.LeaderElection.leaderStepDownWaitTime(properties);
this.pauseMonitor = new JvmPauseMonitor(id,
extraSleep -> handleJvmPause(extraSleep, rpcSlownessTimeout, leaderStepDownWaitTime));
this.threadGroup = threadGroup == null ? new ThreadGroup(this.id.toString()) : threadGroup;
}

private void handleJvmPause(TimeDuration extraSleep, TimeDuration closeThreshold, TimeDuration stepDownThreshold)
Expand DownExpand Up@@ -379,6 +381,10 @@ public LifeCycle.State getLifeCycleState() {
return lifeCycle.getCurrentState();
}

ThreadGroup getThreadGroup() {
return threadGroup;
}

@Override
public void start() throws IOException {
lifeCycle.startAndTransition(this::startImpl, IOException.class);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,26 +47,26 @@ private ServerImplUtils() {
/** Create a {@link RaftServerProxy}. */
public static RaftServerProxy newRaftServer(
RaftPeerId id, RaftGroup group, RaftStorage.StartupOption option, StateMachine.Registry stateMachineRegistry,
RaftProperties properties, Parameters parameters) throws IOException {
ThreadGroup threadGroup, RaftProperties properties, Parameters parameters) throws IOException {
RaftServer.LOG.debug("newRaftServer: {}, {}", id, group);
if (group != null && !group.getPeers().isEmpty()) {
Preconditions.assertNotNull(id, "RaftPeerId %s is not in RaftGroup %s", id, group);
Preconditions.assertNotNull(group.getPeer(id), "RaftPeerId %s is not in RaftGroup %s", id, group);
}
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, properties, parameters);
final RaftServerProxy proxy = newRaftServer(id, stateMachineRegistry, threadGroup, properties, parameters);
proxy.initGroups(group, option);
return proxy;
}

private static RaftServerProxy newRaftServer(
RaftPeerId id, StateMachine.Registry stateMachineRegistry, RaftProperties properties, Parameters parameters)
throws IOException {
RaftPeerId id, StateMachine.Registry stateMachineRegistry, ThreadGroup threadGroup, RaftProperties properties,
Parameters parameters) throws IOException {
final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
final RaftServerProxy proxy;
try {
// attempt multiple times to avoid temporary bind exception
proxy = JavaUtils.attemptRepeatedly(
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters),
() -> new RaftServerProxy(id, stateMachineRegistry, properties, parameters, threadGroup),
5, sleepTime, "new RaftServerProxy", RaftServer.LOG);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,8 +113,8 @@ public int getNumSnapshotsRetained() {
}
};
this.purgeUptoSnapshotIndex = RaftServerConfigKeys.Log.purgeUptoSnapshotIndex(properties);

updater = Daemon.newBuilder().setName(name).setRunnable(this).build();
updater = Daemon.newBuilder().setName(name).setRunnable(this)
.setThreadGroup(server.getThreadGroup()).build();
this.awaitForSignal = new AwaitForSignal(name);
this.stateMachineMetrics = MemoizedSupplier.valueOf(
() -> StateMachineMetrics.getStateMachineMetrics(server, appliedIndex, stateMachine));
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,8 @@ class LogAppenderDaemon {
this.logAppender = logAppender;
this.name = logAppender + "-" + JavaUtils.getClassSimpleName(getClass());
this.lifeCycle = new LifeCycle(name);
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run).build();
this.daemon = Daemon.newBuilder().setName(name).setRunnable(this::run)
.setThreadGroup(logAppender.getServer().getThreadGroup()).build();
}

public boolean isWorking() {
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -390,7 +390,7 @@ private RaftServerProxy newRaftServer(RaftPeerId id, RaftGroup group, boolean fo
RaftServerConfigKeys.setStorageDir(prop, Collections.singletonList(dir));
return ServerImplUtils.newRaftServer(id, group,
format? RaftStorage.StartupOption.FORMAT: RaftStorage.StartupOption.RECOVER,
getStateMachineRegistry(prop), prop, setPropertiesAndInitParameters(id, group, prop));
getStateMachineRegistry(prop), null, prop, setPropertiesAndInitParameters(id, group, prop));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down