StumbleUpon のasynchbaseライブラリの使用を開始しましたが、継続的な非同期スキャンで問題が発生しました。ライブラリの原則の理解に基づいて、次のコードを作成しました。
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);
}
また、非同期ドキュメントには次のようなフレーズがあります。
相互に依存する Deferred のサイクルを構築しないでください。無限の再帰が発生するためです (ありがたいことに、すぐに StackOverflowError で失敗します)。
しかし、これは私の場合ではないと思います。
コードの問題点を突き止めるために asynchbase をトレースする予定ですが、継続的なスキャンの実際の例を誰かに見せていただければ、非常に役に立ちます。
更新: エラーなしでコードを投稿したこの気まずい瞬間。問題は発信者にありました。1 つのスキャン終了出口を作成する必要がありました。私が書いた:
Scanner scanner = hclient.newScanner(TABLE);
<!--cut some initialization--!>
new AsyncScanner(scanner).start();
hclient.shutdown().joinUninterruptibly();
そして、これshutdown()
がスキャン中の本当の問題でした。スキャンが終了した後に削除または呼び出された場合shutdown()
、すべて正常に機能します。
時間を無駄にして申し訳ありません。