/** * Encapsulate the ugly casting and RuntimeException conversion in private method. * @return Codec to use on this client. */ Codec getCodec() { // For NO CODEC, "hbase.client.rpc.codec" must be configured with empty string AND // "hbase.client.default.rpc.codec" also -- because default is to do cell block encoding. String className = conf.get(HConstants.RPC_CODEC_CONF_KEY, getDefaultCodec(this.conf)); if (className == null || className.length() == 0) { return null; } try { return (Codec) Class.forName(className).getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException("Failed getting codec " + className, e); } }
this.codec = getCodec(); this.compressor = getCompressor(conf); this.fallbackAllowed = conf.getBoolean(IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_KEY, IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_DEFAULT); HConstants.DEFAULT_HBASE_CLIENT_PERSERVER_REQUESTS_THRESHOLD); this.connections = new PoolMap<>(getPoolType(conf), getPoolSize(conf));
/** * Make a blocking call. Throws exceptions if there are network problems or if the remote code * threw an exception. * @param ticket Be careful which ticket you pass. A new user will mean a new Connection. * {@link UserProvider#getCurrent()} makes a new instance of User each time so will be a * new Connection each time. * @return A pair with the Message response and the Cell data (if any). */ private Message callBlockingMethod(Descriptors.MethodDescriptor md, HBaseRpcController hrc, Message param, Message returnType, final User ticket, final InetSocketAddress isa) throws ServiceException { BlockingRpcCallback<Message> done = new BlockingRpcCallback<>(); callMethod(md, hrc, param, returnType, ticket, isa, done); Message val; try { val = done.get(); } catch (IOException e) { throw new ServiceException(e); } if (hrc.failed()) { throw new ServiceException(hrc.getFailed()); } else { return val; } }
this.codec = getCodec(); this.compressor = getCompressor(conf); this.fallbackAllowed = conf.getBoolean(IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_KEY, IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_DEFAULT);
Call call = new Call(nextCallId(), md, param, hrc.cellScanner(), returnType, hrc.getCallTimeout(), hrc.getPriority(), new RpcCallback<Call>() { @Override T connection = getConnection(remoteId); connection.sendRequest(call, hrc); } catch (Exception e) {
@Override public RpcChannel createRpcChannel(ServerName sn, User user, int rpcTimeout) throws UnknownHostException { return new RpcChannelImplementation(this, createAddr(sn), user, rpcTimeout); }
@Test public void testRpcWithWriteThread() throws IOException, InterruptedException { LOG.info("Starting test"); Cluster cluster = new Cluster(1, 1); cluster.startServer(); conf.setBoolean(SPECIFIC_WRITE_THREAD, true); for(int i = 0; i <1000; i++) { AbstractRpcClient<?> rpcClient = createRpcClient(conf, true); SimpleClient client = new SimpleClient(cluster, rpcClient, "Client1"); client.start(); while(!client.isSending()) { Thread.sleep(1); } client.stopRunning(); rpcClient.close(); } }
@Override public void close() { if (LOG.isDebugEnabled()) { LOG.debug("Stopping rpc client"); } Collection<T> connToClose; synchronized (connections) { if (!running) { return; } running = false; connToClose = connections.values(); connections.clear(); } cleanupIdleConnectionTask.cancel(true); for (T conn : connToClose) { conn.shutdown(); } closeInternal(); for (T conn : connToClose) { conn.cleanupConnection(); } }
/** * Get a connection from the pool, or create a new one and add it to the pool. Connections to a * given host/port are reused. */ private T getConnection(ConnectionId remoteId) throws IOException { if (failedServers.isFailedServer(remoteId.getAddress())) { if (LOG.isDebugEnabled()) { LOG.debug("Not trying to connect to " + remoteId.address + " this server is in the failed servers list"); } throw new FailedServerException( "This server is in the failed servers list: " + remoteId.address); } T conn; synchronized (connections) { if (!running) { throw new StoppedRpcClientException(); } conn = connections.get(remoteId); if (conn == null) { conn = createConnection(remoteId); connections.put(remoteId, conn); } conn.setLastTouched(EnvironmentEdgeManager.currentTime()); } return conn; }
private void callMethod(final Descriptors.MethodDescriptor md, final HBaseRpcController hrc, final Message param, Message returnType, final User ticket, final InetSocketAddress addr, final RpcCallback<Message> callback) { final MetricsConnection.CallStats cs = MetricsConnection.newCallStats(); cs.setStartTime(EnvironmentEdgeManager.currentTime()); final AtomicInteger counter = concurrentCounterCache.getUnchecked(addr); Call call = new Call(nextCallId(), md, param, hrc.cellScanner(), returnType, hrc.getCallTimeout(), hrc.getPriority(), new RpcCallback<Call>() { @Override public void run(Call call) { counter.decrementAndGet(); onCallFinished(call, hrc, addr, callback); } }, cs); ConnectionId remoteId = new ConnectionId(ticket, md.getService().getName(), addr); int count = counter.incrementAndGet(); try { if (count > maxConcurrentCallsPerServer) { throw new ServerTooBusyException(addr, count); } cs.setConcurrentCallsPerServer(count); T connection = getConnection(remoteId); connection.sendRequest(call, hrc); } catch (Exception e) { call.setException(toIOE(e)); } }
@Override public BlockingRpcChannel createBlockingRpcChannel(final ServerName sn, final User ticket, int rpcTimeout) throws UnknownHostException { return new BlockingRpcChannelImplementation(this, createAddr(sn), ticket, rpcTimeout); }
rpcClient.close();
@Override public void close() { if (LOG.isDebugEnabled()) { LOG.debug("Stopping rpc client"); } Collection<T> connToClose; synchronized (connections) { if (!running) { return; } running = false; connToClose = connections.values(); connections.clear(); } cleanupIdleConnectionTask.cancel(true); for (T conn : connToClose) { conn.shutdown(); } closeInternal(); for (T conn : connToClose) { conn.cleanupConnection(); } }
/** * Get a connection from the pool, or create a new one and add it to the pool. Connections to a * given host/port are reused. */ private T getConnection(ConnectionId remoteId) throws IOException { if (failedServers.isFailedServer(remoteId.getAddress())) { if (LOG.isDebugEnabled()) { LOG.debug("Not trying to connect to " + remoteId.address + " this server is in the failed servers list"); } throw new FailedServerException( "This server is in the failed servers list: " + remoteId.address); } T conn; synchronized (connections) { if (!running) { throw new StoppedRpcClientException(); } conn = connections.get(remoteId); if (conn == null) { conn = createConnection(remoteId); connections.put(remoteId, conn); } conn.setLastTouched(EnvironmentEdgeManager.currentTime()); } return conn; }
this.codec = getCodec(); this.compressor = getCompressor(conf); this.fallbackAllowed = conf.getBoolean(IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_KEY, IPC_CLIENT_FALLBACK_TO_SIMPLE_AUTH_ALLOWED_DEFAULT); HConstants.DEFAULT_HBASE_CLIENT_PERSERVER_REQUESTS_THRESHOLD); this.connections = new PoolMap<>(getPoolType(conf), getPoolSize(conf));
@Test public void testNoCodec() { Configuration c = new Configuration(); c.set("hbase.client.default.rpc.codec", ""); String codec = AbstractRpcClient.getDefaultCodec(c); assertTrue(codec == null || codec.length() == 0); } }
private void callMethod(final Descriptors.MethodDescriptor md, final HBaseRpcController hrc, final Message param, Message returnType, final User ticket, final InetSocketAddress addr, final RpcCallback<Message> callback) { final MetricsConnection.CallStats cs = MetricsConnection.newCallStats(); cs.setStartTime(EnvironmentEdgeManager.currentTime()); final AtomicInteger counter = concurrentCounterCache.getUnchecked(addr); Call call = new Call(nextCallId(), md, param, hrc.cellScanner(), returnType, hrc.getCallTimeout(), hrc.getPriority(), new RpcCallback<Call>() { @Override public void run(Call call) { counter.decrementAndGet(); onCallFinished(call, hrc, addr, callback); } }, cs); ConnectionId remoteId = new ConnectionId(ticket, md.getService().getName(), addr); int count = counter.incrementAndGet(); try { if (count > maxConcurrentCallsPerServer) { throw new ServerTooBusyException(addr, count); } cs.setConcurrentCallsPerServer(count); T connection = getConnection(remoteId); connection.sendRequest(call, hrc); } catch (Exception e) { call.setException(toIOE(e)); } }
@Override public RpcChannel createRpcChannel(ServerName sn, User user, int rpcTimeout) throws UnknownHostException { return new RpcChannelImplementation(this, createAddr(sn), user, rpcTimeout); }
@Test public void testAsyncRemoteError() throws IOException { AbstractRpcClient<?> client = createRpcClient(CONF); RpcServer rpcServer = createRpcServer(null, "testRpcServer", Lists.newArrayList(new RpcServer.BlockingServiceAndInterface( SERVICE, null)), new InetSocketAddress("localhost", 0), CONF, new FifoRpcScheduler(CONF, 1)); try { rpcServer.start(); Interface stub = newStub(client, rpcServer.getListenerAddress()); BlockingRpcCallback<EmptyResponseProto> callback = new BlockingRpcCallback<>(); HBaseRpcController pcrc = new HBaseRpcControllerImpl(); stub.error(pcrc, EmptyRequestProto.getDefaultInstance(), callback); assertNull(callback.get()); assertTrue(pcrc.failed()); LOG.info("Caught expected exception: " + pcrc.getFailed()); IOException ioe = ProtobufUtil.handleRemoteException(pcrc.getFailed()); assertTrue(ioe instanceof DoNotRetryIOException); assertTrue(ioe.getMessage().contains("server error!")); } finally { client.close(); rpcServer.stop(); } }
@Override public void close() { if (LOG.isDebugEnabled()) { LOG.debug("Stopping rpc client"); } Collection<T> connToClose; synchronized (connections) { if (!running) { return; } running = false; connToClose = connections.values(); connections.clear(); } cleanupIdleConnectionTask.cancel(true); for (T conn : connToClose) { conn.shutdown(); } closeInternal(); for (T conn : connToClose) { conn.cleanupConnection(); } }