use of com.alipay.sofa.jraft.rpc.Connection in project sofa-jraft by sofastack.
the class AppendEntriesRequestProcessorTest method setup.
@Override
public void setup() {
super.setup();
this.asyncContext = new MockAsyncContext() {
@Override
public Connection getConnection() {
return AppendEntriesRequestProcessorTest.this.conn;
}
};
Set<PeerPair> pairs = new ConcurrentHashSet<>();
pairs.add(new PeerPair(this.peerIdStr, this.serverId));
Mockito.when(this.conn.getAttribute(AppendEntriesRequestProcessor.PAIR_ATTR)).thenReturn(pairs);
}
use of com.alipay.sofa.jraft.rpc.Connection in project sofa-jraft by sofastack.
the class GrpcServer method registerProcessor.
@SuppressWarnings("unchecked")
@Override
public void registerProcessor(final RpcProcessor processor) {
final String interest = processor.interest();
final Message reqIns = Requires.requireNonNull(this.parserClasses.get(interest), "null default instance: " + interest);
final MethodDescriptor<Message, Message> method = //
MethodDescriptor.<Message, Message>newBuilder().setType(//
MethodDescriptor.MethodType.UNARY).setFullMethodName(//
MethodDescriptor.generateFullMethodName(processor.interest(), GrpcRaftRpcFactory.FIXED_METHOD_NAME)).setRequestMarshaller(//
ProtoUtils.marshaller(reqIns)).setResponseMarshaller(//
ProtoUtils.marshaller(this.marshallerRegistry.findResponseInstanceByRequest(interest))).build();
final ServerCallHandler<Message, Message> handler = ServerCalls.asyncUnaryCall((request, responseObserver) -> {
final SocketAddress remoteAddress = RemoteAddressInterceptor.getRemoteAddress();
final Connection conn = ConnectionInterceptor.getCurrentConnection(this.closedEventListeners);
final RpcContext rpcCtx = new RpcContext() {
@Override
public void sendResponse(final Object responseObj) {
try {
responseObserver.onNext((Message) responseObj);
responseObserver.onCompleted();
} catch (final Throwable t) {
LOG.warn("[GRPC] failed to send response.", t);
}
}
@Override
public Connection getConnection() {
if (conn == null) {
throw new IllegalStateException("fail to get connection");
}
return conn;
}
@Override
public String getRemoteAddress() {
// Rely on GRPC's capabilities, not magic (netty channel)
return remoteAddress != null ? remoteAddress.toString() : null;
}
};
final RpcProcessor.ExecutorSelector selector = processor.executorSelector();
Executor executor;
if (selector != null && request instanceof RpcRequests.AppendEntriesRequest) {
final RpcRequests.AppendEntriesRequest req = (RpcRequests.AppendEntriesRequest) request;
final RpcRequests.AppendEntriesRequestHeader.Builder header = //
RpcRequests.AppendEntriesRequestHeader.newBuilder().setGroupId(//
req.getGroupId()).setPeerId(//
req.getPeerId()).setServerId(req.getServerId());
executor = selector.select(interest, header.build());
} else {
executor = processor.executor();
}
if (executor == null) {
executor = this.defaultExecutor;
}
if (executor != null) {
executor.execute(() -> processor.handleRequest(rpcCtx, request));
} else {
processor.handleRequest(rpcCtx, request);
}
});
final ServerServiceDefinition serviceDef = //
ServerServiceDefinition.builder(//
interest).addMethod(method, //
handler).build();
this.handlerRegistry.addService(ServerInterceptors.intercept(serviceDef, this.serverInterceptors.toArray(new ServerInterceptor[0])));
}
use of com.alipay.sofa.jraft.rpc.Connection in project sofa-jraft by sofastack.
the class AppendEntriesRequestProcessor method sendSequenceResponse.
/**
* Send request in pipeline mode.
*/
void sendSequenceResponse(final String groupId, final PeerPair pair, final int seq, final RpcContext rpcCtx, final Message msg) {
final PeerRequestContext ctx = getPeerRequestContext(groupId, pair);
if (ctx == null) {
// the context was destroyed, so the response can be ignored.
return;
}
final PriorityQueue<SequenceMessage> respQueue = ctx.responseQueue;
assert (respQueue != null);
synchronized (Utils.withLockObject(respQueue)) {
respQueue.add(new SequenceMessage(rpcCtx, msg, seq));
if (!ctx.hasTooManyPendingResponses()) {
while (!respQueue.isEmpty()) {
final SequenceMessage queuedPipelinedResponse = respQueue.peek();
if (queuedPipelinedResponse.sequence != ctx.getNextRequiredSequence()) {
// sequence mismatch, waiting for next response.
break;
}
respQueue.remove();
try {
queuedPipelinedResponse.sendResponse();
} finally {
ctx.getAndIncrementNextRequiredSequence();
}
}
} else {
final Connection connection = rpcCtx.getConnection();
LOG.warn("Closed connection to peer {}/{}, because of too many pending responses, queued={}, max={}", ctx.groupId, pair, respQueue.size(), ctx.maxPendingResponses);
connection.close();
// Close the connection if there are too many pending responses in queue.
removePeerRequestContext(groupId, pair);
}
}
}
use of com.alipay.sofa.jraft.rpc.Connection in project sofa-jraft by sofastack.
the class BoltRpcServer method registerConnectionClosedEventListener.
@Override
public void registerConnectionClosedEventListener(final ConnectionClosedEventListener listener) {
this.rpcServer.addConnectionEventProcessor(ConnectionEventType.CLOSE, (remoteAddress, conn) -> {
final Connection proxyConn = conn == null ? null : new Connection() {
@Override
public Object getAttribute(final String key) {
return conn.getAttribute(key);
}
@Override
public Object setAttributeIfAbsent(final String key, final Object value) {
return conn.setAttributeIfAbsent(key, value);
}
@Override
public void setAttribute(final String key, final Object value) {
conn.setAttribute(key, value);
}
@Override
public void close() {
conn.close();
}
};
listener.onClosed(remoteAddress, proxyConn);
});
}
use of com.alipay.sofa.jraft.rpc.Connection in project sofa-jraft by sofastack.
the class AppendEntriesRequestProcessorTest method testTooManyPendingResponses.
@Test
public void testTooManyPendingResponses() {
final PeerId peer = mockNode();
NodeManager.getInstance().get(this.groupId, peer).getRaftOptions().setMaxReplicatorInflightMsgs(2);
final RpcContext asyncContext = Mockito.mock(RpcContext.class);
final AppendEntriesRequestProcessor processor = (AppendEntriesRequestProcessor) newProcessor();
final PeerPair pair = processor.pairOf(this.peerIdStr, this.serverId);
final PingRequest msg = TestUtils.createPingRequest();
final Connection conn = Mockito.mock(Connection.class);
Mockito.when(asyncContext.getConnection()).thenReturn(conn);
final PeerRequestContext ctx = processor.getOrCreatePeerRequestContext(this.groupId, pair, conn);
assertNotNull(ctx);
processor.sendSequenceResponse(this.groupId, pair, 1, asyncContext, msg);
processor.sendSequenceResponse(this.groupId, pair, 2, asyncContext, msg);
processor.sendSequenceResponse(this.groupId, pair, 3, asyncContext, msg);
Mockito.verify(asyncContext, Mockito.never()).sendResponse(msg);
Mockito.verify(conn).close();
final PeerRequestContext newCtx = processor.getOrCreatePeerRequestContext(this.groupId, pair, conn);
assertNotNull(newCtx);
assertNotSame(ctx, newCtx);
}
Aggregations