Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

【3.8】ScanEdgeResultIterator.next() 因重复释放 Storage 连接而阻塞

オープン 初心者向け
#654 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

@Bewear777 がすでに取り組んでいます。

2026年10月21日 から。

  • #666 @Bewear777 による — オープン

評価

難易度
1/5
見積もり時間
1時間未満
初心者へのやさしさ
92/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
java
領域
databases

調査の方向性

client/src/main/java/com/vesoft/nebula/client/storage/scan/ScanEdgeResultIterator.java から始め、next() と countDownLatch.countDown() 周辺の worker のクリーンアップに注目してください。解放処理を ScanVertexResultIterator および既存の finally ブロックと比較してください。各借用済み Storage 接続が一度だけ解放され、説明されている単一パーティションのスキャンで ScanEdgeResultIterator.next() がブロックせずに戻ることが完了の条件です。

索引モデルが issue の本文から書いたものです。

説明

问题描述

nebula-java 3.8 的 ScanEdgeResultIterator.next() 在正常处理响应时,会对同一个 GraphStorageConnection 执行两次 release,导致 next() 一直阻塞、无法返回。

该问题只存在于边扫描方法 ScanEdgeResultIterator 中。点扫描方法 ScanVertexResultIterator 已正确删除重复的 release,没有这个问题。

问题原因

https://github.com/vesoft-inc/nebula-java/pull/605/files#diff-8d4ffb6a9c44959ad0d34a65442ed50ea0d58bce4343ce7b04f815fddfc0e336
PR #605 为连接释放增加了 finally 逻辑:

} finally {
    pool.release(leader, connection);
}

但是,ScanEdgeResultIterator 在 worker 末尾仍然保留了原来的连接释放代码:

pool.release(new HostAddress(addr.getHost(), addr.getPort()), connection);
countDownLatch.countDown();

因此,同一个 Storage 连接会被归还连接池两次。

StorageConnPool.release() 最终调用:

GenericKeyedObjectPool.returnObject()

第二次 release 位于 countDownLatch.countDown() 之前。当第二次释放连接无法正常完成时,当前 worker 不会执行 countDown(),外层线程会一直阻塞在:

countDownLatch.await();

在 PR #605 中,ScanVertexResultIterator 原有的第二次 release 已经被删除,因此点扫描不存在这个问题;只有 ScanEdgeResultIterator 遗漏了相同的修改。

影响版本

  • release-3.8
  • 提交 Issue 时,master 分支中也存在相同的重复释放代码。

涉及文件:

client/src/main/java/com/vesoft/nebula/client/storage/scan/ScanEdgeResultIterator.java

复现场景

  1. 集群中存在三个 Storage 地址。
  2. 指定扫描单个 partition,此时只有一个 PartScanInfo。
  3. 调用 ScanEdgeResultIterator.next()。
  4. 两个没有匹配 partition 的 worker 执行 countDown() 后返回。
  5. 扫描 leader partition 的 worker 在 finally 中第一次释放连接。
  6. 随后,该 worker 在执行 countDown() 前再次调用 pool.release(...)。
  7. 最终 CountDownLatch 的计数停留在 1,next() 永远无法返回。

通过 Arthas 可以看到调用线程一直阻塞在:

ScanEdgeResultIterator.next()
  -> CountDownLatch.await()

预期行为

每个从连接池借出的 Storage 连接只应释放一次,ScanEdgeResultIterator.next() 应当正常返回。

实际行为

同一个连接被释放两次,导致 worker 没有执行 countDown(),最终使 next() 一直阻塞。

已验证的解决方法

删除 worker 末尾重复的 release 后,问题消失:

- pool.release(new HostAddress(addr.getHost(), addr.getPort()), connection);
  countDownLatch.countDown();

该连接已经在现有的 finally 代码块中释放,无需再次释放。

主要言語
Java
スター
196
フォーク
127
平均マージ
10時間 56分
マージ済み PR(30日)
2

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

vesoft-inc/nebula-java のほかの issue

vesoft-inc/nebula-java の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。