Skip to content

Commit 5449cd4

Browse files
Merge pull request #122 from bugsnag/fix-session-counts
[PLAT-2139] Ensure session counts are reported thread safe
2 parents 5e294cf + 3cfe6b6 commit 5449cd4

4 files changed

Lines changed: 56 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Changelog
22

3-
## 3.4.2 (2018-11-28)
3+
## 3.4.2 (2018-11-29)
44

5+
* Ensure session counts are thread safe
6+
[#122](https://github.com/bugsnag/bugsnag-java/pull/122)
7+
58
* Prevent application hangs due to session flushing
69
[#121](https://github.com/bugsnag/bugsnag-java/pull/121)
710

bugsnag/src/main/java/com/bugsnag/Report.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class Report {
2323
private String groupingHash;
2424
private Diagnostics diagnostics;
2525
private boolean shouldCancel = false;
26-
private Session session;
26+
private Map<String, Object> sessionMap;
2727
private final List<ThreadState> threadStates;
2828

2929
/**
@@ -131,23 +131,22 @@ public Map<String, Object> getMetaData() {
131131

132132
@Expose
133133
Map<String, Object> getSession() {
134-
if (session == null) {
135-
return null;
136-
}
137-
138-
Map<String, Object> map = new HashMap<String, Object>();
139-
map.put("id", session.getId());
140-
map.put("startedAt", session.getStartedAt());
141-
142-
Map<String, Object> handledCounts = new HashMap<String, Object>();
143-
handledCounts.put("handled", session.getHandledCount());
144-
handledCounts.put("unhandled", session.getUnhandledCount());
145-
map.put("events", handledCounts);
146-
return map;
134+
return sessionMap;
147135
}
148136

149137
void setSession(Session session) {
150-
this.session = session;
138+
if (session == null) {
139+
sessionMap = null;
140+
} else {
141+
sessionMap = new HashMap<String, Object>();
142+
sessionMap.put("id", session.getId());
143+
sessionMap.put("startedAt", session.getStartedAt());
144+
145+
Map<String, Object> handledCounts = new HashMap<String, Object>();
146+
handledCounts.put("handled", session.getHandledCount());
147+
handledCounts.put("unhandled", session.getUnhandledCount());
148+
sessionMap.put("events", handledCounts);
149+
}
151150
}
152151

153152
/**

bugsnag/src/test/java/com/bugsnag/BugsnagTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,29 @@ public void close() {
510510
assertTrue(bugsnag.notify(new Throwable()));
511511
}
512512

513+
@Test
514+
public void testMultipleHandledIncrementWithSession() {
515+
bugsnag.startSession();
516+
StubNotificationDelivery testDelivery = new StubNotificationDelivery();
517+
bugsnag.setDelivery(testDelivery);
518+
519+
assertTrue(bugsnag.notify(new Throwable()));
520+
assertTrue(bugsnag.notify(new Throwable()));
521+
assertTrue(bugsnag.notify(new Throwable()));
522+
523+
for (int i = 0 ; i < testDelivery.getNotifications().size(); i++) {
524+
Report report = testDelivery.getNotifications().get(i).getEvents().get(0);
525+
526+
Map<String, Object> session = report.getSession();
527+
assertNotNull(session);
528+
529+
@SuppressWarnings("unchecked")
530+
Map<String, Object> handledCounts = (Map<String, Object>) session.get("events");
531+
assertEquals(i + 1, handledCounts.get("handled"));
532+
assertEquals(0, handledCounts.get("unhandled"));
533+
}
534+
}
535+
513536
@Test
514537
public void testSerialization() {
515538
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

bugsnag/src/test/java/com/bugsnag/NotificationTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.junit.Assert.assertNotNull;
66
import static org.junit.Assert.assertNull;
77

8+
import com.fasterxml.jackson.annotation.JsonInclude;
89
import com.fasterxml.jackson.databind.JsonNode;
910
import com.fasterxml.jackson.databind.ObjectMapper;
1011
import org.junit.Before;
@@ -31,6 +32,9 @@ public void setUp() {
3132
config.appVersion = "1.2.3";
3233
config.releaseStage = "dev";
3334
report = new Report(config, new RuntimeException());
35+
36+
// Only include properties with non-null values
37+
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
3438
}
3539

3640
private JsonNode generateJson(ObjectMapper mapper,
@@ -67,6 +71,17 @@ public void testWithoutSessionSerialisation() throws Throwable {
6771
assertNull(rootNode.get("events").get("session"));
6872
}
6973

74+
@Test
75+
public void testNullSession() throws Throwable {
76+
report.setSession(null);
77+
78+
JsonNode rootNode = generateJson(mapper, config, report);
79+
validateErrorReport(rootNode);
80+
81+
JsonNode session = rootNode.get("events").get(0).get("session");
82+
assertNull(session);
83+
}
84+
7085
private void validateErrorReport(JsonNode rootNode) {
7186
assertNotNull(rootNode);
7287
assertNotNull(rootNode.get("apiKey").asText());

0 commit comments

Comments
 (0)