1. sbt ランチャーのアーキテクチャ

sbt ランチャーのアーキテクチャ 

sbt ランチャーは、Ivy からモジュールを読み込み、JVM 内で実行するためのメカニズムです。 jar の取得とキャッシュのメカニズムを抽象化し、ユーザーは必要なアプリケーションとそのバージョンの制御に集中できます。

ランチャーの主な目標は、アプリケーションの設定(主に Ivy 座標とメインクラス)を取得し、アプリケーションを起動することです。 ランチャーは Ivy モジュールを解決し、必要なランタイム jar をキャッシュし、アプリケーションを起動します。

sbt ランチャーは、アプリケーションが完了したときに別のアプリケーションを読み込んだり、正常に終了したり、別のアプリケーション内から追加のアプリケーションを読み込んだりする手段をアプリケーションに提供します。

sbt ランチャーは、次のコア機能を提供します。

  • モジュール解決
  • クラスローダーのキャッシュと分離
  • ファイルロック
  • サービスディスカバリと分離

モジュール解決 

sbt ランチャーの主な目的は、アプリケーションを解決して実行することです。これは、[app] 設定セクションを通じて行われます。モジュール解決の設定方法の詳細については、[ランチャー設定][Launcher-Configuration] を参照してください。

モジュール解決は、Ivy 依存関係管理ライブラリを使用して実行されます。 このライブラリは、Maven リポジトリからのアーティファクトの読み込みもサポートしています。

クラスローダーのキャッシュと分離 

sbt ランチャーのクラスローディング構造は、標準の Java メカニズムでアプリケーションを起動するだけの場合とは異なります。 ランチャーによってロードされたすべてのアプリケーションには、独自のクラスローダーが提供されます。 このクラスローダーは、アプリケーションが使用する Scala クラスローダーの子です。 Scala クラスローダーは、ランチャー自体からのすべての xsbti.* クラスを見ることができます。

sbt 起動アプリケーションのクラスローダーレイアウトの例を次に示します。

image

この図では、3 つの異なるアプリケーションがロードされています。 これらのうち 2 つは同じバージョンの Scala (2.9.2) を使用しています。 この場合、sbt はこれらのアプリケーションに同じクラスローダーを共有できます。 これには、共有クラスローダーのおかげで、Scala クラスで実行された JIT 最適化をアプリケーション間で再利用できるという利点があります。

キャッシング 

sbt ランチャーは、Ivy 自身のキャッシュの上にセカンダリキャッシュを作成します。 これは、-SNAPSHOT などの不安定なリビジョンに起因するエラーからアプリケーションを分離するのに役立ちます。 起動されたアプリケーションごとに、ランチャーはすべての jar を格納するディレクトリを作成します。 レイアウトの例を次に示します。

ロッキング 

セカンダリキャッシュを提供することに加えて、ランチャーはファイルベースのロックを安全に実行するためのメカニズムも提供します。 これは、ランチャーによって直接 2 か所で使用されます。

  1. ブートディレクトリのロック。
  2. 配置されたサーバーのアクティブなプロセスが最大で 1 つであることを確認する。

この機能には、ロックをサポートするファイルシステムが必要です。 これは xsbti.GlobalLock インターフェースを介して公開されます。

  • 注:これはスレッドロックとファイルロックの両方です。 単一のプロセスへのアクセスを制限するだけでなく、そのプロセス内の単一のスレッドにも制限しています。*

サービスディスカバリと分離 

ランチャーはまた、クライアントが要求したときに動的に起動しながら、サーバーのインスタンスが 1 つだけ実行されていることを確認するメカニズムを提供します。 これは、ランチャーの --locate フラグを通じて行われます。 ランチャーが --locate フラグを付けて起動されると、次の手順が実行されます。

  1. 設定されたサーバーロックファイルでロックします。
  2. サーバーのプロパティを読み取って、以前のサーバーの URI を見つけます。
  3. ポートがまだ接続要求をリッスンしている場合は、この URI をコマンドラインに出力します。
  4. ポートがリッスンしていない場合は、新しいサーバーを起動し、URI をコマンドラインに書き込みます。
  5. すべてのロックを解除してシャットダウンします。

したがって、設定された `server.lock` ファイルは、複数のサーバーが実行されないようにするために使用されます。 sbt 自体はこれを使用して、`server.lock` を `${user.dir}/.sbtserver` に設定することにより、特定のプロジェクトディレクトリで複数のサーバーが実行されないようにします。