summaryrefslogtreecommitdiff
path: root/src/main/java/events/implementations/VSTimestampMonitorEvent.java
blob: c795fe932d0819ab1c004817ed607b3291e4ddf0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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";
    }
}