[ https://issues.apache.org/jira/browse/SCB-174?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16315867#comment-16315867 ]
ASF GitHub Bot commented on SCB-174: ------------------------------------ seanyinx closed pull request #105: SCB-174 add kryo serializer URL: https://github.com/apache/incubator-servicecomb-saga/pull/105 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/omega/omega-format/pom.xml b/omega/omega-format/pom.xml index a842cbb..f34f323 100644 --- a/omega/omega-format/pom.xml +++ b/omega/omega-format/pom.xml @@ -33,6 +33,10 @@ <groupId>org.apache.servicecomb.saga</groupId> <artifactId>omega-transaction</artifactId> </dependency> + <dependency> + <groupId>com.esotericsoftware</groupId> + <artifactId>kryo</artifactId> + </dependency> <dependency> <groupId>junit</groupId> diff --git a/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormat.java b/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormat.java new file mode 100644 index 0000000..f948963 --- /dev/null +++ b/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormat.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.saga.omega.format; + +import java.io.ByteArrayInputStream; + +import org.apache.servicecomb.saga.omega.transaction.OmegaException; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoException; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import com.esotericsoftware.kryo.pool.KryoFactory; +import com.esotericsoftware.kryo.pool.KryoPool; + +public class KryoMessageFormat implements MessageFormat { + + private static final int DEFAULT_BUFFER_SIZE = 4096; + + private static final KryoFactory factory = Kryo::new; + + private static final KryoPool pool = new KryoPool.Builder(factory).softReferences().build(); + + @Override + public byte[] serialize(Object[] objects) { + Output output = new Output(DEFAULT_BUFFER_SIZE, -1); + + Kryo kryo = pool.borrow(); + kryo.writeObjectOrNull(output, objects, Object[].class); + pool.release(kryo); + + return output.toBytes(); + } + + @Override + public Object[] deserialize(byte[] message) { + try { + Input input = new Input(new ByteArrayInputStream(message)); + + Kryo kryo = pool.borrow(); + Object[] objects = kryo.readObjectOrNull(input, Object[].class); + pool.release(kryo); + + return objects; + } catch (KryoException e) { + throw new OmegaException("Unable to deserialize message", e); + } + } +} diff --git a/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormat.java b/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/MessageFormat.java similarity index 56% rename from omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormat.java rename to omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/MessageFormat.java index a486e1d..0ccac37 100644 --- a/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormat.java +++ b/omega/omega-format/src/main/java/org/apache/servicecomb/saga/omega/format/MessageFormat.java @@ -17,46 +17,18 @@ package org.apache.servicecomb.saga.omega.format; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import org.apache.servicecomb.saga.omega.transaction.TxEvent; import org.apache.servicecomb.saga.omega.transaction.MessageDeserializer; import org.apache.servicecomb.saga.omega.transaction.MessageSerializer; import org.apache.servicecomb.saga.omega.transaction.OmegaException; +import org.apache.servicecomb.saga.omega.transaction.TxEvent; -public class NativeMessageFormat implements MessageSerializer, MessageDeserializer { +interface MessageFormat extends MessageSerializer, MessageDeserializer { @Override - public byte[] serialize(TxEvent event) { + default byte[] serialize(TxEvent event) { try { return serialize(event.payloads()); } catch (OmegaException e) { throw new OmegaException("Unable to serialize event with global tx id " + event.globalTxId(), e); } } - - @Override - public byte[] serialize(Object[] objects) { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try (ObjectOutputStream outputStream = new ObjectOutputStream(out)) { - outputStream.writeObject(objects); - return out.toByteArray(); - } - } catch (IOException e) { - throw new OmegaException("Unable to serialize object", e); - } - } - - @Override - public Object[] deserialize(byte[] message) { - try (ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(message))) { - return (Object[]) inputStream.readObject(); - } catch (IOException | ClassNotFoundException e) { - throw new OmegaException("Unable to deserialize message", e); - } - } } diff --git a/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormatTest.java b/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormatTest.java new file mode 100644 index 0000000..1f63d74 --- /dev/null +++ b/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/KryoMessageFormatTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.saga.omega.format; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class KryoMessageFormatTest extends MessageFormatTestBase { + + @BeforeClass + public static void setUp() { + format = new KryoMessageFormat(); + } + + @Test + public void serializeEmptyClassIntoBytes() { + byte[] bytes = format.serialize(eventOf(new EmptyClass())); + + Object[] message = format.deserialize(bytes); + + assertThat(message[0] instanceof EmptyClass, is(true)); + } +} diff --git a/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormatTest.java b/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/MessageFormatTestBase.java similarity index 78% rename from omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormatTest.java rename to omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/MessageFormatTestBase.java index 1460fd2..17674b7 100644 --- a/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/NativeMessageFormatTest.java +++ b/omega/omega-format/src/test/java/org/apache/servicecomb/saga/omega/format/MessageFormatTestBase.java @@ -20,16 +20,20 @@ import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertThat; import org.apache.servicecomb.saga.omega.transaction.OmegaException; import org.apache.servicecomb.saga.omega.transaction.TxEvent; +import org.junit.Ignore; import org.junit.Test; -public class NativeMessageFormatTest { +@Ignore +public class MessageFormatTestBase { - private final NativeMessageFormat format = new NativeMessageFormat(); + static MessageFormat format; @Test public void serializeObjectIntoBytes() throws Exception { @@ -41,13 +45,12 @@ public void serializeObjectIntoBytes() throws Exception { } @Test - public void blowsUpWhenObjectIsNotSerializable() throws Exception { - try { - format.serialize(eventOf(new NotSerializable())); - expectFailing(OmegaException.class); - } catch (OmegaException e) { - assertThat(e.getMessage(), startsWith("Unable to serialize event with global tx id")); - } + public void serializeNullIntoBytes() throws Exception { + byte[] bytes = format.serialize(eventOf((Object[]) null)); + + Object[] message = format.deserialize(bytes); + + assertThat(message, is(nullValue())); } @Test @@ -60,10 +63,10 @@ public void blowsUpWhenObjectIsNotDeserializable() throws Exception { } } - private TxEvent eventOf(Object... payloads) { + TxEvent eventOf(Object... payloads) { return new TxEvent(null, null, null, null, payloads); } - private static class NotSerializable { + static class EmptyClass { } } diff --git a/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java b/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java index 9e0ebb6..7ed1f84 100644 --- a/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java +++ b/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java @@ -29,7 +29,7 @@ import org.apache.servicecomb.saga.omega.context.OmegaContext; import org.apache.servicecomb.saga.omega.context.ServiceConfig; import org.apache.servicecomb.saga.omega.context.UniqueIdGenerator; -import org.apache.servicecomb.saga.omega.format.NativeMessageFormat; +import org.apache.servicecomb.saga.omega.format.KryoMessageFormat; import org.apache.servicecomb.saga.omega.transaction.MessageHandler; import org.apache.servicecomb.saga.omega.transaction.MessageSender; import org.slf4j.Logger; @@ -76,7 +76,8 @@ MessageSender grpcMessageSender(@Value("${alpha.cluster.address}") String[] addr // TODO: 2017/12/26 connect to the one with lowest latency for (String address : addresses) { try { - MessageSender sender = new GrpcClientMessageSender(grpcChannel(address), new NativeMessageFormat(), new NativeMessageFormat(), serviceConfig, handler); + MessageSender sender = new GrpcClientMessageSender(grpcChannel(address), new KryoMessageFormat(), + new KryoMessageFormat(), serviceConfig, handler); sender.onConnected(); senders.add(sender); return sender; diff --git a/pom.xml b/pom.xml index 145b658..f2d275b 100755 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ <rat.version>0.12</rat.version> <maven.failsafe.version>2.19.1</maven.failsafe.version> <grpc.version>1.8.0</grpc.version> + <kryo.version>4.0.1</kryo.version> </properties> <name>ServiceComb Saga</name> @@ -329,6 +330,11 @@ <artifactId>grpc-stub</artifactId> <version>${grpc.version}</version> </dependency> + <dependency> + <groupId>com.esotericsoftware</groupId> + <artifactId>kryo</artifactId> + <version>${kryo.version}</version> + </dependency> <!-- test dependencies --> <dependency> ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > [pack] object serialization/deserialization > ------------------------------------------- > > Key: SCB-174 > URL: https://issues.apache.org/jira/browse/SCB-174 > Project: Apache ServiceComb > Issue Type: Improvement > Components: Saga > Reporter: Yin Xiang > Assignee: Eric Lee > Fix For: saga-0.1.0 > > > as of now, we used java native object serializer, i.e. ObjectInputStream & > ObjectOutputStream, for quick prototyping. > but these serializer/deserializer are problematic and we need to find more > suitable one. -- This message was sent by Atlassian JIRA (v6.4.14#64029)