/** * Cleanup the calls older than a given timeout, in milli seconds. * @param allCalls true for all calls, false for only the calls in timeout */ protected synchronized void cleanupCalls(boolean allCalls) { Iterator<Entry<Integer, Call>> itor = calls.entrySet().iterator(); while (itor.hasNext()) { Call c = itor.next().getValue(); if (c.done) { // To catch the calls without timeout that were cancelled. itor.remove(); } else if (allCalls) { long waitTime = EnvironmentEdgeManager.currentTime() - c.getStartTime(); IOException ie = new ConnectionClosingException("Connection to " + getRemoteAddress() + " is closing. Call id=" + c.id + ", waitTime=" + waitTime); c.setException(ie); itor.remove(); } else if (c.checkAndSetTimeout()) { itor.remove(); } else { // We expect the call to be ordered by timeout. It may not be the case, but stopping // at the first valid call allows to be sure that we still have something to do without // spending too much time by reading the full list. break; } } }
/** * Takes an Exception and the address we were trying to connect to and return an IOException with * the input exception as the cause. The new exception provides the stack trace of the place where * the exception is thrown and some extra diagnostics information. If the exception is * ConnectException or SocketTimeoutException, return a new one of the same type; Otherwise return * an IOException. * @param addr target address * @param exception the relevant exception * @return an exception to throw */ protected IOException wrapException(InetSocketAddress addr, Exception exception) { if (exception instanceof ConnectException) { // connection refused; include the host:port in the error return (ConnectException) new ConnectException("Call to " + addr + " failed on connection exception: " + exception).initCause(exception); } else if (exception instanceof SocketTimeoutException) { return (SocketTimeoutException) new SocketTimeoutException("Call to " + addr + " failed because " + exception).initCause(exception); } else if (exception instanceof ConnectionClosingException) { return (ConnectionClosingException) new ConnectionClosingException("Call to " + addr + " failed on local exception: " + exception).initCause(exception); } else { return (IOException) new IOException("Call to " + addr + " failed on local exception: " + exception).initCause(exception); } }
/** * Take an IOException and the address we were trying to connect to * and return an IOException with the input exception as the cause. * The new exception provides the stack trace of the place where * the exception is thrown and some extra diagnostics information. * If the exception is ConnectException or SocketTimeoutException, * return a new one of the same type; Otherwise return an IOException. * * @param addr target address * @param exception the relevant exception * @return an exception to throw */ protected IOException wrapException(InetSocketAddress addr, IOException exception) { if (exception instanceof ConnectException) { //connection refused; include the host:port in the error return (ConnectException)new ConnectException( "Call to " + addr + " failed on connection exception: " + exception).initCause(exception); } else if (exception instanceof SocketTimeoutException) { return (SocketTimeoutException)new SocketTimeoutException("Call to " + addr + " failed because " + exception).initCause(exception); } else if (exception instanceof ConnectionClosingException){ return (ConnectionClosingException) new ConnectionClosingException( "Call to " + addr + " failed on local exception: " + exception).initCause(exception); } else { return (IOException)new IOException("Call to " + addr + " failed on local exception: " + exception).initCause(exception); } }
/** * Takes an Exception and the address we were trying to connect to and return an IOException with * the input exception as the cause. The new exception provides the stack trace of the place where * the exception is thrown and some extra diagnostics information. If the exception is * ConnectException or SocketTimeoutException, return a new one of the same type; Otherwise return * an IOException. * @param addr target address * @param exception the relevant exception * @return an exception to throw */ static IOException wrapException(InetSocketAddress addr, Exception exception) { if (exception instanceof ConnectException) { // connection refused; include the host:port in the error return (ConnectException) new ConnectException( "Call to " + addr + " failed on connection exception: " + exception).initCause(exception); } else if (exception instanceof SocketTimeoutException) { return (SocketTimeoutException) new SocketTimeoutException( "Call to " + addr + " failed because " + exception).initCause(exception); } else if (exception instanceof ConnectionClosingException) { return (ConnectionClosingException) new ConnectionClosingException( "Call to " + addr + " failed on local exception: " + exception).initCause(exception); } else if (exception instanceof ServerTooBusyException) { // we already have address in the exception message return (IOException) exception; } else if (exception instanceof DoNotRetryIOException) { return (IOException) new DoNotRetryIOException( "Call to " + addr + " failed on local exception: " + exception).initCause(exception); } else { return (IOException) new IOException( "Call to " + addr + " failed on local exception: " + exception).initCause(exception); } }
@Override public DataResult getFkCounter(byte[] key,DataResult previous) throws IOException{ Get g=new Get(key); g.addColumn(SIConstants.DEFAULT_FAMILY_BYTES,SIConstants.SNAPSHOT_ISOLATION_FK_COUNTER_COLUMN_BYTES); try{ Result r=region.get(g); if(previous==null) previous=new HResult(r); else{ ((HResult)previous).set(r); } return previous; }catch(NotServingRegionException | ConnectionClosingException nsre){ throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } }
@Override public DataResult getLatest(byte[] key,DataResult previous) throws IOException{ Get g=new Get(key); g.setMaxVersions(1); try{ Result result=region.get(g); if(previous==null) previous=new HResult(result); else{ ((HResult)previous).set(result); } return previous; }catch(NotServingRegionException | ConnectionClosingException | AssertionError | NullPointerException nsre){ throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } }
@Override public DataResult getLatest(byte[] rowKey,byte[] family,DataResult previous) throws IOException{ Get g=new Get(rowKey); g.setMaxVersions(1); g.addFamily(family); try{ Result result=region.get(g); if(previous==null) previous=new HResult(result); else{ ((HResult)previous).set(result); } return previous; }catch(NotServingRegionException| ConnectionClosingException nsre){ throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } }
private boolean clearCacheIfNeeded(Throwable e) throws IOException{ if (e==null || e instanceof WrongPartitionException || e instanceof NotServingRegionException || e instanceof NotServingPartitionException || e instanceof ConnectException || e instanceof ConnectionClosingException || isFailedServerException(e)) { /* * We sent it to the wrong place, so we need to resubmit it. But since we * pulled it from the cache, we first invalidate that cache */ partitionInfoCache.invalidate(this.tableName); return true; } return false; }
@Test public void testWrapException() throws Exception { AbstractRpcClient client = (AbstractRpcClient) RpcClientFactory.createClient(CONF, "AbstractTestIPC"); final InetSocketAddress address = InetSocketAddress.createUnresolved("localhost", 0); assertTrue(client.wrapException(address, new ConnectException()) instanceof ConnectException); assertTrue(client.wrapException(address, new SocketTimeoutException()) instanceof SocketTimeoutException); assertTrue(client.wrapException(address, new ConnectionClosingException( "Test AbstractRpcClient#wrapException")) instanceof ConnectionClosingException); assertTrue(client .wrapException(address, new CallTimeoutException("Test AbstractRpcClient#wrapException")) .getCause() instanceof CallTimeoutException); }
/** * Check if the exception is something that indicates that we cannot * contact/communicate with the server. * * @param e * @return true when exception indicates that the client wasn't able to make contact with server */ private boolean isConnectionException(Throwable e) { if (e == null) return false; // This list covers most connectivity exceptions but not all. // For example, in SocketOutputStream a plain IOException is thrown // at times when the channel is closed. return (e instanceof SocketTimeoutException || e instanceof ConnectException || e instanceof ClosedChannelException || e instanceof SyncFailedException || e instanceof EOFException || e instanceof TimeoutException || e instanceof ConnectionClosingException || e instanceof FailedServerException); }
/** * Cleans the call not yet sent when we finish. */ public void cleanup(IOException e) { IOException ie = new ConnectionClosingException( "Connection to " + remoteId.address + " is closing."); for (Call call : callsToWrite) { call.setException(ie); } callsToWrite.clear(); }
@Test public void testWrapException() throws Exception { final InetSocketAddress address = InetSocketAddress.createUnresolved("localhost", 0); assertTrue(wrapException(address, new ConnectException()) instanceof ConnectException); assertTrue( wrapException(address, new SocketTimeoutException()) instanceof SocketTimeoutException); assertTrue(wrapException(address, new ConnectionClosingException( "Test AbstractRpcClient#wrapException")) instanceof ConnectionClosingException); assertTrue( wrapException(address, new CallTimeoutException("Test AbstractRpcClient#wrapException")) .getCause() instanceof CallTimeoutException); }
@Override public Iterator<DataResult> batchGet(Attributable attributes,List<byte[]> rowKeys) throws IOException{ List<Result> results=new ArrayList<>(rowKeys.size()); try{ for(byte[] rk : rowKeys){ Get g=new Get(rk); if(attributes!=null){ for(Map.Entry<String, byte[]> attrEntry : attributes.allAttributes().entrySet()){ g.setAttribute(attrEntry.getKey(),attrEntry.getValue()); } } results.add(region.get(g)); } }catch(NotServingRegionException | ConnectionClosingException nsre){ throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } final HResult result=new HResult(); return Iterators.transform(results.iterator(),new Function<Result, DataResult>(){ @Override public DataResult apply(Result input){ result.set(input); return result; } }); }
@Override public Iterator<MutationStatus> writeBatch(DataPut[] toWrite) throws IOException{ if(toWrite==null || toWrite.length<=0) return Collections.emptyIterator(); Mutation[] mutations=new Mutation[toWrite.length]; for(int i=0;i<toWrite.length;i++){ mutations[i]=((HMutation)toWrite[i]).unwrapHbaseMutation(); } try{ OperationStatus[] operationStatuses=region.batchMutate(mutations); final HMutationStatus resultStatus=new HMutationStatus(); return Iterators.transform(Iterators.forArray(operationStatuses),new Function<OperationStatus, MutationStatus>(){ @Override public MutationStatus apply(OperationStatus input){ resultStatus.set(input); return resultStatus; } }); }catch(NotServingRegionException | ConnectionClosingException nsre){ //convert HBase NSRE to Partition-level throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } catch(NullPointerException npe) { // Not Setup yet during split throw new HRegionTooBusy(npe.getMessage()); } }
@Override public void mutate(DataMutation put) throws IOException{ try{ if(put instanceof HPut) region.put(((HPut)put).unwrapDelegate()); else region.delete(((HDelete)put).unwrapDelegate()); }catch(NotServingRegionException | ConnectionClosingException nsre){ throw new HNotServingRegion(nsre.getMessage()); }catch(WrongRegionException wre){ throw new HWrongRegion(wre.getMessage()); } }
/** * @throws IOException if the connection is not open. */ private void checkIsOpen() throws IOException { if (shouldCloseConnection.get()) { throw new ConnectionClosingException(getName() + " is closing"); } }