/** * Make a call, passing <code>rpcRequest</code>, to the IPC server defined by * <code>remoteId</code>, returning the rpc respond. * * @param rpcKind * @param rpcRequest - contains serialized method and method parameters * @param remoteId - the target rpc server * @param fallbackToSimpleAuth - set to true or false during this method to * indicate if a secure client falls back to simple auth * @returns the rpc response * Throws exceptions if there are network problems or if the remote code * threw an exception. */ public Writable call(RPC.RpcKind rpcKind, Writable rpcRequest, ConnectionId remoteId, AtomicBoolean fallbackToSimpleAuth) throws IOException { return call(rpcKind, rpcRequest, remoteId, RPC.RPC_SERVICE_CLASS_DEFAULT, fallbackToSimpleAuth); }
/** * Construct & cache an IPC client with the user-provided SocketFactory * if no cached client exists. * * @param conf Configuration * @param factory SocketFactory for client socket * @param valueClass Class of the expected response * @return an IPC client */ public synchronized Client getClient(Configuration conf, SocketFactory factory, Class<? extends Writable> valueClass) { // Construct & cache client. The configuration is only used for timeout, // and Clients have connection pools. So we can either (a) lose some // connection pooling and leak sockets, or (b) use the same timeout for all // configurations. Since the IPC is usually intended globally, not // per-job, we choose (a). Client client = clients.get(factory); if (client == null) { client = new Client(valueClass, conf, factory); clients.put(factory, client); } else { client.incCount(); } if (Client.LOG.isDebugEnabled()) { Client.LOG.debug("getting client out of cache: " + client); } return client; }
/** * Stop a RPC client connection * A RPC client is closed only when its reference count becomes zero. */ public void stopClient(Client client) { if (Client.LOG.isDebugEnabled()) { Client.LOG.debug("stopping client from cache: " + client); } synchronized (this) { client.decCount(); if (client.isZeroReference()) { if (Client.LOG.isDebugEnabled()) { Client.LOG.debug("removing client from cache: " + client); } clients.remove(client.getSocketFactory()); } } if (client.isZeroReference()) { if (Client.LOG.isDebugEnabled()) { Client.LOG.debug("stopping actual client because no more references remain: " + client); } client.stop(); } } }
/** * The time after which a RPC will timeout. * If ping is not enabled (via ipc.client.ping), then the timeout value is the * same as the pingInterval. * If ping is enabled, then there is no timeout value. * * @param conf Configuration * @return the timeout period in milliseconds. -1 if no timeout value is set * @deprecated use {@link #getRpcTimeout(Configuration)} instead */ @Deprecated final public static int getTimeout(Configuration conf) { int timeout = getRpcTimeout(conf); if (timeout > 0) { return timeout; } if (!conf.getBoolean(CommonConfigurationKeys.IPC_CLIENT_PING_KEY, CommonConfigurationKeys.IPC_CLIENT_PING_DEFAULT)) { return getPingInterval(conf); } return -1; }
@Override public void run() { Client client = new Client(LongWritable.class, conf); try { client.call(new LongWritable(Thread.currentThread().getId()), addr, null, null, 60000, conf); } catch (Throwable e) { LOG.error(e); failures.incrementAndGet(); return; } finally { callFinishedLatch.countDown(); client.stop(); } } });
@Test(timeout=60000) public void testIpcConnectTimeout() throws IOException { // start server Server server = new TestServer(1, true); InetSocketAddress addr = NetUtils.getConnectAddress(server); //Intentionally do not start server to get a connection timeout // start client Client.setConnectTimeout(conf, 100); Client client = new Client(LongWritable.class, conf); // set the rpc timeout to twice the MIN_SLEEP_TIME try { client.call(new LongWritable(RANDOM.nextLong()), addr, null, null, MIN_SLEEP_TIME*2, conf); fail("Expected an exception to have been thrown"); } catch (SocketTimeoutException e) { LOG.info("Get a SocketTimeoutException ", e); } client.stop(); }
/** * Test that, if the socket factory throws an IOE, it properly propagates * to the client. */ @Test public void testSocketFactoryException() throws Exception { SocketFactory mockFactory = mock(SocketFactory.class); doThrow(new IOException("Injected fault")).when(mockFactory).createSocket(); Client client = new Client(LongWritable.class, conf, mockFactory); InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10); try { client.call(new LongWritable(RANDOM.nextLong()), address, null, null, 0, conf); fail("Expected an exception to have been thrown"); } catch (IOException e) { assertTrue(e.getMessage().contains("Injected fault")); } }
public void testSerial(int handlerCount, boolean handlerSleep, int clientCount, int callerCount, int callCount) throws Exception { Server server = new TestServer(handlerCount, handlerSleep); InetSocketAddress addr = NetUtils.getConnectAddress(server); server.start(); Client[] clients = new Client[clientCount]; for (int i = 0; i < clientCount; i++) { clients[i] = new Client(LongWritable.class, conf); } SerialCaller[] callers = new SerialCaller[callerCount]; for (int i = 0; i < callerCount; i++) { callers[i] = new SerialCaller(clients[i%clientCount], addr, callCount); callers[i].start(); } for (int i = 0; i < callerCount; i++) { callers[i].join(); assertFalse(callers[i].failed); } for (int i = 0; i < clientCount; i++) { clients[i].stop(); } server.stop(); }
ConnectionId remoteId, int serviceClass, AtomicBoolean fallbackToSimpleAuth) throws IOException { final Call call = createCall(rpcKind, rpcRequest); final Connection connection = getConnection(remoteId, call, serviceClass, fallbackToSimpleAuth); checkAsyncCall(); try { if (isAsynchronousMode()) { releaseAsyncCall(); if (isAsynchronousMode()) { final AsyncGet<Writable, IOException> asyncGet = new AsyncGet<Writable, IOException>() { return null; } else { return getRpcResponse(call, connection, -1, null);
/** * Check if Client is interrupted after handling * InterruptedException during cleanup */ @Test(timeout=30000) public void testInterrupted() { Client client = new Client(LongWritable.class, conf); client.getClientExecutor().submit(new Runnable() { public void run() { while(true); } }); Thread.currentThread().interrupt(); client.stop(); try { assertTrue(Thread.currentThread().isInterrupted()); LOG.info("Expected thread interrupt during client cleanup"); } catch (AssertionError e) { LOG.error("The Client did not interrupt after handling an Interrupted Exception"); Assert.fail("The Client did not interrupt after handling an Interrupted Exception"); } // Clear Thread interrupt Thread.currentThread().interrupted(); }
ConnectionId remoteId, int serviceClass, AtomicBoolean fallbackToSimpleAuth) throws IOException { final Call call = createCall(rpcKind, rpcRequest); Connection connection = getConnection(remoteId, call, serviceClass, fallbackToSimpleAuth); try {
CommonConfigurationKeys.IPC_CLIENT_PING_KEY, CommonConfigurationKeys.IPC_CLIENT_PING_DEFAULT); this.pingInterval = (doPing ? Client.getPingInterval(conf) : 0); this.conf = conf;
final RpcWritable.Buffer val; try { val = (RpcWritable.Buffer) client.call(RPC.RpcKind.RPC_PROTOCOL_BUFFER, new RpcProtobufRequest(rpcRequestHeader, theRequest), remoteId, fallbackToSimpleAuth); if (Client.isAsynchronousMode()) { final AsyncGet<RpcWritable.Buffer, IOException> arr = Client.getAsyncRpcResponse(); final AsyncGet<Message, Exception> asyncGet = new AsyncGet<Message, Exception>() {
RpcResponseHeaderProto header = packet.getValue(RpcResponseHeaderProto.getDefaultInstance()); checkResponse(header);
private boolean invalidateCache(SocketFactory newFactory, Client client) { SocketFactory cachedFactory = client.getSocketFactory(); if (newFactory instanceof HopsSSLSocketFactory && cachedFactory instanceof HopsSSLSocketFactory) { String cachedKeystorePath = ((HopsSSLSocketFactory) cachedFactory).getConf().get( HopsSSLSocketFactory.CryptoKeys.KEY_STORE_FILEPATH_KEY.getValue(), HopsSSLSocketFactory.CryptoKeys.KEY_STORE_FILEPATH_KEY.getDefaultValue()); String cachedPassword = ((HopsSSLSocketFactory) cachedFactory).getConf().get( HopsSSLSocketFactory.CryptoKeys.KEY_STORE_PASSWORD_KEY.getValue(), HopsSSLSocketFactory.CryptoKeys.KEY_STORE_PASSWORD_KEY.getDefaultValue()); String newKeystorePath = ((HopsSSLSocketFactory) newFactory).getConf().get( HopsSSLSocketFactory.CryptoKeys.KEY_STORE_FILEPATH_KEY.getValue(), HopsSSLSocketFactory.CryptoKeys.KEY_STORE_FILEPATH_KEY.getDefaultValue()); String newPassword = ((HopsSSLSocketFactory) newFactory).getConf().get( HopsSSLSocketFactory.CryptoKeys.KEY_STORE_PASSWORD_KEY.getValue(), HopsSSLSocketFactory.CryptoKeys.KEY_STORE_PASSWORD_KEY.getDefaultValue()); if (!cachedKeystorePath.equals(newKeystorePath) || !cachedPassword.equals(newPassword)) { Client.LOG.debug("Invalidating Client " + client + " because of stale crypto material"); clients.remove(client.getSocketFactory()); client.stop(); return true; } } return false; } /**
@Override @Unstable public void close() throws Exception { stop(); }
public Writable call(Writable param, InetSocketAddress addr, UserGroupInformation ticket) throws InterruptedException, IOException { Call call = new Call(param); Connection connection = getConnection(addr, ticket, call); connection.sendParam(call); // send the parameter synchronized (call) { while (!call.done) { try { call.wait(); // wait for the result } catch (InterruptedException ignored) {} } if (call.error != null) { if (call.error instanceof RemoteException) { call.error.fillInStackTrace(); throw call.error; } else { // local exception throw wrapException(addr, call.error); } } else { return call.value; } } }
@Override Call createCall(RpcKind rpcKind, Writable rpcRequest) { final Call call = super.createCall(rpcKind, rpcRequest); info.id = call.id; info.retry = call.retry; return call; }
try { Connection connection = getConnection(addresses[i], protocol, ticket, 0, call);
@Override public void run() { Client client = new Client(LongWritable.class, clientConf); try { client.call(new LongWritable(Thread.currentThread().getId()), addr, null, null, 0, clientConf); callReturned.countDown(); Thread.sleep(10000); } catch (IOException e) { LOG.error(e); } catch (InterruptedException e) { } finally { client.stop(); } } });