summaryrefslogtreecommitdiff
path: root/src/main/java/events
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-27 13:05:59 +0200
committerPaul Buetow <paul@buetow.org>2026-03-27 13:05:59 +0200
commitf55d67d98dddf5861dc4266564863dde4b0b6ed1 (patch)
treeb87ad04a444b9873cb9ec0ede643772f160e6012 /src/main/java/events
parent29252fbc7803e4a660332524d5811ff942e2b0bc (diff)
sr: retune Raft replay for faster reelection
Diffstat (limited to 'src/main/java/events')
-rw-r--r--src/main/java/events/VSRegisteredEvents.java2
-rw-r--r--src/main/java/events/internal/VSProtocolEvent.java51
-rw-r--r--src/main/java/events/internal/VSProtocolScheduleEvent.java97
3 files changed, 148 insertions, 2 deletions
diff --git a/src/main/java/events/VSRegisteredEvents.java b/src/main/java/events/VSRegisteredEvents.java
index 8d31b0e..2ce24ea 100644
--- a/src/main/java/events/VSRegisteredEvents.java
+++ b/src/main/java/events/VSRegisteredEvents.java
@@ -88,6 +88,8 @@ public final class VSRegisteredEvents {
registerEvent("events.implementations.VSVectorTimestampEvent");
registerEvent("events.implementations.VSTimestampMonitorEvent");
registerEvent("events.implementations.VSTimestampTriggeredEvent");
+ registerEvent("events.internal.VSProtocolEvent");
+ registerEvent("events.internal.VSProtocolScheduleEvent");
registerEvent("protocols.implementations.VSBasicMulticastProtocol");
registerEvent("protocols.implementations.VSBerkelyTimeProtocol");
registerEvent("protocols.implementations.VSBroadcastProtocol");
diff --git a/src/main/java/events/internal/VSProtocolEvent.java b/src/main/java/events/internal/VSProtocolEvent.java
index 5cbe6df..41adc3c 100644
--- a/src/main/java/events/internal/VSProtocolEvent.java
+++ b/src/main/java/events/internal/VSProtocolEvent.java
@@ -3,6 +3,8 @@ package events.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
import core.VSInternalProcess;
import core.VSTask;
@@ -43,6 +45,9 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
/** The event is a protocol activation if true. Else it is a deactivation */
private boolean isProtocolActivation;
+ /** Optional long preference overrides applied when the protocol starts. */
+ private HashMap<String, Long> longOverrides;
+
/* (non-Javadoc)
* @see events.VSCopyableEvent#initCopy(events.VSAbstractEvent)
*/
@@ -51,6 +56,10 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
protocolEventCopy.isClientProtocol(isClientProtocol);
protocolEventCopy.isProtocolActivation(isProtocolActivation);
protocolEventCopy.setProtocolClassname(protocolClassname);
+ if (longOverrides != null) {
+ protocolEventCopy.longOverrides =
+ new HashMap<String, Long>(longOverrides);
+ }
}
/* (non-Javadoc)
@@ -108,6 +117,20 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
public void setProtocolClassname(String protocolClassname) {
this.protocolClassname = protocolClassname;
}
+
+ /**
+ * Overrides a long preference before the protocol starts.
+ *
+ * @param key the preference key
+ * @param value the value to apply
+ */
+ public void setLongOverride(String key, long value) {
+ if (longOverrides == null) {
+ longOverrides = new HashMap<String, Long>();
+ }
+
+ longOverrides.put(key, Long.valueOf(value));
+ }
/**
* Checks if we should schedule a protocol start task.
@@ -158,6 +181,8 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
VSAbstractProtocol protocol =
internalProcess.getProtocolObject(protocolClassname);
+ applyLongOverrides(protocol);
+
if (isClientProtocol)
protocol.isClient(isProtocolActivation);
else
@@ -215,7 +240,9 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
objectOutputStream.writeObject(Boolean.valueOf(isProtocolActivation));
/** For later backwards compatibility, to add more stuff */
- objectOutputStream.writeObject(Boolean.valueOf(false));
+ objectOutputStream.writeObject(longOverrides == null
+ ? Boolean.valueOf(false)
+ : new HashMap<String, Long>(longOverrides));
}
/* (non-Javadoc)
@@ -242,7 +269,17 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
this.setShortname(createShortname(null));
/** For later backwards compatibility, to add more stuff */
- objectInputStream.readObject();
+ Object overrides = objectInputStream.readObject();
+ if (overrides instanceof Map<?, ?> map) {
+ longOverrides = new HashMap<String, Long>();
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ if (entry.getKey() instanceof String
+ && entry.getValue() instanceof Long) {
+ longOverrides.put((String) entry.getKey(),
+ (Long) entry.getValue());
+ }
+ }
+ }
}
protected String createShortname(String savedShortname) {
@@ -266,4 +303,14 @@ public class VSProtocolEvent extends VSAbstractInternalEvent
prefs.getString("lang.deactivated");
return protocolShortname + " " + clientServer + " " + activateDeactivate;
}
+
+ private void applyLongOverrides(VSAbstractProtocol protocol) {
+ if (longOverrides == null || longOverrides.isEmpty()) {
+ return;
+ }
+
+ for (Map.Entry<String, Long> entry : longOverrides.entrySet()) {
+ protocol.setLong(entry.getKey(), entry.getValue().longValue());
+ }
+ }
}
diff --git a/src/main/java/events/internal/VSProtocolScheduleEvent.java b/src/main/java/events/internal/VSProtocolScheduleEvent.java
index c940212..e01b3da 100644
--- a/src/main/java/events/internal/VSProtocolScheduleEvent.java
+++ b/src/main/java/events/internal/VSProtocolScheduleEvent.java
@@ -3,7 +3,12 @@ package events.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import core.VSAbstractProcess;
+import core.VSInternalProcess;
+import events.VSRegisteredEvents;
import protocols.VSAbstractProtocol;
import serialize.VSNotSerializable;
import serialize.VSSerialize;
@@ -24,6 +29,12 @@ public class VSProtocolScheduleEvent extends VSAbstractInternalEvent
private VSAbstractProtocol protocol;
/**
+ * Create a VSProtocolScheduleEvent object for deserialization.
+ */
+ public VSProtocolScheduleEvent() {
+ }
+
+ /**
* Create a VSProtocolScheduleEvent object
*
* @param protocol the protocol
@@ -41,6 +52,7 @@ public class VSProtocolScheduleEvent extends VSAbstractInternalEvent
*/
public void onInit() {
setClassname(getClass().toString());
+ setShortname(createShortname(null));
}
/**
@@ -85,6 +97,14 @@ public class VSProtocolScheduleEvent extends VSAbstractInternalEvent
* @see events.VSAbstractEvent#onStart()
*/
public void onStart() {
+ if (protocol == null) {
+ protocol = resolveProtocolFromProcess();
+ }
+
+ if (protocol == null) {
+ return;
+ }
+
if (isServerSchedule)
protocol.onServerScheduleStart();
else
@@ -122,5 +142,82 @@ public class VSProtocolScheduleEvent extends VSAbstractInternalEvent
/** For later backwards compatibility, to add more stuff */
objectInputStream.readObject();
+ /** For later backwards compatibility, to add more stuff */
+ objectInputStream.readObject();
+
+ }
+
+ protected String createShortname(String savedShortname) {
+ if (prefs == null) {
+ return savedShortname != null
+ ? savedShortname
+ : "Protocol Schedule";
+ }
+
+ if (protocol == null || protocol.getClassname() == null) {
+ return prefs.getString("lang.events.internal.VSProtocolScheduleEvent.short");
+ }
+
+ String protocolShortname =
+ VSRegisteredEvents.getShortnameByClassname(protocol.getClassname());
+ if (protocolShortname == null)
+ protocolShortname = protocol.getClassname();
+
+ return protocolShortname + " "
+ + (isServerSchedule
+ ? prefs.getString("lang.server")
+ : prefs.getString("lang.client"))
+ + " "
+ + prefs.getString("lang.events.internal.VSProtocolScheduleEvent.short");
+ }
+
+ @SuppressWarnings("unchecked")
+ private VSAbstractProtocol resolveProtocolFromProcess() {
+ if (!(process instanceof VSInternalProcess internalProcess)) {
+ return null;
+ }
+
+ try {
+ VSAbstractProtocol raftProtocol =
+ internalProcess.getProtocolObject(
+ "protocols.implementations.VSRaftProtocol");
+ if (raftProtocol != null) {
+ return raftProtocol;
+ }
+
+ Field field = VSAbstractProcess.class.getDeclaredField("protocolsToReset");
+ field.setAccessible(true);
+
+ ArrayList<VSAbstractProtocol> protocols =
+ (ArrayList<VSAbstractProtocol>) field.get(internalProcess);
+ if (protocols == null || protocols.isEmpty()) {
+ return null;
+ }
+
+ VSAbstractProtocol activeProtocol = null;
+ for (VSAbstractProtocol candidate : protocols) {
+ if (candidate == null) {
+ continue;
+ }
+
+ if ("protocols.implementations.VSRaftProtocol".equals(
+ candidate.getClassname())) {
+ return candidate;
+ }
+
+ if (activeProtocol == null &&
+ (candidate.isServer() || candidate.isClient())) {
+ activeProtocol = candidate;
+ }
+ }
+
+ if (activeProtocol != null) {
+ return activeProtocol;
+ }
+
+ return protocols.get(0);
+ } catch (ReflectiveOperationException e) {
+ return null;
+ }
}
}