diff --git a/README.md b/README.md index ebfc0b3..036df25 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

-# Meteor ![branches](.github/badges/branches.svg) ![jacoco coverage](.github/badges/jacoco.svg) +# Meteor ![Maven Central](https://img.shields.io/maven-central/v/dev.pixelib.meteor/meteor-parent) ![branches](.github/badges/branches.svg) ![jacoco coverage](.github/badges/jacoco.svg) > A general-purpose Java RPC library that plugs in like magic Meteor is designed to fill the (physical) gap between application instances and remote services where applications need to interface with a service that may be available locally or be provided by a remote JVM instance. @@ -12,7 +12,7 @@ It allows you to write your application against your interface as if it's local

-> *Note that this diagram ommits certain parts, like scheduling/threading and abstracted serailization layers to make it more readable.* +> *Note that this diagram omits certain parts, like scheduling/threading and abstracted serialization layers to make it more readable.* # Installation Meteor comes by default with a local loopback transport. @@ -21,7 +21,7 @@ Meteor is available on Maven Central, and can be installed by adding the followi dev.pixelib.meteor meteor-core - 1.0.0 + 1.0.2 ``` @@ -32,7 +32,7 @@ You can install the Redis transport by adding the following dependency to your ` dev.pixelib.meteor.transport meteor-jedis - 1.0.0 + 1.0.2 ``` @@ -105,7 +105,7 @@ A full performance analysis can be found [here](PERFORMANCE.md) # Design considerations ### To queue or not to queue -The library itself is unopinionated about transport and thus execution. +The library itself is un opinionated about transport and thus execution. It's up to the specific transport implementation to decide whether a fan-out or queueing strategy is appropriate. The default Redis implementation uses a normal broadcast, meaning that all invocations will be executed on all nodes which provide an implementation (but only the first return value is returned to the invoker function). Other implementations may use a more sophisticated queueing mechanism, allowing implementation instances to only process a subset of the invocations. ### Error handling @@ -115,5 +115,5 @@ Invocations leading to an exception on the implementation are considered as not Each Meteor instance uses its own internal thread pool for invocations against implementations. Invocations are queued up (in order of invocation time) if an implementation is busy. The thread pool size can be configured through the `RpcOptions`, and defaults to `1`. ### To serialize or not to serialize -The library itself is unopinionated about serialization. +The library itself is un opinionated about serialization. GSON gets used by default, but you can use any other serialization library you want, as long as it can serialize and deserialize generic types with another fallback method for unknown types. diff --git a/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethod.java b/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethod.java index fb09b06..b293e1f 100644 --- a/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethod.java +++ b/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethod.java @@ -10,6 +10,7 @@ public static void main(String[] args) throws Exception{ MathAdd mathAdd = meteor.registerProcedure(MathAdd.class); MathSubstract mathSubstract = meteor.registerProcedure(MathSubstract.class); + MathMultiply mathMultiply = meteor.registerProcedure(MathMultiply.class); // register an implementation, invocations will be dispatched to this object. // implementations will be registered under all interfaces they implement @@ -21,6 +22,9 @@ public static void main(String[] args) throws Exception{ int addResult = mathAdd.add(1, 2, 3, 4, 5); System.out.println("1 + 2 + 3 + 4 + 5 = " + addResult); + int multiResult = mathMultiply.multiply(5, 5); + System.out.println("5 * 5 = " + multiResult); + meteor.stop(); } diff --git a/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethodRedis.java b/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethodRedis.java index ae4a450..17e7902 100644 --- a/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethodRedis.java +++ b/examples/src/main/java/dev/pixelib/meteor/sender/SendingUpdateMethodRedis.java @@ -10,6 +10,7 @@ public static void main(String[] args) throws Exception{ MathAdd mathAdd = meteor.registerProcedure(MathAdd.class); MathSubstract mathSubstract = meteor.registerProcedure(MathSubstract.class); + MathMultiply mathMultiply = meteor.registerProcedure(MathMultiply.class); // register an implementation, invocations will be dispatched to this object. // implementations will be registered under all interfaces they implement @@ -22,6 +23,9 @@ public static void main(String[] args) throws Exception{ int addResult = mathAdd.add(1, 2, 3, 4, 5); System.out.println("1 + 2 + 3 + 4 + 5 = " + addResult); + int multiResult = mathMultiply.multiply(5, 5); + System.out.println("5 * 5 = " + multiResult); + meteor.stop(); } diff --git a/meteor-common/src/main/java/dev/pixelib/meteor/base/RpcTransport.java b/meteor-common/src/main/java/dev/pixelib/meteor/base/RpcTransport.java index 1402db2..b559b85 100644 --- a/meteor-common/src/main/java/dev/pixelib/meteor/base/RpcTransport.java +++ b/meteor-common/src/main/java/dev/pixelib/meteor/base/RpcTransport.java @@ -1,7 +1,7 @@ package dev.pixelib.meteor.base; -import dev.pixelib.meteor.base.interfaces.SubscriptionHandler; import dev.pixelib.meteor.base.enums.Direction; +import dev.pixelib.meteor.base.interfaces.SubscriptionHandler; import java.io.Closeable; diff --git a/meteor-common/src/main/java/dev/pixelib/meteor/base/defaults/LoopbackTransport.java b/meteor-common/src/main/java/dev/pixelib/meteor/base/defaults/LoopbackTransport.java index 599382a..ec6ffb7 100644 --- a/meteor-common/src/main/java/dev/pixelib/meteor/base/defaults/LoopbackTransport.java +++ b/meteor-common/src/main/java/dev/pixelib/meteor/base/defaults/LoopbackTransport.java @@ -6,17 +6,17 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; +import java.util.EnumMap; import java.util.List; import java.util.Map; public class LoopbackTransport implements RpcTransport { - private final Map> onReceiveFunctions = new HashMap<>(); + private final Map> onReceiveFunctions = new EnumMap<>(Direction.class); /** * @param bytes the bytes to send - * bytes given should already been considered as a packet, and should not be further processed by the transport implementation + * bytes given should already been considered as a packet, and should1not be further processed by the transport implementation * this particular implementation will call all the onReceive functions, and stop if one of them returns HANDLED * no actual sending is done, as this is a loopback transport meant for testing */ diff --git a/meteor-core/src/main/java/dev/pixelib/meteor/core/Meteor.java b/meteor-core/src/main/java/dev/pixelib/meteor/core/Meteor.java index b096a82..95f3e52 100644 --- a/meteor-core/src/main/java/dev/pixelib/meteor/core/Meteor.java +++ b/meteor-core/src/main/java/dev/pixelib/meteor/core/Meteor.java @@ -4,8 +4,8 @@ import dev.pixelib.meteor.base.RpcSerializer; import dev.pixelib.meteor.base.RpcTransport; import dev.pixelib.meteor.base.defaults.GsonSerializer; -import dev.pixelib.meteor.core.proxy.ProxyInvocHandler; import dev.pixelib.meteor.core.proxy.MeteorMock; +import dev.pixelib.meteor.core.proxy.ProxyInvocHandler; import dev.pixelib.meteor.core.trackers.IncomingInvocationTracker; import dev.pixelib.meteor.core.trackers.OutgoingInvocationTracker; import dev.pixelib.meteor.core.transport.TransportHandler; diff --git a/meteor-core/src/main/java/dev/pixelib/meteor/core/proxy/ProxyInvocHandler.java b/meteor-core/src/main/java/dev/pixelib/meteor/core/proxy/ProxyInvocHandler.java index 881d0be..1486861 100644 --- a/meteor-core/src/main/java/dev/pixelib/meteor/core/proxy/ProxyInvocHandler.java +++ b/meteor-core/src/main/java/dev/pixelib/meteor/core/proxy/ProxyInvocHandler.java @@ -1,7 +1,7 @@ package dev.pixelib.meteor.core.proxy; -import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import dev.pixelib.meteor.core.trackers.OutgoingInvocationTracker; +import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; diff --git a/meteor-core/src/main/java/dev/pixelib/meteor/core/transport/TransportHandler.java b/meteor-core/src/main/java/dev/pixelib/meteor/core/transport/TransportHandler.java index ae8d6a5..9b1ecf7 100644 --- a/meteor-core/src/main/java/dev/pixelib/meteor/core/transport/TransportHandler.java +++ b/meteor-core/src/main/java/dev/pixelib/meteor/core/transport/TransportHandler.java @@ -5,18 +5,21 @@ import dev.pixelib.meteor.base.enums.Direction; import dev.pixelib.meteor.core.executor.ImplementationWrapper; import dev.pixelib.meteor.core.trackers.IncomingInvocationTracker; +import dev.pixelib.meteor.core.trackers.OutgoingInvocationTracker; import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import dev.pixelib.meteor.core.transport.packets.InvocationResponse; -import dev.pixelib.meteor.core.trackers.OutgoingInvocationTracker; import java.io.Closeable; import java.io.IOException; import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; public class TransportHandler implements Closeable { + private final Logger logger = Logger.getLogger(TransportHandler.class.getSimpleName()); private final RpcSerializer serializer; private final RpcTransport transport; private final IncomingInvocationTracker incomingInvocationTracker; @@ -91,8 +94,8 @@ private boolean handleInvocationRequest(byte[] bytes) throws ClassNotFoundExcept Object response = matchedImplementation.invokeOn(invocationDescriptor, invocationDescriptor.getReturnType()); InvocationResponse invocationResponse = new InvocationResponse(invocationDescriptor.getUniqueInvocationId(), response); transport.send(Direction.METHOD_PROXY, invocationResponse.toBytes(serializer)); - } catch (NoSuchMethodException e) { - e.printStackTrace(); + } catch (Throwable e) { + logger.log(Level.SEVERE, "An error occurred while invoking a method", e); } }); diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/LogicTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/LogicTest.java index e34b6c8..8d7ded0 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/LogicTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/LogicTest.java @@ -8,7 +8,7 @@ import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; public class LogicTest { diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/MeteorTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/MeteorTest.java index f42b708..40154eb 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/MeteorTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/MeteorTest.java @@ -1,8 +1,8 @@ package dev.pixelib.meteor.core; import dev.pixelib.meteor.base.defaults.LoopbackTransport; -import org.junit.jupiter.api.Test; import dev.pixelib.meteor.core.utils.MathFunctions; +import org.junit.jupiter.api.Test; import java.lang.reflect.Proxy; diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/invocations/PendingInvocationTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/invocations/PendingInvocationTest.java index cb32973..8cc21dc 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/invocations/PendingInvocationTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/invocations/PendingInvocationTest.java @@ -4,8 +4,8 @@ import dev.pixelib.meteor.base.defaults.GsonSerializer; import dev.pixelib.meteor.base.defaults.LoopbackTransport; import dev.pixelib.meteor.base.errors.InvocationTimedOutException; -import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import dev.pixelib.meteor.core.trackers.OutgoingInvocationTracker; +import dev.pixelib.meteor.core.transport.packets.InvocationDescriptor; import dev.pixelib.meteor.core.transport.packets.InvocationResponse; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/trackers/IncomingInvocationTrackerTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/trackers/IncomingInvocationTrackerTest.java index 2b5ce96..5ffee70 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/trackers/IncomingInvocationTrackerTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/trackers/IncomingInvocationTrackerTest.java @@ -1,8 +1,8 @@ package dev.pixelib.meteor.core.trackers; import dev.pixelib.meteor.core.executor.ImplementationWrapper; -import org.junit.jupiter.api.Test; import dev.pixelib.meteor.core.utils.MathFunctions; +import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationDescriptorTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationDescriptorTest.java index 0eb2ed2..d200708 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationDescriptorTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationDescriptorTest.java @@ -4,7 +4,7 @@ import dev.pixelib.meteor.base.defaults.GsonSerializer; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; class InvocationDescriptorTest { diff --git a/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationResponseTest.java b/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationResponseTest.java index af493fc..8075eff 100644 --- a/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationResponseTest.java +++ b/meteor-core/src/test/java/dev/pixelib/meteor/core/transport/packets/InvocationResponseTest.java @@ -6,7 +6,8 @@ import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; class InvocationResponseTest { diff --git a/meteor-jedis/src/test/java/dev/pixelib/meteor/transport/redis/RedisPacketListenerTest.java b/meteor-jedis/src/test/java/dev/pixelib/meteor/transport/redis/RedisPacketListenerTest.java index 43db742..0543cbe 100644 --- a/meteor-jedis/src/test/java/dev/pixelib/meteor/transport/redis/RedisPacketListenerTest.java +++ b/meteor-jedis/src/test/java/dev/pixelib/meteor/transport/redis/RedisPacketListenerTest.java @@ -7,9 +7,7 @@ import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; -import redis.clients.jedis.Connection; import redis.clients.jedis.JedisPool; import java.util.Base64; diff --git a/pom.xml b/pom.xml index 36a9e61..81523fa 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ - 1.0.0-localbuild + 1.0.2-localbuild 17 17 UTF-8