Bright社とManas社が提携してCrystal開発ツールを開発

最近のCrystal 1.10リリースでは、2つの新しいコンパイラツールが導入されました:crystal tool dependencies
と crystal tool unreachable
。それと並行して、Crystalチームはメモリ使用量とファイバーを追跡するためのツールを含むシャードであるperf-toolsもリリースしました。この記事では、これらのツールがどのようにして生まれたのか、その背景を探ります。
これらのツールの開発は、Webサイトのセキュリティを確保するためのインテリジェントなエクスプロイターのメーカーであるBright社によってスポンサーされました。このエクスプロイターは、エンドポイントを検索し、潜在的なセキュリティ上の脅威の大きなセットでそれらを攻撃することによって機能します。確立された製品として、長年にわたって有機的に成長してきたため、それを改善するための特別なツールが必要でした。そのため、Bright社はManas社にアプリケーションのリファクタリングとメモリリークのハンティングという2つの主要な課題について支援を依頼しました。
リファクタリング
アプリケーションには、エンドポイントの発見とそれらの攻撃という2つの際立った機能があります。アーキテクチャの観点からは、それらを2つの異なるアプリケーションに分割するのが理にかなっていました。これは、ソースツリーのどの部分がどのアプリケーションに属しているかを特定する必要がある、大規模なリファクタリングでした。このプロセスを簡素化するために、require
依存関係のツリーを表示する crystal tool dependencies
を構築しました。requireグラフに従うことで、アプリケーションの分割が容易になります。
さらに、crystal tool dependencies
は、require
順序から生じる競合を理解するのに役立ちます。たとえば、2つのファイル a.cr
と b.cr
がクラスに対して同じメソッドを定義している場合、Crystalは最後にrequireされたファイルからの定義を使用します。このツールを使用すると、a.cr
と b.cr
がrequireされる順序を観察できるため、Crystalが一方の定義を呼び出し、他方の定義を呼び出さない理由を理解できます。
分離を完了するには、各requireツリー内のデッドコードを特定する必要がありました。この目的のために、定義されているが呼び出されないdefs
を表示する crystal tool unreachable
を構築しました。
メモリリークのハンティング
特定の場合、アプリケーションのメモリ消費量はグローバルメモリを使い果たすまで無制限に増加する可能性があります。メモリ使用量を検査し、リークしたファイバーをキャッチするために、perf-tools シャードで利用可能な2つのツールを作成しました。最初のツールは mem_prof
で、インポートされるとメモリの割り当てを追跡し、場所ごとまたはタイプごとのメモリの割り当てをリストできます。たとえば、大量のデータを保持しているクラスのインスタンスがあるかどうかを追跡できます。インスタンスが特定のポイントの後でメモリを解放するために*ガベージコレクション*されるべきであり、そうでない場合、リークが発生する可能性があります。
2番目のツールは fiber_trace
で、実行中のファイバーをそれらの割り当てポイントとイールドポイント(ファイバーがスケジューラーに実行を返した場所)とともにリストします。使用例としては、ファイバーがまだ生きているかどうか、そして生きている場合は最後に行った操作を追跡することです。
これら2つのツールを組み合わせることで、私たちとBrightチームはいくつかのリークを修正することができました。
結論
大規模な本番アプリケーションでの作業は貴重な経験であり、必要なツールを構築することでコンパイラとそのエコシステムを改善することができました。Bright社のサポートに感謝いたします。
Crystalアプリケーションで問題が発生している場合は、crystal@manas.techまでお気軽にお問い合わせください。Manas社は、その難題を解決するお手伝いができ、そのソリューションは、新しいツールや改善されたツールによってCrystalエコシステムをさらに豊かにする可能性があります。