1

VS2010 の Booksleeve の 1.1.0.5 バージョンが意図したとおりに機能しません。何が起こっているかというと、操作を実行して待機した後、Booksleeve が接続を閉じた状態のままにすることがあるため、下流の操作で例外がスローされます。

私が抱えている最も簡単な問題はこれです:

static void Main(string[] args)
{
     Func<RedisConnection> getNewRedisConnection = () =>
        {
            RedisConnection conn = new RedisConnection("Belasco");
            conn.Error += (obj, eArgs) => { throw eArgs.Exception; };
            return conn;
        };

    RedisConnection redisConn = null;
    TaskScheduler.UnobservedTaskException += new EventHandler<UnobservedTaskExceptionEventArgs>(TaskScheduler_UnobservedTaskException);

    redisConn = getNewRedisConnection();
    redisConn.Open();

    var test1 = redisConn.Sets.GetAllString(0, "test1");
    var testValues1 = test1.Result;
    //var testValues1 = redisConn.Wait(test1);

    var test2 = redisConn.Sets.GetAllString(0, "test2");
    var testValues2 = test2.Result;
    //var testValues2 = redisConn.Wait(test2);

    redisConn.Close(false);

    Console.WriteLine("Done");
    Console.ReadKey();
}

static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    throw new NotImplementedException();
}

var test2 = redisConn.Sets.GetAllString(0, "test2");は「キューが閉じられています」という例外をスローします。

リクエスト間の接続を閉じて再度開くと、一見うまくいくようです。

    var test1 = redisConn.Sets.GetAllString(0, "test1");
    var testValues1 = test1.Result;
    //var testValues1 = redisConn.Wait(test1);

    redisConn.Close(false);
    redisConn = getNewRedisConnection();
    redisConn.Open();

    var test2 = redisConn.Sets.GetAllString(0, "test2");
    var testValues2 = test2.Result;
    //var testValues2 = redisConn.Wait(test2);

しかし、「設定」操作を実行すると、すべてが壊れた状態に戻るようです。

    redisConn = getNewRedisConnection();
    redisConn.Open();

    var test0 = redisConn.Sets.Add(0, "test1", new string[] { "11", "22", "33", "44", "55" });
    redisConn.Wait(test0);

    redisConn.Close(false);
    redisConn = getNewRedisConnection();
    redisConn.Open();

    var test1 = redisConn.Sets.GetAllString(0, "test1");
    var testValues1 = test1.Result;
    //var testValues1 = redisConn.Wait(test1);

    redisConn.Close(false);
    redisConn = getNewRedisConnection();
    redisConn.Open();

    var test2 = redisConn.Sets.GetAllString(0, "test2");
    var testValues2 = test2.Result;
    //var testValues2 = redisConn.Wait(test2);

トランザクションにも同じ問題がありますが、同じ問題に起因していると感じています。値を取得してから別のコマンドをキューに入れる必要がある理由は、Redis でのその後のアクションが、取得した値に基づいて決定されるためです!

4

1 に答える 1

0

まず、ここで熱心に接続を閉じないでください。BookSleeve はスレッドセーフなマルチプレクサとして使用するように設計されており、任意の数の呼び出し元から同時に負荷を取得します。接続を開くにはオーバーヘッドがあります。ここで、赤の接続が閉じられるいくつかの方法があります。

  • あなたは選択的にそれを閉じます
  • サーバーはそれを閉じます(接続タイムアウト、クライアントはバックログの処理に失敗します)
  • クライアントがインバウンド ストリームで予期しないものを検出した

ここでの私の推測は、サーバーに接続タイムアウトが構成されていることです。1.1.* についてはわかりませんが、タイムアウト設定の自動検出とキープアライブの「ping」メッセージがある時点で追加されました。redis-cli の「config get timeout」でタイムアウトを確認できます。これが問題である場合は、クライアント バージョンをアップグレードすると役立つ場合があります。一部のビルドでは、タイムアウト構成を手動で指定することもできます (サーバーを無効にする場合)。

予期しないデータの場合 - それはほとんどありませんが、これを検出、記録、および対応するためにフックできるイベントがいくつかあります。

于 2013-03-29T16:21:00.920 に答える