[
https://issues.apache.org/jira/browse/JAMES-4197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
René Cordier updated JAMES-4197:
--------------------------------
Attachment: flamegraph-event-serializers-aggregator.png
Description:
EventSerializersAggregator relies on exceptions in rder to detect faulty json
and pick the right deserializer.
A certain amount of the CPU is being used just filling stack traces exceptions
because of this.
!flamegraph-event-serializers-aggregator.png!
There could be two approaches here:
* simple approach: the event serializer interface methods could return
Optional, so that we don't hit exceptions anymore in the aggregator serializer
for example:
{code:java}
public interface EventSerializer {
Optional<String> toJson(Event event);
Optional<String> toJson(Collection<Event> event);
default Optional<byte[]> toJsonBytes(Event event) {
return toJson(event).getBytes(StandardCharsets.UTF_8);
}
default Optional<byte[]> toJsonBytes(Collection<Event> event) {
return toJson(event).getBytes(StandardCharsets.UTF_8);
}
Optional<Event> asEvent(String serialized);
Optional<List<Event>> asEvents(String serialized);
default Optional<Event> fromBytes(byte[] serialized) {
return asEvent(new String(serialized, StandardCharsets.UTF_8));
}
default Optional<List<Event>> asEventsFromBytes(byte[] serialized) {
return asEvents(new String(serialized, StandardCharsets.UTF_8));
}
}
{code}
* more complex approach: eventbus could hint the desirializer to be used in the
EventBus message payload, the hint can be caried along in the deserializer and
help select the right thing without needing to fail a parsing
{code:java}
public interface EventSerializer {
record StringSerializationResult(String result, Optional<Class<? extends
EventSerializer>> serializer) {
public BytesSerializationResult asBytes() {
return new
BytesSerializationResult(result.getBytes(StandardCharsets.UTF_8), serializer);
}
}
record BytesSerializationResult(byte[] result, Optional<Class<? extends
EventSerializer>> serializer) {
}
StringSerializationResult toJson(Event event);
StringSerializationResult toJson(Collection<Event> event);
default BytesSerializationResult toJsonBytes(Event event) {
return toJson(event).asBytes();
}
default BytesSerializationResult toJsonBytes(Collection<Event> event) {
return toJson(event).asBytes();
}
Event asEvent(String serialized, Optional<Class<? extends EventSerializer>>
serializerHint);
List<Event> asEvents(String serialized, Optional<Class<? extends
EventSerializer>> serializerHint);
default Event fromBytes(byte[] serialized, Optional<Class<? extends
EventSerializer>> serializerHint) {
return asEvent(new String(serialized, StandardCharsets.UTF_8),
serializerHint);
}
default List<Event> asEventsFromBytes(byte[] serialized, Optional<Class<?
extends EventSerializer>> serializerHint) {
return asEvents(new String(serialized, StandardCharsets.UTF_8),
serializerHint);
}
}
{code}
Let's give a shot to simple approach first and see if it's enough.
was:
EventSerializersAggregator relies on exceptions in rder to detect faulty json
and pick the right deserializer.
A certain amount of the CPU is being used just filling stack traces exceptions
because of this.
There could be two approaches here:
* simple approach: the event serializer interface methods could return
Optional, so that we don't hit exceptions anymore in the aggregator serializer
for example:
{code:java}
public interface EventSerializer {
Optional<String> toJson(Event event);
Optional<String> toJson(Collection<Event> event);
default Optional<byte[]> toJsonBytes(Event event) {
return toJson(event).getBytes(StandardCharsets.UTF_8);
}
default Optional<byte[]> toJsonBytes(Collection<Event> event) {
return toJson(event).getBytes(StandardCharsets.UTF_8);
}
Optional<Event> asEvent(String serialized);
Optional<List<Event>> asEvents(String serialized);
default Optional<Event> fromBytes(byte[] serialized) {
return asEvent(new String(serialized, StandardCharsets.UTF_8));
}
default Optional<List<Event>> asEventsFromBytes(byte[] serialized) {
return asEvents(new String(serialized, StandardCharsets.UTF_8));
}
}
{code}
* more complex approach: eventbus could hint the desirializer to be used in the
EventBus message payload, the hint can be caried along in the deserializer and
help select the right thing without needing to fail a parsing
{code:java}
public interface EventSerializer {
record StringSerializationResult(String result, Optional<Class<? extends
EventSerializer>> serializer) {
public BytesSerializationResult asBytes() {
return new
BytesSerializationResult(result.getBytes(StandardCharsets.UTF_8), serializer);
}
}
record BytesSerializationResult(byte[] result, Optional<Class<? extends
EventSerializer>> serializer) {
}
StringSerializationResult toJson(Event event);
StringSerializationResult toJson(Collection<Event> event);
default BytesSerializationResult toJsonBytes(Event event) {
return toJson(event).asBytes();
}
default BytesSerializationResult toJsonBytes(Collection<Event> event) {
return toJson(event).asBytes();
}
Event asEvent(String serialized, Optional<Class<? extends EventSerializer>>
serializerHint);
List<Event> asEvents(String serialized, Optional<Class<? extends
EventSerializer>> serializerHint);
default Event fromBytes(byte[] serialized, Optional<Class<? extends
EventSerializer>> serializerHint) {
return asEvent(new String(serialized, StandardCharsets.UTF_8),
serializerHint);
}
default List<Event> asEventsFromBytes(byte[] serialized, Optional<Class<?
extends EventSerializer>> serializerHint) {
return asEvents(new String(serialized, StandardCharsets.UTF_8),
serializerHint);
}
}
{code}
Let's give a shot to simple approach first and see if it's enough.
> EventSerializersAggregator refactoring
> --------------------------------------
>
> Key: JAMES-4197
> URL: https://issues.apache.org/jira/browse/JAMES-4197
> Project: James Server
> Issue Type: Improvement
> Reporter: René Cordier
> Priority: Major
> Attachments: flamegraph-event-serializers-aggregator.png
>
>
> EventSerializersAggregator relies on exceptions in rder to detect faulty json
> and pick the right deserializer.
> A certain amount of the CPU is being used just filling stack traces
> exceptions because of this.
> !flamegraph-event-serializers-aggregator.png!
> There could be two approaches here:
> * simple approach: the event serializer interface methods could return
> Optional, so that we don't hit exceptions anymore in the aggregator
> serializer for example:
> {code:java}
> public interface EventSerializer {
> Optional<String> toJson(Event event);
> Optional<String> toJson(Collection<Event> event);
> default Optional<byte[]> toJsonBytes(Event event) {
> return toJson(event).getBytes(StandardCharsets.UTF_8);
> }
> default Optional<byte[]> toJsonBytes(Collection<Event> event) {
> return toJson(event).getBytes(StandardCharsets.UTF_8);
> }
> Optional<Event> asEvent(String serialized);
> Optional<List<Event>> asEvents(String serialized);
> default Optional<Event> fromBytes(byte[] serialized) {
> return asEvent(new String(serialized, StandardCharsets.UTF_8));
> }
> default Optional<List<Event>> asEventsFromBytes(byte[] serialized) {
> return asEvents(new String(serialized, StandardCharsets.UTF_8));
> }
> }
> {code}
> * more complex approach: eventbus could hint the desirializer to be used in
> the EventBus message payload, the hint can be caried along in the
> deserializer and help select the right thing without needing to fail a parsing
> {code:java}
> public interface EventSerializer {
> record StringSerializationResult(String result, Optional<Class<? extends
> EventSerializer>> serializer) {
> public BytesSerializationResult asBytes() {
> return new
> BytesSerializationResult(result.getBytes(StandardCharsets.UTF_8), serializer);
> }
> }
> record BytesSerializationResult(byte[] result, Optional<Class<? extends
> EventSerializer>> serializer) {
> }
> StringSerializationResult toJson(Event event);
> StringSerializationResult toJson(Collection<Event> event);
> default BytesSerializationResult toJsonBytes(Event event) {
> return toJson(event).asBytes();
> }
> default BytesSerializationResult toJsonBytes(Collection<Event> event) {
> return toJson(event).asBytes();
> }
> Event asEvent(String serialized, Optional<Class<? extends
> EventSerializer>> serializerHint);
> List<Event> asEvents(String serialized, Optional<Class<? extends
> EventSerializer>> serializerHint);
> default Event fromBytes(byte[] serialized, Optional<Class<? extends
> EventSerializer>> serializerHint) {
> return asEvent(new String(serialized, StandardCharsets.UTF_8),
> serializerHint);
> }
> default List<Event> asEventsFromBytes(byte[] serialized, Optional<Class<?
> extends EventSerializer>> serializerHint) {
> return asEvents(new String(serialized, StandardCharsets.UTF_8),
> serializerHint);
> }
> }
> {code}
> Let's give a shot to simple approach first and see if it's enough.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]