Skip to content

Commit

Permalink
Merge pull request #2816 from SCADA-LTS/fix/#2628_Fixed_ConcurrentMod…
Browse files Browse the repository at this point in the history
…ificationException_in_MonitoredValues

#2628 Fixed ConcurrentModificationException in MonitoredValues:
  • Loading branch information
Limraj authored Feb 15, 2024
2 parents 9e4f44d + 087f722 commit adc2bd8
Show file tree
Hide file tree
Showing 16 changed files with 430 additions and 58 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -204,5 +204,6 @@ test {
includeTestsMatching "com.serotonin.mango.rt.maint.work.CreateWorkItemToStringTest"
includeTestsMatching "com.serotonin.util.SerializationHelperTest"
includeTestsMatching "org.scada_lts.web.mvc.api.json.WorkItemInfoListTest"
includeTestsMatching "org.scada_lts.monitor.ConcurrentMonitoredValuesTest"
}
}
5 changes: 3 additions & 2 deletions src/com/serotonin/mango/Common.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import javax.servlet.http.HttpServletRequest;

import com.serotonin.mango.web.mvc.controller.ScadaLocaleUtils;
import org.scada_lts.monitor.IMonitoredValues;
import gnu.io.CommPortIdentifier;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
Expand All @@ -52,7 +53,7 @@
import com.serotonin.mango.vo.CommPortProxy;
import com.serotonin.mango.vo.User;
import com.serotonin.mango.web.ContextWrapper;
import com.serotonin.monitor.MonitoredValues;
import org.scada_lts.monitor.ConcurrentMonitoredValues;
import com.serotonin.timer.CronTimerTrigger;
import com.serotonin.timer.RealTimeTimer;
import com.serotonin.util.PropertiesUtils;
Expand All @@ -76,7 +77,7 @@ public class Common {
// This is initialized
public static final RealTimeTimer timer = new RealTimeTimer();

public static final MonitoredValues MONITORED_VALUES = new MonitoredValues();
public static final IMonitoredValues MONITORED_VALUES = new ConcurrentMonitoredValues();

private static String environmentProfileName = "env";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import com.serotonin.mango.rt.dataSource.PollingDataSource;
import com.serotonin.mango.vo.dataSource.internal.InternalDataSourceVO;
import com.serotonin.mango.vo.dataSource.internal.InternalPointLocatorVO;
import com.serotonin.monitor.IntegerMonitor;
import org.scada_lts.monitor.type.IntegerMonitor;

/**
* @author Matthew Lohbihler
Expand Down
2 changes: 1 addition & 1 deletion src/com/serotonin/mango/rt/maint/WorkItemMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.concurrent.ThreadPoolExecutor;

import com.serotonin.mango.Common;
import com.serotonin.monitor.IntegerMonitor;
import com.serotonin.timer.FixedRateTrigger;
import com.serotonin.timer.TimerTask;
import org.scada_lts.monitor.type.IntegerMonitor;

public class WorkItemMonitor extends TimerTask {
private static final long TIMEOUT = 1000 * 10; // Run every ten seconds.
Expand Down
2 changes: 1 addition & 1 deletion src/org/scada_lts/mango/service/PointValueService.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.scada_lts.dao.pointvalues.PointValueDAO;
import org.scada_lts.mango.adapter.MangoPointValues;
import org.scada_lts.mango.adapter.MangoPointValuesWithChangeOwner;
import org.scada_lts.monitor.type.IntegerMonitor;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
Expand All @@ -62,7 +63,6 @@
import com.serotonin.mango.rt.maint.work.WorkItem;
import com.serotonin.mango.vo.AnonymousUser;
import com.serotonin.mango.vo.bean.LongPair;
import com.serotonin.monitor.IntegerMonitor;
import com.serotonin.util.queue.ObjectQueue;

import static com.serotonin.mango.util.LoggingScriptUtils.infoErrorExecutionScript;
Expand Down
26 changes: 26 additions & 0 deletions src/org/scada_lts/monitor/ConcurrentMonitoredValues.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.scada_lts.monitor;

import org.scada_lts.monitor.type.ValueMonitor;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentMonitoredValues implements IMonitoredValues {
private final Map<String, ValueMonitor<?>> monitors = new ConcurrentHashMap<>();

@Override
public <T> ValueMonitor<T> addIfMissingStatMonitor(ValueMonitor<T> monitor) {
monitors.put(monitor.getId(), monitor);
return monitor;
}

@Override
public ValueMonitor<?> getValueMonitor(String id) {
return monitors.get(id);
}
}
8 changes: 8 additions & 0 deletions src/org/scada_lts/monitor/IMonitoredValues.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.scada_lts.monitor;

import org.scada_lts.monitor.type.ValueMonitor;

public interface IMonitoredValues {
<T> ValueMonitor<T> addIfMissingStatMonitor(ValueMonitor<T> monitor);
ValueMonitor<?> getValueMonitor(String id);
}
33 changes: 33 additions & 0 deletions src/org/scada_lts/monitor/type/DoubleMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.scada_lts.monitor.type;

public class DoubleMonitor extends ValueMonitor<Double> {
private double value;

public DoubleMonitor(String id, String name) {
this(id, name, 0.0);
}

public DoubleMonitor(String id, String name, double initialValue) {
super(id, name);
this.value = initialValue;
}

public Double getValue() {
return this.value;
}

public void setValue(double value) {
this.value = value;
}

public void addValue(double value) {
this.value += value;
}

public void setValueIfGreater(double value) {
if (this.value < value) {
this.value = value;
}

}
}
33 changes: 33 additions & 0 deletions src/org/scada_lts/monitor/type/FloatMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.scada_lts.monitor.type;

public class FloatMonitor extends ValueMonitor<Float> {
private float value;

public FloatMonitor(String id, String name) {
this(id, name, 0.0F);
}

public FloatMonitor(String id, String name, float initialValue) {
super(id, name);
this.value = initialValue;
}

public Float getValue() {
return this.value;
}

public void setValue(float value) {
this.value = value;
}

public void addValue(float value) {
this.value += value;
}

public void setValueIfGreater(float value) {
if (this.value < value) {
this.value = value;
}

}
}
33 changes: 33 additions & 0 deletions src/org/scada_lts/monitor/type/IntegerMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.scada_lts.monitor.type;

public class IntegerMonitor extends ValueMonitor<Integer> {
protected int value;

public IntegerMonitor(String id, String name) {
this(id, name, 0);
}

public IntegerMonitor(String id, String name, int initialValue) {
super(id, name);
this.value = initialValue;
}

public Integer getValue() {
return this.value;
}

public void setValue(int value) {
this.value = value;
}

public void addValue(int value) {
this.value += value;
}

public void setValueIfGreater(int value) {
if (this.value < value) {
this.value = value;
}

}
}
33 changes: 33 additions & 0 deletions src/org/scada_lts/monitor/type/LongMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.scada_lts.monitor.type;

public class LongMonitor extends ValueMonitor<Long> {
private long value;

public LongMonitor(String id, String name) {
this(id, name, 0L);
}

public LongMonitor(String id, String name, long initialValue) {
super(id, name);
this.value = initialValue;
}

public Long getValue() {
return this.value;
}

public void setValue(long value) {
this.value = value;
}

public void addValue(long value) {
this.value += value;
}

public void setValueIfGreater(long value) {
if (this.value < value) {
this.value = value;
}

}
}
26 changes: 26 additions & 0 deletions src/org/scada_lts/monitor/type/ObjectMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.scada_lts.monitor.type;

public class ObjectMonitor<T> extends ValueMonitor<T> {
private T value;

public ObjectMonitor(String id, String name) {
this(id, name, null);
}

public ObjectMonitor(String id, String name, T initialValue) {
super(id, name);
this.value = initialValue;
}

public T getValue() {
return this.value;
}

public void setValue(T value) {
this.value = value;
}

public String stringValue() {
return this.value == null ? null : this.value.toString();
}
}
25 changes: 25 additions & 0 deletions src/org/scada_lts/monitor/type/ValueMonitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.scada_lts.monitor.type;


public abstract class ValueMonitor<T> {
private static final long serialVersionUID = 3992668527962817285L;
private final String id;
private final String name;

public ValueMonitor(String id, String name) {
this.id = id;
this.name = name;
}

public String getId() {
return this.id;
}

public String getName() {
return this.name;
}

public T getValue() {
throw new UnsupportedOperationException();
}
}
20 changes: 20 additions & 0 deletions test/org/scada_lts/monitor/ConcurrentMonitoredValuesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.scada_lts.monitor;

import org.junit.Test;
import org.scada_lts.monitor.type.ObjectMonitor;
import utils.TestConcurrentUtils;


public class ConcurrentMonitoredValuesTest {

@Test
public void when_addIfMissingStatMonitor_in_ConcurrentMonitoredValues_then_non_exception() throws Throwable {
//given:
IMonitoredValues concurrentMonitoredValues = new ConcurrentMonitoredValues();

//when
TestConcurrentUtils.functionCheck(16, concurrentMonitoredValues::addIfMissingStatMonitor,
new ObjectMonitor<>("id", "name"));
}

}
Loading

0 comments on commit adc2bd8

Please sign in to comment.