Skip to content

Commit 06814f3

Browse files
committed
Made new features thread safe
1 parent 6077a6c commit 06814f3

File tree

5 files changed

+100
-28
lines changed

5 files changed

+100
-28
lines changed

src/main/java/software/amazon/cloudwatchlogs/emf/logger/MetricsLogger.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ public MetricsLogger putMetric(String key, double value, AggregationType aggrega
359359
* @throws InvalidMetricException if the metric is invalid
360360
*/
361361
public MetricsLogger setMetric(String key, Metric value) throws InvalidMetricException {
362+
rwl.readLock().lock();
362363
try {
363364
this.context.setMetric(key, value);
364365
return this;

src/main/java/software/amazon/cloudwatchlogs/emf/model/HistogramMetric.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.LinkedList;
2020
import java.util.List;
2121
import java.util.Queue;
22+
2223
import software.amazon.cloudwatchlogs.emf.Constants;
2324
import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException;
2425

@@ -95,22 +96,37 @@ public HistogramMetricBuilder() {
9596

9697
@Override
9798
public Histogram getValues() {
98-
return values.reduce();
99+
rwl.readLock().lock();
100+
try {
101+
return values.reduce();
102+
} finally {
103+
rwl.readLock().unlock();
104+
}
99105
}
100106

101107
@Override
102108
public HistogramMetricBuilder addValue(double value) {
103-
this.values.addValue(value);
104-
return this;
109+
rwl.readLock().lock();
110+
try {
111+
values.addValue(value);
112+
return this;
113+
} finally {
114+
rwl.readLock().unlock();
115+
}
105116
}
106117

107118
@Override
108119
public HistogramMetric build() {
109-
values.reduce();
110-
if (name == null) {
111-
return new HistogramMetric(unit, storageResolution, values);
120+
rwl.writeLock().lock();
121+
try {
122+
values.reduce();
123+
if (name == null) {
124+
return new HistogramMetric(unit, storageResolution, values);
125+
}
126+
return new HistogramMetric(name, unit, storageResolution, values);
127+
} finally {
128+
rwl.writeLock().unlock();
112129
}
113-
return new HistogramMetric(name, unit, storageResolution, values);
114130
}
115131
}
116132
}

src/main/java/software/amazon/cloudwatchlogs/emf/model/Metric.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
2323
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2424
import java.util.Queue;
25+
import java.util.concurrent.locks.ReentrantReadWriteLock;
2526
import lombok.AccessLevel;
2627
import lombok.Getter;
2728
import lombok.NonNull;
@@ -78,6 +79,14 @@ protected Object getFormattedValues() {
7879

7980
public abstract static class MetricBuilder<V, T extends MetricBuilder<V, T>> extends Metric<V> {
8081

82+
/**
83+
* This lock is used to create an internal sync context for build() method in multi-threaded
84+
* situations. build() acquires write lock, other methods (accessing mutable shared data))
85+
* acquires read lock. This makes sure build() is executed exclusively, while other methods
86+
* can be executed concurrently.
87+
*/
88+
@JsonIgnore final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
89+
8190
protected abstract T getThis();
8291

8392
/**
@@ -95,18 +104,33 @@ public abstract static class MetricBuilder<V, T extends MetricBuilder<V, T>> ext
95104
abstract Metric<V> build();
96105

97106
protected T name(@NonNull String name) {
98-
this.name = name;
99-
return getThis();
107+
rwl.readLock().lock();
108+
try {
109+
this.name = name;
110+
return getThis();
111+
} finally {
112+
rwl.readLock().unlock();
113+
}
100114
}
101115

102116
public T unit(Unit unit) {
103-
this.unit = unit;
104-
return getThis();
117+
rwl.readLock().lock();
118+
try {
119+
this.unit = unit;
120+
return getThis();
121+
} finally {
122+
rwl.readLock().unlock();
123+
}
105124
}
106125

107126
public T storageResolution(StorageResolution storageResolution) {
108-
this.storageResolution = storageResolution;
109-
return getThis();
127+
rwl.readLock().lock();
128+
try {
129+
this.storageResolution = storageResolution;
130+
return getThis();
131+
} finally {
132+
rwl.readLock().unlock();
133+
}
110134
}
111135

112136
@Override

src/main/java/software/amazon/cloudwatchlogs/emf/model/MetricDefinition.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,36 @@ public MetricDefinitionBuilder() {
118118

119119
@Override
120120
public MetricDefinitionBuilder addValue(double value) {
121-
this.values.add(value);
122-
return this;
121+
rwl.readLock().lock();
122+
try {
123+
this.values.add(value);
124+
return this;
125+
} finally {
126+
rwl.readLock().unlock();
127+
}
123128
}
124129

125130
public MetricDefinitionBuilder values(@NonNull List<Double> values) {
126-
this.values = values;
127-
return this;
131+
rwl.readLock().lock();
132+
try {
133+
this.values = values;
134+
return this;
135+
} finally {
136+
rwl.readLock().unlock();
137+
}
128138
}
129139

130140
@Override
131141
public MetricDefinition build() {
132-
if (name == null) {
133-
return new MetricDefinition(unit, storageResolution, values);
142+
rwl.writeLock().lock();
143+
try {
144+
if (name == null) {
145+
return new MetricDefinition(unit, storageResolution, values);
146+
}
147+
return new MetricDefinition(name, unit, storageResolution, values);
148+
} finally {
149+
rwl.writeLock().unlock();
134150
}
135-
return new MetricDefinition(name, unit, storageResolution, values);
136151
}
137152
}
138153
}

src/main/java/software/amazon/cloudwatchlogs/emf/model/StatisticSet.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.LinkedList;
2020
import java.util.Queue;
21+
2122
import lombok.NonNull;
2223
import software.amazon.cloudwatchlogs.emf.exception.InvalidMetricException;
2324

@@ -89,21 +90,36 @@ public StatisticSetBuilder() {
8990

9091
@Override
9192
public StatisticSetBuilder addValue(double value) {
92-
this.values.addValue(value);
93-
return this;
93+
rwl.readLock().lock();
94+
try {
95+
this.values.addValue(value);
96+
return this;
97+
} finally {
98+
rwl.readLock().unlock();
99+
}
94100
}
95101

96-
public StatisticSetBuilder values(@NonNull Statistics values) {
97-
this.values = values;
98-
return this;
102+
StatisticSetBuilder values(@NonNull Statistics values) {
103+
rwl.readLock().lock();
104+
try {
105+
this.values = values;
106+
return this;
107+
} finally {
108+
rwl.readLock().unlock();
109+
}
99110
}
100111

101112
@Override
102113
public StatisticSet build() {
103-
if (name == null) {
104-
return new StatisticSet(unit, storageResolution, values);
114+
rwl.writeLock().lock();
115+
try {
116+
if (name == null) {
117+
return new StatisticSet(unit, storageResolution, values);
118+
}
119+
return new StatisticSet(name, unit, storageResolution, values);
120+
} finally {
121+
rwl.writeLock().unlock();
105122
}
106-
return new StatisticSet(name, unit, storageResolution, values);
107123
}
108124
}
109125
}

0 commit comments

Comments
 (0)