Skip to content

Commit 185dfbb

Browse files
feat(events): make event serialization usable from another package (#214)
## What Widens five declarations in `com.launchdarkly.sdk.internal.events` from package-private to public. **Visibility only — no behavior change.** | Declaration | What becomes public | | --- | --- | | `EventOutputFormatter` | class, constructor, `writeOutputEvents` | | `EventSummarizerInterface` | interface | | `AggregatedEventSummarizer` | class, constructor | | `PerContextEventSummarizer` | class, constructor | | `EventSummarizer` | class only — so that `EventSummary` can be named | | `EventSummarizer.EventSummary` | class only | Everything else stays package-private. `EventSummarizer` and `EventSummary` gain no callable surface: `EventSummarizer`'s constructors and methods are untouched, and `EventSummary` cannot be constructed from outside the package. They are public so the type `List<EventSummarizer.EventSummary>` can be *named* by a caller passing it from a summarizer to the formatter. ## Why The Android SDK's event durability work summarizes and serializes each event on the thread that recorded it, ahead of the bounded queue that `DefaultEventProcessor` keeps between the caller and the summarizer. That means it needs the summarizers and the output formatter directly: `DefaultEventProcessor` only accepts individual events and summarizes them itself, so there is no public way to hand java-sdk-internal a summary that has already been aggregated. Today the Android SDK gets at them by declaring `AndroidEventBuffer` in this package — a split package across two artifacts, with a javadoc workaround to keep it out of the published docs. That works, but it is not something to keep: it is fragile under any build that takes package ownership seriously, and it puts a class the Android team maintains inside a package this repo owns. With these declarations public, that class moves into `com.launchdarkly.sdk.android` where it belongs, and the split package and its build workaround go away. The important part is that the Android SDK keeps using *this* implementation of the wire format rather than growing a second copy that could drift from it. ## Notes for review - The diff is modifiers only, apart from one added line of javadoc on `EventSummary`, which `JavadocType` requires because it is a newly public type. No existing comment was edited. - `javadoc` reports three new `no comment` warnings, on the two constructors and `writeOutputEvents`. That is the same warning roughly eighty existing members in this module already produce, and it does not fail the build. - `Event`, `EventsConfiguration` and `Sampler` were already public and needed no change. - `compileJava`, `checkstyleMain`, `javadoc` and the `com.launchdarkly.sdk.internal.events.*` tests all pass. 🤖 Generated with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 85d1f7d commit 185dfbb

5 files changed

Lines changed: 23 additions & 10 deletions

File tree

‎lib/shared/internal/src/main/java/com/launchdarkly/sdk/internal/events/AggregatedEventSummarizer.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
* Note that the methods of this class are deliberately not thread-safe, because they should
1717
* always be called from EventProcessor's single message-processing thread.
1818
*/
19-
final class AggregatedEventSummarizer implements EventSummarizerInterface {
19+
public final class AggregatedEventSummarizer implements EventSummarizerInterface {
2020
private final EventSummarizer summarizer;
2121

22-
AggregatedEventSummarizer() {
22+
public AggregatedEventSummarizer() {
2323
this.summarizer = new EventSummarizer();
2424
}
2525

‎lib/shared/internal/src/main/java/com/launchdarkly/sdk/internal/events/EventOutputFormatter.java‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,28 @@
2525
* handling of context data and private attribute redaction is implemented in EventContextFormatter
2626
* and tested in more detail in EventContextFormatterTest.
2727
*/
28-
final class EventOutputFormatter {
28+
public final class EventOutputFormatter {
2929
private final EventContextFormatter contextFormatter;
3030
private final boolean redactAnonymousAllEvents;
3131

32-
EventOutputFormatter(EventsConfiguration config) {
32+
public EventOutputFormatter(EventsConfiguration config) {
3333
this.contextFormatter = new EventContextFormatter(
3434
config.allAttributesPrivate,
3535
config.privateAttributes.toArray(new AttributeRef[config.privateAttributes.size()]));
3636
this.redactAnonymousAllEvents = config.redactAnonymousAllEvents;
3737
}
3838

39-
int writeOutputEvents(Event[] events, List<EventSummarizer.EventSummary> summaries, Writer writer) throws IOException {
39+
/**
40+
* Writes events and summaries as the JSON array that makes up a request body.
41+
*
42+
* @param events the individual events to write
43+
* @param summaries the summaries to write; empty ones are skipped
44+
* @param writer where to write the JSON
45+
* @return how many output events were written, counting each summary as one
46+
* @throws IOException if the writer failed
47+
*/
48+
public int writeOutputEvents(Event[] events, List<EventSummarizer.EventSummary> summaries, Writer writer)
49+
throws IOException {
4050
int count = 0;
4151
JsonWriter jsonWriter = new JsonWriter(writer);
4252
jsonWriter.beginArray();

‎lib/shared/internal/src/main/java/com/launchdarkly/sdk/internal/events/EventSummarizer.java‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* methods of this class are deliberately not thread-safe, because they should always
1515
* be called from EventProcessor's single message-processing thread.
1616
*/
17-
final class EventSummarizer {
17+
public final class EventSummarizer {
1818
private EventSummary eventsState;
1919
private final LDContext context; // nullable - only set for per-context summarization
2020

@@ -85,7 +85,10 @@ void clear() {
8585
eventsState = new EventSummary(context);
8686
}
8787

88-
static final class EventSummary {
88+
/**
89+
* A snapshot of the evaluations counted since the last reset.
90+
*/
91+
public static final class EventSummary {
8992
final Map<String, FlagInfo> counters;
9093
long startDate;
9194
long endDate;

‎lib/shared/internal/src/main/java/com/launchdarkly/sdk/internal/events/EventSummarizerInterface.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Note that implementations are deliberately not thread-safe, as they should always
1414
* be called from EventProcessor's single message-processing thread.
1515
*/
16-
interface EventSummarizerInterface {
16+
public interface EventSummarizerInterface {
1717
/**
1818
* Adds information about an evaluation to the summary.
1919
*

‎lib/shared/internal/src/main/java/com/launchdarkly/sdk/internal/events/PerContextEventSummarizer.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
* Note that the methods of this class are deliberately not thread-safe, because they should
2020
* always be called from EventProcessor's single message-processing thread.
2121
*/
22-
final class PerContextEventSummarizer implements EventSummarizerInterface {
22+
public final class PerContextEventSummarizer implements EventSummarizerInterface {
2323
private final Map<LDContext, EventSummarizer> summarizersByContext;
2424

25-
PerContextEventSummarizer() {
25+
public PerContextEventSummarizer() {
2626
this.summarizersByContext = new HashMap<>();
2727
}
2828

0 commit comments

Comments
 (0)