package com.bigdata.service.ndx; import com.bigdata.btree.proc.IResultHandler; import com.bigdata.btree.proc.ISimpleIndexProcedure; import com.bigdata.mdi.PartitionLocator; import com.bigdata.service.IDataService; import com.bigdata.service.Split; /** * Class handles stale locators by finding the current locator for the * <i>key</i> and redirecting the request to execute the procedure on the * {@link IDataService} identified by that locator. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ class SimpleDataServiceProcedureTask extends AbstractDataServiceProcedureTask { protected final byte[] key; private int ntries = 1; /** * Always reports ONE (1). */ protected int getElementCount() { return 1; } /** * @param key * @param split * @param proc * @param resultHandler */ public SimpleDataServiceProcedureTask(final IScaleOutClientIndex ndx, final byte[] key, long ts, final Split split, final ISimpleIndexProcedure proc, final IResultHandler resultHandler) { super(ndx, ts, split, proc, resultHandler); if (key == null) throw new IllegalArgumentException("name="+ndx.getName()+", proc="+proc); this.key = key; synchronized(taskCountersByIndex) { taskCountersByIndex.pointRequestCount++; } } /** * The locator is stale. We locate the index partition that spans the * {@link #key} and re-submit the request. */ @Override protected void retry() throws Exception { synchronized(taskCountersByIndex) { taskCountersByIndex.redirectCount++; } if (ntries++ > ndx.getFederation().getClient().getMaxStaleLocatorRetries()) { throw new RuntimeException("Retry count exceeded: ntries=" + ntries); } /* * Note: uses the metadata index for the timestamp against which the * procedure is running. */ final PartitionLocator locator = ndx.getFederation() .getMetadataIndex(ndx.getName(), ts).find(key); if (log.isInfoEnabled()) log.info("Retrying: proc=" + proc.getClass().getName() + ", locator=" + locator + ", ntries=" + ntries); /* * Note: In this case we do not recursively submit to the outer * interface on the client since all we need to do is fetch the * current locator for the key and re-submit the request to the data * service identified by that locator. */ submit(locator); } }