From f55d67d98dddf5861dc4266564863dde4b0b6ed1 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 27 Mar 2026 13:05:59 +0200 Subject: sr: retune Raft replay for faster reelection --- src/main/java/events/internal/VSProtocolEvent.java | 51 +++++++++++- .../events/internal/VSProtocolScheduleEvent.java | 97 ++++++++++++++++++++++ 2 files changed, 146 insertions(+), 2 deletions(-) (limited to 'src/main/java/events/internal') 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 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(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(); + } + + 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(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(); + 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 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; @@ -23,6 +28,12 @@ public class VSProtocolScheduleEvent extends VSAbstractInternalEvent /** The reference to the protocol object to schedule. */ private VSAbstractProtocol protocol; + /** + * Create a VSProtocolScheduleEvent object for deserialization. + */ + public VSProtocolScheduleEvent() { + } + /** * Create a VSProtocolScheduleEvent object * @@ -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 protocols = + (ArrayList) 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; + } } } -- cgit v1.2.3