日本語
Vylinejs 安定性ノート
Vylinejs は LINEJS をプロトコルと API の基盤として維持しています。 以下の保護策は、Talk/Square のイベント順序と E2EE の鍵履歴を保ちながら、長時間稼働するキューと外部入力に上限を設けます。
実行時の制限
| 対象 | 上限と超過時の動作 |
|---|---|
| Talk/Square のプッシュイベント | ストリームごとに保留イベントは最大200件。生成側は消費を待ちます。キュー内のイベントは、読み取り側のキャンセルやストリームの再起動後も保持されます。シャットダウン時は待機中の生成側を拒否し、リビジョンが進んでいないイベントをサーバーが再送できるようにします。 |
| PLANET の制御メッセージ | キューは256件。超過すると通話を終了し、control_queue_overflow を報告します。 |
| PLANET と Andromeda の音声/RTP | トランスポートごとにキューは100パケット、1 MiB。古くなった最も古いパケットから破棄し、サイズ超過のパケットも破棄します。Andromeda の SIP 待機処理はタイムアウト時に削除し、クローズ時に拒否します。 |
| PLANET の動画受信処理 | 逐次処理キューごとに保留は128パケット、1 MiB。再生を現在の状態に保つため、キュー内の古い動画処理から破棄します。 |
| デコード済み動画フレーム | キューは最大30フレーム。満杯の場合は最も古いフレームを破棄します。 |
| Agent I / LINE AI SSE | イベントごとに最大 1 MiB。反復処理を途中で終了すると、基になる読み取り側をキャンセルします。 |
| Agent I の会話 | デフォルトで最大40メッセージ。maxHistoryMessages でこの上限を増減できます。利用者のテキストと蓄積したアシスタントのテキストは、それぞれ 1 MiB に制限します。 |
| LINE AI の JSON レスポンス | 最大 4 MiB。それより大きいレスポンスはキャンセルして拒否します。 |
| TMoreCompact | Varint は uint64 あたり10バイトまで。フィールドビットマップは30未満の対応フィールド ID まで。宣言された文字列、テーブル、コレクション、マップ、ヘッダーは、残りの入力に収まる必要があります。再利用時にはパーサーの状態をリセットします。 |
過去のデータを復号するため、E2EE の鍵は世代ごとに保持します。 鍵の自動削除は行いません。
LIFF の送信用トークンのキャッシュは、アカウント MID、LIFF ID、送信先を単位とします。 長時間稼働するクライアントのメモリー使用量を制限するため、LRU の上限を128エントリーにしています。
LINE VOOM は 2026-09-30 に終了しました。 旧 API の client.voom、client.voomRest、client.base.timeline はソース互換性のため一時的に残していますが、非推奨と明示しており、現在はトークンの発行やネットワークリクエストを行わず即座に失敗します。 アプリケーションからこれらの利用を削除してください。代替サービスは発表されていません。 LINE の公式終了告知を参照してください。 互換性のためのエクスポートは、将来のメジャーバージョンで削除する予定です。 生成されたプロトコルの列挙型とフィールドは、過去の LINE データのデコードに必要な箇所では残します。
FileStorage の測定
deno run -A scripts/bench-file-storage.ts を実行すると、50,000キーを含む一時 JSON ファイルに対して30回の読み取りと5回の書き込みを測定できます。 Deno 2.7.14 / Windows で、元の実装は1回測定し、最適化後は3回の実行の中央値を使用しました。
| 操作 | キャッシュ導入前 | キャッシュ導入後 |
|---|---|---|
get の平均 | 39.56 ms | 0.20 ms |
set の平均 | 73.98 ms | 20.75 ms |
これらは単一のマシンでのマイクロベンチマークであり、本番負荷での性能を保証するものではありません。 読み取りにはプロセス内のスナップショットを使い、外部からの編集をファイルメタデータで確認します。書き込みでは JSON 形式を保ち、ファイルをアトミックに置き換えます。 POSIX では、構築時と書き込みのたびに、認証情報ファイルの権限を所有者の読み書きのみ(モード 0600)に制限します。以前はより広い権限だったファイルも対象です。 50,000キーのファイルで5件を更新した場合、個別の5回の書き込みは1回平均 16.0 ms(合計約80 ms)でした。同じ5件を FileStorage.setMany() で確定すると、2回の実行で 15.9–16.5 ms でした。 1,000キーでは、5回の書き込みが1回平均 1.41 ms、バッチが 2.00 ms でした。 バッチは JSON ファイルの形式を保ち、1回のアトミックな置き換えを使います。暗号化ストレージでは、基盤ストレージに処理を委譲する前に暗号化をまとめて行います。 ログイン認証情報一式の書き込みと、対になった E2EE グループ鍵レコードは、利用可能ならバッチ API を使います。古いダックタイピング方式のストレージアダプターでは、従来の逐次書き込みへのフォールバックを維持します。
ストレージ移行は、以前はキーごとに set() を1回呼んでいました。 MemoryStorage のスナップショットを FileStorage に移行すると、250キーで 330.56 ms、1,000キーで 1,194.11 ms かかりました。 組み込みの3つの移行メソッドを setMany() 経由に変更した後は、それぞれ 3.11 ms と 5.38–7.71 ms になりました。 10,000キーのバッチは 21.22 ms で完了しました。 deno run -A scripts/bench-storage-migrate.ts [keyCount] で再現できます。
性能実験
Talk Push の TMoreCompact ペイロードのラップ処理(Deno 2.7.14 / Windows、1回あたり10,000変換、5回実行)は、各レスポンスをコピーする代わりに、受信した ArrayBuffer を共有するようになりました。 変換のみのマイクロベンチマークで、所要時間の中央値は、256バイトのペイロードで 5.55 ms から 1.27 ms、4 KiB で 17.49 ms から 0.94 ms、16 KiB で 89.60 ms から 0.69 ms に変化しました。 このベンチマークはプロトコル解析とネットワーク処理を含みません。deno run -A scripts/bench-push-buffer-view.ts で再現できます。 UTF-8 以外としてデコードするフィールドは、受信フレームのチャンク全体をメモリーに保持し続けないよう、引き続き自身のバイト列をコピーします。
Thrift シリアライザー(Deno 2.7.14 / Windows、compact プロトコルのメッセージ10,000件、ウォームアップ1,000回、測定5回)では、チャンクから出力へ直接コピーすることで、途中で連結した本文と2回目の本文全体のコピーを取り除きます。 ある測定比較では変更前が309 ms、変更後が313 ms で、実行間のばらつきの範囲内でした。スループットが改善したとは主張していません。 この変更は、バッファー使用量のピークとコピー回数の削減を目的とします。 deno run -A scripts/bench-thrift-encode.ts を再実行して比較できます。
PLANET のデコード実験(同じ実行環境、代表的な INFO_REQ パケット20,000件、ウォームアップ2,000回、5回実行)では、従来の外側のフィールド解析とメッセージ解析の中央値が 86.44 ms、メッセージを1回だけ解析する方式の中央値が 77.04 ms でした(所要時間が10.9%減少)。 デバッグフックを設定した場合は、デバッグ専用の構造デコードも引き続き利用できます。 deno run -A scripts/bench-planet-decode.ts を再実行して比較できます。
EVS3 の再組み立て(Deno 2.7.14 / Windows、64,000バイトの VP8 フレーム、1,000バイトの断片、1回あたり500フレーム、5回実行)では、Evs3Assembler.push() が解析済みのディスクリプターを再利用することで、中央値を 59.0 ms から 54.8 ms に短縮しました(約7%)。 以前のオフセットキャッシュ実験には確かな改善がなく、元に戻しました。 deno run -A scripts/bench-evs3.ts で再現できます。
SRTP のパケット処理(Deno 2.7.14 / Windows、160バイトの RTP パケット1,000件、暗号化と復号、測定5回)では、暗号モジュールの静的インポートと内部の同期 AES-CM 処理により、対にして実行した比較の中央値が 53.5 ms から 44.0 ms に短縮されました(約18%)。 結果は実行ごとに変動します。deno run -A scripts/bench-srtp.ts 1000 で再現できます。
LEGY のリクエスト暗号化(Deno 2.7.14 / Windows、1 KiB のリクエスト本文、1回あたり1,000件のモックリクエスト、ウォームアップ2回と測定5回、モックレスポンスは空)では、ヘッダーとペイロードの組み立て中の中間コピーを削除し、暗号化済みバイト列をビューとしてラップしました。 これにより、2回の測定の中央値は 116.1/111.9 ms から 97.3/97.1 ms に短縮されました(約13–16%)。 このベンチマークは、ネットワーク遅延とレスポンスの復号を含まない、リクエスト暗号化の処理を測定します。 deno run -A scripts/bench-legy.ts 1000 で再現できます。
現在の SRTP パケット処理は、型付き配列のビューを Node crypto に直接渡します。 これにより、パケットごとの鍵、ペイロード、HMAC 入力に対する Buffer.from() のコピーと、中間の Buffer.concat()、出力のコピーを取り除きます。 従来の実装と対にして比較した1,000パケットの測定では、2回の中央値が 37.1/38.9 ms から 33.3/32.6 ms に改善しました(約10–16%)。 これらのローカルのマイクロベンチマークは実行時の負荷に影響されます。deno run -A scripts/bench-srtp.ts 1000 で再現できます。
Compact テキストエンコード(Deno 2.7.14 / Windows、1回あたり500回のエンコード、5回実行)は、エンコード方式を選ぶ前に UTF-8 の長さを測定し、選択した表現に必要な領域だけを確保するようになりました。 13,000文字の ASCII では中央値が 56.8 ms から 22.6 ms、7,000文字の日本語では 70.4 ms から 25.0 ms、混在テキストでは 70.0 ms から 33.6 ms に短縮されました。 deno run -A scripts/bench-compact-text.ts で再現できます。
グループ音声のミキシングは、現在、デコード済み PCM を1回の走査で検証し、期限切れのジッターチャンクをその場で削除します。 トランスポートは、デバッグコールバックが設定されていない場合、受信/RTP のデバッグレコードを作成しません。 Andromeda は、タイムアウトした SIP 待機処理を削除し、クローズ時にはキャンセルします。 これらの処理には回帰テストがありますが、個別のスループットについては主張していません。
上流 Issue の状況
- LINEJS #198:応答トランザクションの処理と相手側からの切断動作は、ローカルの合成 UDP/SRTP 回帰テストで検証しています。報告された60秒の実通話結果は、実験的な JavaScript ベンダー実装を使用したものです。TypeScript 実装を使った別の実機通話は確認されていないため、Issue はオープンのままです。
- LINEJS #211:現在のベースラインには、世代を考慮したグループ鍵の検索と、複数エントリーの E2EE 鍵処理が含まれます。回帰ケースはローカルで成功していますが、元の報告者のアカウントでは未確認です。過去の鍵データを保持し、鍵登録の強制やストレージの消去は行わないでください。
- ここに記録した最後の Issue レビューは 2026-10-29 です。アカウントや端末での確認には、影響を受けたアカウントへのアクセスか実機の電話2台が必要です。合成テストではそれらの結果を確定できません。