FIRST INITIAL

This commit is contained in:
Qing Wang
2020-10-21 21:38:06 +08:00
parent 7e22d4b402
commit f4c9b02908
7 changed files with 45 additions and 40 deletions
@@ -10,7 +10,7 @@ public interface AsyncRpcFunction {
// CompletableFuture<Object> invoke(Arg1Type arg1); // CompletableFuture<Object> invoke(Arg1Type arg1);
<ReturnType, Arg1Type, Arg2Type> <ReturnType, Arg1Type, Arg2Type>
RestFuture<ReturnType> invoke(Arg1Type arg1, Arg2Type arg2); CompletableFuture<Object> invoke(Class returnClz, Arg1Type arg1, Arg2Type arg2);
// <Arg1Type, Arg2Type, Arg3Type> // <Arg1Type, Arg2Type, Arg3Type>
// CompletableFuture<Object> invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3); // CompletableFuture<Object> invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3);
@@ -23,9 +23,9 @@ public class AsyncRpcFunctionImpl implements AsyncRpcFunction {
// } // }
public <ReturnType, Arg1Type, Arg2Type> public <ReturnType, Arg1Type, Arg2Type>
RestFuture<ReturnType> invoke(Arg1Type arg1, Arg2Type arg2) { CompletableFuture<Object> invoke(Class returnClz, Arg1Type arg1, Arg2Type arg2) {
Object[] args = new Object[] {arg1, arg2}; Object[] args = new Object[] {arg1, arg2};
return internalInvoke(args); return internalInvoke(returnClz, args);
} }
// public <Arg1Type, Arg2Type, Arg3Type> // public <Arg1Type, Arg2Type, Arg3Type>
@@ -53,7 +53,7 @@ public class AsyncRpcFunctionImpl implements AsyncRpcFunction {
// return internalInvoke(args); // return internalInvoke(args);
// } // }
private <ReturnType> RestFuture<ReturnType> internalInvoke(Object[] args) { private <ReturnType> CompletableFuture<Object> internalInvoke(Class returnClz, Object[] args) {
return rpcClient.invoke(funcName, args); return rpcClient.invoke(returnClz, funcName, args);
} }
} }
@@ -46,8 +46,8 @@ public class Codec {
return messagePacker.toByteArray(); return messagePacker.toByteArray();
} }
public Object decodeSingleValue(String targetTypeName, byte[] encodedBytes) throws IOException { public Object decodeReturnValue(Class returnClz, byte[] encodedBytes) throws IOException {
if (targetTypeName == null) { if (returnClz == null) {
throw new RuntimeException("Internal bug."); throw new RuntimeException("Internal bug.");
} }
@@ -57,17 +57,18 @@ public class Codec {
// TODO(qwang): unpack nil. // TODO(qwang): unpack nil.
MessageUnpacker messageUnpacker = MessagePack.newDefaultUnpacker(encodedBytes); MessageUnpacker messageUnpacker = MessagePack.newDefaultUnpacker(encodedBytes);
switch (targetTypeName) { // Unpack unnecessary fields.
case INT_TYPE_NAME: messageUnpacker.unpackArrayHeader();
return messageUnpacker.unpackInt(); messageUnpacker.unpackInt();
case LONG_TYPE_NAME:
return messageUnpacker.unpackLong();
case STRING_TYPE_NAME:
return messageUnpacker.unpackString();
default:
throw new RuntimeException("Unknown type: " + targetTypeName);
}
if (Integer.class.equals(returnClz)) {
return messageUnpacker.unpackInt();
} else if (Long.class.equals(returnClz)) {
return messageUnpacker.unpackLong();
} else if (String.class.equals(returnClz)) {
return messageUnpacker.unpackString();
}
throw new RuntimeException("Unknown type: " + returnClz);
} }
public int myDecodeInt(byte[] encodedBytes) throws IOException { public int myDecodeInt(byte[] encodedBytes) throws IOException {
@@ -1,7 +1,7 @@
package org.restrpc.client; package org.restrpc.client;
import java.io.IOException; import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -16,9 +16,9 @@ public class NativeRpcClient implements RpcClient {
private Codec codec; private Codec codec;
// The map to cache return type. // The map to cache return type.
private ConcurrentHashMap<Long, String> localFutureReturnTypenameCache = new ConcurrentHashMap<>(); private ConcurrentHashMap<Long, Class<?>> localFutureReturnTypenameCache = new ConcurrentHashMap<>();
private ConcurrentHashMap<Long, RestFuture<?>> localFutureCache = new ConcurrentHashMap<>(); private ConcurrentHashMap<Long, CompletableFuture<Object>> localFutureCache = new ConcurrentHashMap<>();
public NativeRpcClient() { public NativeRpcClient() {
rpcClientPointer = nativeNewRpcClient(); rpcClientPointer = nativeNewRpcClient();
@@ -39,7 +39,7 @@ public class NativeRpcClient implements RpcClient {
return new AsyncRpcFunctionImpl(this, funcName); return new AsyncRpcFunctionImpl(this, funcName);
} }
public <ReturnType> RestFuture<ReturnType> invoke(String funcName, Object[] args) { public <ReturnType> CompletableFuture<Object> invoke(Class returnClz, String funcName, Object[] args) {
if (rpcClientPointer == -1) { if (rpcClientPointer == -1) {
throw new RuntimeException("no init"); throw new RuntimeException("no init");
} }
@@ -55,10 +55,14 @@ public class NativeRpcClient implements RpcClient {
return null; return null;
} }
final long requestId = nativeInvoke(rpcClientPointer, encodedBytes); synchronized (this) {
RestFuture<ReturnType> futureToReturn = new RestFuture<ReturnType>() {}; final long requestId = nativeInvoke(rpcClientPointer, encodedBytes);
localFutureCache.put(requestId, futureToReturn); CompletableFuture<Object> futureToReturn = new CompletableFuture<Object>();
return futureToReturn; localFutureReturnTypenameCache.put(requestId, returnClz);
localFutureCache.put(requestId, futureToReturn);
return futureToReturn;
}
} }
public void close() { public void close() {
@@ -76,15 +80,13 @@ public class NativeRpcClient implements RpcClient {
*/ */
private void onResultReceived(long requestId, byte[] encodedReturnValueBytes) throws IOException { private void onResultReceived(long requestId, byte[] encodedReturnValueBytes) throws IOException {
// if (requestId not is local_cache) {//error} // if (requestId not is local_cache) {//error}
// codec.decodeReturnValue(encodedReturnValueBytes); // System.out.println("result is " + codec.myDecodeInt(encodedReturnValueBytes));
System.out.println("-----------oo java-----------"); synchronized (this) {
System.out.println("result is " + codec.myDecodeInt(encodedReturnValueBytes)); final Class<?> returnClz = localFutureReturnTypenameCache.get(requestId);
System.out.println("-----------end java-----------"); CompletableFuture<Object> future = localFutureCache.get(requestId);
Object o = codec.decodeReturnValue(returnClz, encodedReturnValueBytes);
RestFuture<?> future = localFutureCache.get(requestId); future.complete(o);
future.getClass().getGenericSuperclass().getTypeName(); }
Object o = codec.decodeSingleValue(
future.getClass().getGenericSuperclass().getTypeName(), encodedReturnValueBytes);
} }
private native long nativeNewRpcClient(); private native long nativeNewRpcClient();
@@ -2,6 +2,7 @@ package org.restrpc.client;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CompletableFuture;
public class RestFuture<T> { public class RestFuture<T> {
@@ -12,6 +13,7 @@ public class RestFuture<T> {
public RestFuture(Class<T> metaType) { public RestFuture(Class<T> metaType) {
this.metaType = metaType; this.metaType = metaType;
} }
private byte[] encodedData; private byte[] encodedData;
private static Codec codec = new Codec(); private static Codec codec = new Codec();
@@ -8,7 +8,7 @@ public interface RpcClient {
AsyncRpcFunction asyncFunc(String funcName); AsyncRpcFunction asyncFunc(String funcName);
<ReturnType> RestFuture<ReturnType> invoke(String funcName, Object[] args); <ReturnType> CompletableFuture<Object> invoke(Class returnClz, String funcName, Object[] args);
void close(); void close();
} }
@@ -12,17 +12,17 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class BasicClientTest { public class BasicClientTest {
@Test @Test
public void testBasic() throws IOException, InterruptedException { public void testBasic() throws IOException, InterruptedException, ExecutionException {
RpcClient rpcClient = new NativeRpcClient(); RpcClient rpcClient = new NativeRpcClient();
rpcClient.connect("127.0.0.1:9000"); rpcClient.connect("127.0.0.1:9000");
RestFuture<Integer> obj = rpcClient.asyncFunc("add").invoke(2, 3); CompletableFuture<Object> future = rpcClient.asyncFunc("echo").invoke(String.class, 2, 3);
TimeUnit.SECONDS.sleep(10000); System.out.println("The result of add(2, 3) is " + future.get());
System.out.println("The result of add(2, 3) is " + obj.get());
} }
private String getClassStr(Object o) { private String getClassStr(Object o) {
@@ -50,7 +50,7 @@ public class BasicClientTest {
@Test @Test
public void testDecode() throws IOException { public void testDecode() throws IOException {
CompletableFuture<?> i = new CompletableFuture<Integer>() {}; // CompletableFuture<?> i = new CompletableFuture<Integer>() {};
// System.out.println(i.getClass().getDeclare); // System.out.println(i.getClass().getDeclare);
// //
// OutputStream os = new ByteArrayOutputStream(); // OutputStream os = new ByteArrayOutputStream();