-
Notifications
You must be signed in to change notification settings - Fork 11
RedisCommandReplicator Native method implementation #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev-pr
Are you sure you want to change the base?
Changes from all commits
afec947
8fec691
3222193
ca4a1f8
85d3256
fd6d8d7
16b7b28
6ce07bb
07c3f4c
16ad659
52891e5
76929c7
89b81ed
c8fa4e0
b9ad5bf
1f940ee
ec8205b
563db9b
f4ed19c
4b0db5e
f24a3a0
431b3ff
d5a67e7
757f24b
29762dc
c08af07
34f05b4
3719ab4
9da4aef
2457897
d99bdc9
c5b5682
97fcf62
16074b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package io.microsphere.redis.replicator.spring.event.handler; | ||
|
|
||
| import java.lang.reflect.Method; | ||
|
|
||
| import static io.microsphere.redis.spring.metadata.RedisMetadataRepository.getWriteCommandMethodHandle; | ||
|
|
||
| public class MethodHandleRedisCommandReplicatedEventHandler implements RedisCommandReplicatedEventHandler { | ||
|
|
||
| @Override | ||
| public void handleEvent(Method method, Object redisCommandObject, Object... args) throws Throwable { | ||
| int length = args.length; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| Object[] arguments = new Object[1 + args.length]; | ||
| arguments[0] = redisCommandObject; | ||
| System.arraycopy(args, 0, arguments, 1, length); | ||
| getWriteCommandMethodHandle(method).invokeWithArguments(arguments); | ||
| } | ||
|
|
||
| @Override | ||
| public String name() { | ||
| return EventHandleName.METHOD_HANDLE.name(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package io.microsphere.redis.replicator.spring.event.handler; | ||
|
|
||
| import java.lang.reflect.Method; | ||
|
|
||
| public interface RedisCommandReplicatedEventHandler { | ||
| void handleEvent(Method method, Object redisCommandObject, Object... args) throws Throwable; | ||
|
Check warning on line 6 in microsphere-redis-replicator-spring/src/main/java/io/microsphere/redis/replicator/spring/event/handler/RedisCommandReplicatedEventHandler.java
|
||
|
|
||
| String name(); | ||
|
|
||
| enum EventHandleName{ | ||
| REFLECT, | ||
| METHOD_HANDLE; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package io.microsphere.redis.replicator.spring.event.handler; | ||
|
|
||
| import org.springframework.util.ReflectionUtils; | ||
|
|
||
| import java.lang.reflect.Method; | ||
|
|
||
| import static io.microsphere.redis.replicator.spring.event.handler.RedisCommandReplicatedEventHandler.EventHandleName.REFLECT; | ||
|
|
||
| public class ReflectRedisCommandReplicatedEventHandler implements RedisCommandReplicatedEventHandler { | ||
|
|
||
| @Override | ||
| public void handleEvent(Method method, Object redisCommandObject, Object... args) throws Throwable { | ||
|
|
||
| ReflectionUtils.invokeMethod(method, redisCommandObject, args); | ||
| } | ||
|
|
||
| @Override | ||
| public String name() { | ||
| return REFLECT.name(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| package io.microsphere.redis.benchmark; | ||
|
|
||
| import io.microsphere.redis.replicator.spring.event.handler.MethodHandleRedisCommandReplicatedEventHandler; | ||
| import io.microsphere.redis.replicator.spring.event.handler.RedisCommandReplicatedEventHandler; | ||
| import io.microsphere.redis.replicator.spring.event.handler.ReflectRedisCommandReplicatedEventHandler; | ||
| import org.openjdk.jmh.annotations.Benchmark; | ||
| import org.openjdk.jmh.annotations.BenchmarkMode; | ||
| import org.openjdk.jmh.annotations.Fork; | ||
| import org.openjdk.jmh.annotations.Level; | ||
| import org.openjdk.jmh.annotations.Measurement; | ||
| import org.openjdk.jmh.annotations.Mode; | ||
| import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
| import org.openjdk.jmh.annotations.Scope; | ||
| import org.openjdk.jmh.annotations.Setup; | ||
| import org.openjdk.jmh.annotations.State; | ||
| import org.openjdk.jmh.annotations.TearDown; | ||
| import org.openjdk.jmh.annotations.Warmup; | ||
| import org.springframework.data.redis.connection.RedisConnection; | ||
| import org.springframework.data.redis.connection.RedisStandaloneConfiguration; | ||
| import org.springframework.data.redis.connection.RedisStringCommands; | ||
| import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
| import org.testcontainers.containers.GenericContainer; | ||
|
|
||
| import java.lang.reflect.Method; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| import static io.microsphere.redis.spring.metadata.RedisMetadataRepository.findWriteCommandMethod; | ||
| import static org.testcontainers.utility.DockerImageName.parse; | ||
|
|
||
| @State(Scope.Thread) | ||
| @BenchmarkMode(Mode.AverageTime) | ||
| @OutputTimeUnit(TimeUnit.NANOSECONDS) | ||
| @Warmup(iterations = 5, time = 1) | ||
| @Measurement(iterations = 20, time = 1) | ||
| @Fork(3) | ||
| public class RedisCommandReplicatedEventHandlerBenchmark { | ||
| static GenericContainer<?> redisContainer; | ||
| RedisStringCommands redisStringCommands; | ||
| Method method; | ||
| RedisCommandReplicatedEventHandler methodHandleHandler; | ||
| RedisCommandReplicatedEventHandler reflectHandler; | ||
|
|
||
| byte[] key; | ||
| byte[] value; | ||
|
|
||
| @Setup(Level.Trial) | ||
| public void setup() throws Exception { | ||
| // 启动 PostgreSQL 容器 | ||
| redisContainer = new GenericContainer<>(parse("redis:latest")).withExposedPorts(6379); | ||
| redisContainer.start(); | ||
|
|
||
| String interfaceName = "org.springframework.data.redis.connection.RedisStringCommands"; | ||
| String methodName = "set"; | ||
| String[] parameterTypes = new String[]{"[B", "[B"}; | ||
| method = findWriteCommandMethod(interfaceName, methodName, parameterTypes); | ||
|
|
||
| LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(redisContainer.getHost(), redisContainer.getFirstMappedPort())); | ||
| redisConnectionFactory.afterPropertiesSet(); | ||
| RedisConnection connection = redisConnectionFactory.getConnection(); | ||
| redisStringCommands = connection.stringCommands(); | ||
|
|
||
| methodHandleHandler = new MethodHandleRedisCommandReplicatedEventHandler(); | ||
| reflectHandler = new ReflectRedisCommandReplicatedEventHandler(); | ||
| key = "key".getBytes(StandardCharsets.UTF_8); | ||
| value = "value".getBytes(StandardCharsets.UTF_8); | ||
| } | ||
|
|
||
| @Benchmark | ||
| public void benchmarkDirect() throws Throwable { | ||
| redisStringCommands.set(key, value); | ||
| } | ||
|
|
||
| @Benchmark | ||
| public void benchmarkMethodHandleRedisCommandReplicatedEventHandler() throws Throwable { | ||
| methodHandleHandler.handleEvent(method, redisStringCommands, key, value); | ||
| } | ||
|
|
||
| @Benchmark | ||
| public void benchmarkReflectRedisCommandReplicatedEventHandler() throws Throwable { | ||
| reflectHandler.handleEvent(method, redisStringCommands, key, value); | ||
| } | ||
|
|
||
| @TearDown(Level.Trial) | ||
| public void tearDown() throws Exception { | ||
|
Check warning on line 85 in microsphere-redis-replicator-spring/src/test/java/io/microsphere/redis/benchmark/RedisCommandReplicatedEventHandlerBenchmark.java
|
||
| if (redisContainer != null) { | ||
| redisContainer.stop(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package io.microsphere.redis.benchmark.runner; | ||
|
|
||
| import io.microsphere.redis.benchmark.RedisCommandReplicatedEventHandlerBenchmark; | ||
| import org.openjdk.jmh.runner.Runner; | ||
| import org.openjdk.jmh.runner.RunnerException; | ||
| import org.openjdk.jmh.runner.options.Options; | ||
| import org.openjdk.jmh.runner.options.OptionsBuilder; | ||
|
|
||
| public class BenchmarkRunner { | ||
| public static void main(String[] args) throws RunnerException { | ||
| Options options = new OptionsBuilder() | ||
| .include(RedisCommandReplicatedEventHandlerBenchmark.class.getSimpleName()) | ||
| .warmupIterations(3) | ||
| .measurementIterations(5) | ||
| .forks(1) | ||
| .build(); | ||
|
|
||
| new Runner(options).run(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thrown
IllegalStateException("No eventHandle found")doesn’t includeCONSUMER_EVENT_HANDLE_PROPERTY_NAMEor the configuredeventHandleType, which can make misconfiguration harder to diagnose. Consider including those details in the exception message.🤖 Was this useful? React with 👍 or 👎