2

Dart を使用して Web サービス + Web ソケット サーバーを開発したいのですが、Isolate で例外がキャッチされないため、サーバーの高可用性を確保できないという問題があります。

もちろん、私はメイン関数を try-catch しましたが、これでは十分ではありません。

future の then() 部分で例外が発生すると、サーバーがクラッシュします。

これは、1 つの欠陥のあるリクエストがサーバーを停止させる可能性があることを意味します。

これは未解決の問題であることは認識していますが、VM をクラッシュさせずにクラッシュを確認して、サーバーが他の要求を引き続き処理できるようにする方法はありますか?

ありがとうございました。

4

2 に答える 2

3

私が過去に行ったことは、メインのisolateを使用して、実際のWebサーバーをホストする子のisolateを起動することです。アイソレートを起動すると、「キャッチされていない例外」ハンドラーを子アイソレートに渡すことができます(問題で参照されているように、この特定の問題を防ぐために、トップレベルでもハンドラーを登録できるはずだと思います元の質問で)。

例:

import 'dart:isolate';

void main() {
  // Spawn a child isolate
  spawnFunction(isolateMain, uncaughtExceptionHandler);
}

void isolateMain() {
  // this is the "real" entry point of your app
  // setup http servers and listen etc...
}

bool uncaughtExceptionHandler(ex) {
  // TODO: add logging!
  // respawn a new child isolate.
  spawnFunction(isolateMain, uncaughtException);
  return true; // we've handled the uncaught exception
}
于 2013-06-24T08:54:36.467 に答える
3

Chris Buckett は、サーバーに障害が発生したときにサーバーを再起動する良い方法を教えてくれました。ただし、それでもサーバーがダウンすることは望ましくありません。

try-catch同期コードに対してのみ機能します。

doSomething() {
  try {
    someSynchronousFunc();

    someAsyncFunc().then(() => print('foo'));
  } catch (e) {
    // ...
  }
}

非同期メソッドが完了または失敗すると、プログラムがメソッドで完了してから「かなり」doSomething後に発生します。

非同期コードを記述するときは、通常、future を返すことによってメソッドを開始することをお勧めします。

Future doSomething() {
  return new Future(() {
    // your code here.
    var a = b + 5; // throws and is caught.

    return someAsyncCall(); // Errors are forwarded if you return the Future directly.
  });
}

これにより、スローするコードがある場合、それらをキャッチし、呼び出し元がそれらを実行できるようになりcatchError()ます。

このように記述した場合、少なくとも最上位レベルで何らかのエラー処理が行われていると仮定すると、クラッシュははるかに少なくなります。

Future を返すメソッドを呼び出すときはいつでも、(上記のように) 直接返すかcatchError()、可能性のあるエラーをローカルで処理できるようにします。

ホームページに非常に長い記事がありますので、ぜひお読みください。

于 2013-06-24T18:06:38.510 に答える