diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-20 17:18:45 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-20 17:18:45 +0300 |
| commit | 5e16f7f37c984d7ee1d1f0484cf0a8154bbb849d (patch) | |
| tree | b163049ab785dcfba3bc46cb159156e1c8566bf1 /src/main/java/events/implementations/VSTimestampMonitorEvent.java | |
| parent | 28beef18a728ec4c35e47378c514ad826c2f9a31 (diff) | |
Improve code quality: Replace instanceof with polymorphism and extract constants
Major improvements:
1. Replace instanceof checks with polymorphic methods in VSAbstractEvent hierarchy
- Added isInternalEvent(), isMessageReceiveEvent(), etc. methods
- Added getEventPriority() for clean event ordering
- Added shouldIncreaseTimestamps() to control timestamp behavior
- Refactored VSTask to use these polymorphic methods
2. Extract magic numbers and strings to constants
- Created VSConstants class for centralized configuration values
- Added event priority constants (PRIORITY_HIGHEST, PRIORITY_HIGH, etc.)
- Extracted string constants like CLASS_PREFIX
- Moved magic numbers to named constants (PERCENTAGE_RANGE, etc.)
3. Update tests to work with new polymorphic approach
- Fixed mocking in VSTaskTest to return correct values
- All 132 tests passing
These changes improve maintainability, reduce coupling, and make the codebase
more self-documenting. The polymorphic approach eliminates type checking and
makes it easier to add new event types.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'src/main/java/events/implementations/VSTimestampMonitorEvent.java')
| -rw-r--r-- | src/main/java/events/implementations/VSTimestampMonitorEvent.java | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/main/java/events/implementations/VSTimestampMonitorEvent.java b/src/main/java/events/implementations/VSTimestampMonitorEvent.java new file mode 100644 index 0000000..c795fe9 --- /dev/null +++ b/src/main/java/events/implementations/VSTimestampMonitorEvent.java @@ -0,0 +1,184 @@ +package events.implementations; + +import java.util.ArrayList; +import java.util.List; + +import core.VSInternalProcess; +import core.VSTask; +import events.VSAbstractEvent; +import events.VSCopyableEvent; + +/** + * A monitoring event that checks for Lamport timestamp conditions. + * Vector timestamp events should use VSVectorClockMonitor instead, + * as they need to be checked when vector clocks change, not on time intervals. + * + * This event reschedules itself to run periodically, monitoring only + * Lamport timestamp events for the process. + * + * @author Paul C. Buetow + */ +public class VSTimestampMonitorEvent extends VSAbstractEvent implements VSCopyableEvent { + + private List<VSTimestampTriggeredEvent> lamportEvents; + private long monitorInterval; + private boolean isActive; + + /** + * Constructor with default monitoring interval + */ + public VSTimestampMonitorEvent() { + this.lamportEvents = new ArrayList<>(); + this.monitorInterval = constants.VSConstants.DEFAULT_MONITOR_INTERVAL; + this.isActive = true; + } + + /** + * Constructor with custom monitoring interval + */ + public VSTimestampMonitorEvent(long interval) { + this.lamportEvents = new ArrayList<>(); + this.monitorInterval = interval; + this.isActive = true; + } + + @Override + public void onInit() { + setClassname(getClass().getName()); + } + + @Override + public void onStart() { + if (!isActive) { + return; + } + + VSInternalProcess internalProcess = (VSInternalProcess) process; + + // Check only Lamport timestamp events (vector events are handled separately) + List<VSTimestampTriggeredEvent> triggeredEvents = new ArrayList<>(); + + for (VSTimestampTriggeredEvent event : lamportEvents) { + if (!event.hasTriggered() && + event.getTimestampType() == VSTimestampTriggeredEvent.TimestampType.LAMPORT) { + + // Initialize the event if needed + if (event.getProcess() == null) { + event.init(internalProcess); + } + + // Check if condition is met + if (event.checkCondition(internalProcess)) { + event.onStart(); // This will trigger the event + triggeredEvents.add(event); + } + } + } + + // Remove triggered events from monitoring list + lamportEvents.removeAll(triggeredEvents); + + // Reschedule this monitor if there are still events to monitor + if (!lamportEvents.isEmpty()) { + rescheduleMonitor(); + } + } + + /** + * Add a Lamport timestamp event to monitor + */ + public void addLamportEvent(VSTimestampTriggeredEvent event) { + if (event.getTimestampType() == VSTimestampTriggeredEvent.TimestampType.LAMPORT && + !lamportEvents.contains(event)) { + lamportEvents.add(event); + + // If this is the first event, start monitoring + if (lamportEvents.size() == 1 && process != null) { + rescheduleMonitor(); + } + } + } + + /** + * Remove a Lamport timestamp event from monitoring + */ + public void removeLamportEvent(VSTimestampTriggeredEvent event) { + lamportEvents.remove(event); + } + + /** + * Schedule the next monitoring check + */ + private void rescheduleMonitor() { + if (process instanceof VSInternalProcess) { + VSInternalProcess internalProcess = (VSInternalProcess) process; + + // Create a new monitor task for the next interval + VSTimestampMonitorEvent nextMonitor = new VSTimestampMonitorEvent(monitorInterval); + nextMonitor.lamportEvents = new ArrayList<>(this.lamportEvents); + nextMonitor.isActive = this.isActive; + + // Schedule as local timed task + long nextTime = internalProcess.getTime() + monitorInterval; + VSTask monitorTask = new VSTask(nextTime, internalProcess, nextMonitor, VSTask.LOCAL); + + internalProcess.getSimulatorCanvas().getTaskManager().addTask(monitorTask); + } + } + + /** + * Stop monitoring + */ + public void stopMonitoring() { + isActive = false; + lamportEvents.clear(); + } + + /** + * Get count of Lamport events being monitored + */ + public int getLamportEventCount() { + return lamportEvents.size(); + } + + /** + * Check if monitoring is active + */ + public boolean isActive() { + return isActive && !lamportEvents.isEmpty(); + } + + @Override + public void initCopy(VSAbstractEvent copy) { + if (copy instanceof VSTimestampMonitorEvent) { + VSTimestampMonitorEvent copyEvent = (VSTimestampMonitorEvent) copy; + copyEvent.monitorInterval = this.monitorInterval; + copyEvent.isActive = this.isActive; + copyEvent.lamportEvents = new ArrayList<>(this.lamportEvents); + } + } + + @Override + public String toString() { + return String.format(" [LamportMonitor: %d events, interval=%d]", + lamportEvents.size(), monitorInterval); + } + + // Getters and setters + public long getMonitorInterval() { + return monitorInterval; + } + + public void setMonitorInterval(long interval) { + this.monitorInterval = interval; + } + + public List<VSTimestampTriggeredEvent> getLamportEvents() { + return new ArrayList<>(lamportEvents); + } + + @Override + protected String createShortname(String savedShortname) { + return "TimestampMonitor"; + } +}
\ No newline at end of file |
