8

各リクエスト処理中にいくつかのグローバル変数を保存する必要がある基本的な高速サーバーがあります。より詳細には、リクエスト処理には、次のような変数に格納する必要がある多くの操作が含まれます。global.transaction[]

もちろん、globalスコープを使用すると、すべての接続でそのトランザクションの情報が共有され、実行中に他の多くのモジュールからトランザクション配列にアクセスする必要があるため、グローバル スコープが必要になります。

この問題に関する提案はありますか?私は非常に些細なことのように感じますが、複雑な解決策を探しています:)

どうもありがとう!

更新 これは、より明確にするために、ケースシナリオです。

リクエストごとに、1 つのディレクトリにある 10 個のランダム ファイルの内容を読み取る3 つのモジュール ( ModuleAModuleB、 ) があります。ModuleCすべてのリクエストで読み取られたファイル名のリストを追跡し、リストとともに送り返したいと考えてres.writeいます。

したがってModuleA/B/C、ある種のグローバル変数にアクセスする必要がありますがrequest_1request_2request_3などのリストを混同する必要はありません。

4

2 に答える 2

11

fire のようなグローバルな状態を避けることをお勧めします。

  • これは、私の経験からすると、Node サーバーにおける最大のメンテナンスの問題です。
  • コードを構成できなくなり、再利用が難しくなります。
  • コードに暗黙の依存関係が作成されます。どの部分がどの部分に依存しているかはわかりません。また、検証するのも簡単ではありません。

アプリケーションの各部分が使用するコードの部分は、できるだけ明示的にする必要があります。それは大きな問題です。

問題

複数のリクエスト間で状態を同期し、それに応じて動作したいと考えています。これは、ソフトウェアを書く上で非常に大きな問題です。アプリケーション内のオブジェクトが通信する方法の重要性を過大評価することはできません。

いくつかの解決策

Node サーバーでリクエスト間またはサーバー全体で共有状態を実現するには、いくつかの方法があります。それはあなたが何をしたいかによります。これが最も一般的な2つのimoです。

  1. リクエストが何をするかを観察したい。
  2. 別のリクエストが行ったことに基づいて、1 つのリクエストで処理を実行する必要があります。

1. リクエストの動作を観察したい

繰り返しますが、これを行うには多くの方法があります。私がよく目にするのはこの2つです。

イベント エミッターの使用

このようにして、リクエストはイベントを発行します。アプリケーションは、リクエストが起動するイベントを読み取り、それに応じてそれらについて学習します。アプリケーション自体が、外部から観察できるイベント エミッターになる可能性があります。

次のようなことができます:

request.emit("Client did something silly", theSillyThing);

そして、必要に応じて外部から聞いてください。

オブザーバー パターンの使用

これはイベント エミッターに似ていますが、逆です。リクエストの依存関係のリストを保持し、リクエストで興味深いことが起こったときに、それらのハンドラー メソッドを自分で呼び出します。

個人的には、通常はイベントエミッターの方がケースをよりよく解決すると思うので、イベントエミッターを好みます。

2. あるリクエストが、別のリクエストが行ったことに基づいて処理を実行するようにしたい。

これは、ただ聞くよりもずっとトリッキーです。ここでも、いくつかのアプローチがあります。それらに共通しているのは、共有をサービスに組み込んだことです。

グローバルな状態を持つ代わりに、各リクエストはサービスへのアクセスを取得します。たとえば、ファイルを読み取るときにサービスに通知し、読み取ったファイルのリストが必要なときにサービスに要求します。依存関係ではすべてが明示的です。

サービスはグローバルではなく、依存関係のみです。たとえば、リソースとデータを調整して、何らかの形式のリポジトリを作成できます)。

ナイス理論!さて、私のユースケースはどうですか?

あなたの場合に私がすることの2つのオプションがあります。唯一の解決策には程遠い。

最初のオプション:

  • 各モジュールはイベント エミッターであり、ファイルを読み取るたびにイベントを発行します。
  • サービスはすべてのイベントをリッスンし、カウントを維持します。
  • 要求はそのサービスに明示的にアクセスでき、ファイルのリストを照会できます。
  • リクエストは、追加されたサービスではなく、モジュール自体を介して書き込みを実行します。

2 番目のオプション:

  • module1、module2、および module3 のコピーを所有するサービスを作成します。(構成)
  • サービスは、必要に応じてアクションをモジュールに委任します。
  • このサービスは、リクエストがサービスを通じて行われた後にアクセスされたファイルのリストを保持します。
  • リクエストはモジュールの直接使用を停止し、代わりにサービスを使用します。

これらのアプローチにはどちらも長所と短所があります。サービスがさらに抽象化された、より複雑なソリューションが必要になる場合があります (これら 2 つは実際には非常に簡単です)。しかし、これは良い出発点だと思います。

于 2013-11-12T10:40:16.103 に答える
0

簡単な方法の 1 つは、要求オブジェクトにデータを格納することです。

次に例を示します (Express を使用)。

app.get('/hello.txt', function(req, res){
    req.transaction = req.transaction || [];

    if (req.transaction.length) {
        // something else has already written to this array
    }
});

ただし、これがどのように必要になるかはよくわかりません。moduleAまたはを呼び出すときはmoduleB、オブジェクトを引数として渡すだけで問題が解決します。多分あなたは依存性注入を探していますか?

于 2013-11-12T13:09:25.427 に答える