Skip to content

Commit 873bf44

Browse files
committed
Made new features thread safe
1 parent 6077a6c commit 873bf44

File tree

5 files changed

+98
-28
lines changed

5 files changed

+98
-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: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,37 @@ public HistogramMetricBuilder() {
9595

9696
@Override
9797
public Histogram getValues() {
98-
return values.reduce();
98+
rwl.readLock().lock();
99+
try {
100+
return values.reduce();
101+
} finally {
102+
rwl.readLock().unlock();
103+
}
99104
}
100105

101106
@Override
102107
public HistogramMetricBuilder addValue(double value) {
103-
this.values.addValue(value);
104-
return this;
108+
rwl.readLock().lock();
109+
try {
110+
values.addValue(value);
111+
return this;
112+
} finally {
113+
rwl.readLock().unlock();
114+
}
105115
}
106116

107117
@Override
108118
public HistogramMetric build() {
109-
values.reduce();
110-
if (name == null) {
111-
return new HistogramMetric(unit, storageResolution, values);
119+
rwl.writeLock().lock();
120+
try {
121+
values.reduce();
122+
if (name == null) {
123+
return new HistogramMetric(unit, storageResolution, values);
124+
}
125+
return new HistogramMetric(name, unit, storageResolution, values);
126+
} finally {
127+
rwl.writeLock().unlock();
112128
}
113-
return new HistogramMetric(name, unit, storageResolution, values);
114129
}
115130
}
116131
}

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: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,36 @@ public StatisticSetBuilder() {
8989

9090
@Override
9191
public StatisticSetBuilder addValue(double value) {
92-
this.values.addValue(value);
93-
return this;
92+
rwl.readLock().lock();
93+
try {
94+
this.values.addValue(value);
95+
return this;
96+
} finally {
97+
rwl.readLock().unlock();
98+
}
9499
}
95100

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

101111
@Override
102112
public StatisticSet build() {
103-
if (name == null) {
104-
return new StatisticSet(unit, storageResolution, values);
113+
rwl.writeLock().lock();
114+
try {
115+
if (name == null) {
116+
return new StatisticSet(unit, storageResolution, values);
117+
}
118+
return new StatisticSet(name, unit, storageResolution, values);
119+
} finally {
120+
rwl.writeLock().unlock();
105121
}
106-
return new StatisticSet(name, unit, storageResolution, values);
107122
}
108123
}
109124
}

0 commit comments

Comments
 (0)