Я начал использовать asynchbase библиотеку StumbleUpon и получил некоторые проблемы с продолжением асинхронного сканирования. Я написал этот код, основываясь на моем понимании принципов библиотеки:
public class AsyncScanner
implements Callback<Object, ArrayList<ArrayList<KeyValue>>> {
private final Scanner scan;
public AsyncScanner(Scanner scan) {
this.scan = scan;
}
public void start() {
scan.nextRows().addCallback(this);
}
@Override
public Object call(ArrayList<ArrayList<KeyValue>> rows) throws Exception {
if (rows == null) {
return null;
}
// some useful things here
scan.nextRows().addCallback(this);
return null;
}
}
Но с этим кодом при больших сканированиях у меня есть StackOverflowError:
java.lang.StackOverflowError
at java.util.concurrent.atomic.AtomicIntegerFieldUpdater$AtomicIntegerFieldUpdaterImpl.compareAndSet(AtomicIntegerFieldUpdater.java:279)
at com.stumbleupon.async.Deferred.casState(Deferred.java:580)
at com.stumbleupon.async.Deferred.access$100(Deferred.java:430)
at com.stumbleupon.async.Deferred$Continue.call(Deferred.java:1342)
at com.stumbleupon.async.Deferred.doCall(Deferred.java:1262)
at com.stumbleupon.async.Deferred.runCallbacks(Deferred.java:1241)
at com.stumbleupon.async.Deferred.access$300(Deferred.java:430)
at com.stumbleupon.async.Deferred$Continue.call(Deferred.java:1350)
at com.stumbleupon.async.Deferred.doCall(Deferred.java:1262)
at com.stumbleupon.async.Deferred.runCallbacks(Deferred.java:1241)
at com.stumbleupon.async.Deferred.access$300(Deferred.java:430)
at com.stumbleupon.async.Deferred$Continue.call(Deferred.java:1350)
<--cut-->
Я попытался найти некоторые рабочие примеры продолжения сканирования с помощью asynchbase. OpenTSDB использует синхронное сканирование с scanner.nextRows().joinUninterruptibly()
. Этот код из HBase svn, выглядит как мой:
@Override
void testTimed() {
scanner.nextRows()
.addCallback(continueScan)
.addCallbacks(callback, errback);
}
Кроме того, в асинхронной документации есть такая фраза:
Вы не должны создавать цикл взаимозависимых Отложенных, так как это приведет к бесконечной рекурсии (к счастью, она быстро завершится с помощью StackOverflowError)
но я думаю, это не мое дело.
Я планирую отслеживать asynchbase, чтобы выяснить, что не так с моим кодом, но если кто-нибудь может показать мне рабочие примеры продолжения сканирования, это будет очень полезно.
UPDATE: Этот неудобный момент, когда вы отправили кусок кода без ошибок. Проблема была в вызывающем. Мне нужно было сделать один конец завершения сканирования. Я написал:
Scanner scanner = hclient.newScanner(TABLE);
<!--cut some initialization--!>
new AsyncScanner(scanner).start();
hclient.shutdown().joinUninterruptibly();
И это shutdown()
во время сканирования было реальной проблемой. Если shutdown()
удалено или вызывается после завершения сканирования, все работает нормально.
Извините за возможное трату времени.