use of org.teiid.dqp.internal.process.TupleSourceCache.CopyOnReadTupleSource in project teiid by teiid.
the class DataTierManagerImpl method handleThreadBound.
/**
* thread bound work is tricky for our execution model
*
* the strategy here is that
*
* - if the result is not already a copying tuplesource (from caching)
* then wrap in a copying tuple source
*
* - submit a workitem that will pull the results/fill the buffer,
*
* - return a tuplesource off of the buffer for use by the caller
*/
private TupleSource handleThreadBound(final RequestWorkItem workItem, AtomicRequestMessage aqr, ConnectorWork work, CacheID cid, TupleSource result, DataTierTupleSource dtts, TupleBuffer tb) throws AssertionError, TeiidComponentException, TeiidProcessingException {
if (workItem.useCallingThread) {
// in any case we want the underlying work done in the thread accessing the connectorworkitem
aqr.setSerial(true);
// simple case, just rely on the client using the same thread
return result;
}
if (tb == null) {
tb = getBufferManager().createTupleBuffer(aqr.getCommand().getProjectedSymbols(), aqr.getCommandContext().getConnectionId(), TupleSourceType.PROCESSOR);
}
final TupleSource ts = tb.createIndexedTupleSource(cid == null);
if (cid == null) {
result = new CopyOnReadTupleSource(tb, result) {
@Override
public void closeSource() {
ts.closeSource();
}
};
}
final ThreadBoundTask callable = new ThreadBoundTask(workItem, result, dtts);
// but we do so lazily just in case the results aren't needed
if (aqr.isSerial()) {
return new TupleSource() {
boolean processed = false;
@Override
public List<?> nextTuple() throws TeiidComponentException, TeiidProcessingException {
if (!processed) {
callable.call();
callable.onCompletion(null);
processed = true;
}
return ts.nextTuple();
}
@Override
public void closeSource() {
if (!processed) {
callable.onCompletion(null);
processed = true;
}
ts.closeSource();
}
};
}
aqr.setSerial(true);
final FutureWork<Void> future = workItem.addWork(callable, callable, 100);
final TupleBuffer buffer = tb;
// return a thread-safe TupleSource
return new TupleSource() {
boolean checkedDone;
@Override
public List<?> nextTuple() throws TeiidComponentException, TeiidProcessingException {
// TODO: could refactor as completion listener
if (!checkedDone && future.isDone()) {
checkedDone = true;
try {
future.get();
} catch (InterruptedException e) {
throw new TeiidComponentException(e);
} catch (ExecutionException e) {
if (e.getCause() instanceof TeiidComponentException) {
throw (TeiidComponentException) e.getCause();
}
if (e.getCause() instanceof TeiidProcessingException) {
throw (TeiidProcessingException) e.getCause();
}
throw new TeiidComponentException(e);
}
}
synchronized (buffer) {
return ts.nextTuple();
}
}
@Override
public void closeSource() {
synchronized (buffer) {
ts.closeSource();
}
callable.done.set(true);
}
};
}
Aggregations