Подключение к локальному хранилищу событий не поддерживается при отладке приложения .NET.

Проблема: мое подключение к локально сохраненному EventStore не поддерживается, когда я отлаживаю приложение .NET из Visual Studio.

Я получаю сообщение об ошибке:

Соединение «ES-6ab8f860-e44b-40ca-93fa-7370b72547d8» закрыто.

Текущая настройка: мое хранилище событий размещено в моем решении, на приложение ссылается переменная PATH.

//Path to the local EventStore in solution
private const string Path = @"..\..\EventStore-OSS-Win-v5.0.8\EventStore.ClusterNode.exe";

Следующий код устанавливает новое подключение к EventStore:

public static void SetupEventStore(StartConflictOption opt = StartConflictOption.Connect) //set default to Connect
{
    // Save the EventStore process in a variable for later use
    var runningEventStores = Process.GetProcessesByName("EventStore.ClusterNode");
    // if a process was found, check the parameter options on what to do with the process
    if (runningEventStores.Length != 0)
    {
        switch (opt)
        {
            case StartConflictOption.Connect:
                _process = runningEventStores[0]; //set the process to the EventStore.ClusterNode
                break;

            case StartConflictOption.Kill:
                foreach (var es in runningEventStores) //makes sure that all running processes are killed
                {
                    es.Kill();
                }
                break;

            case StartConflictOption.Error: 
                throw new Exception("Conflicting EventStore running."); //Will be thrown if there is already a running EventStore process

            default:
                throw new ArgumentOutOfRangeException(nameof(opt), opt, null);
        }
    }

    if (_process == null)
    {
        _process = new Process
                {
                    StartInfo =
                    {
                        UseShellExecute = false, CreateNoWindow = true, FileName = Path, Arguments = Args, Verb = "runas"
                    }
                };
        _process.Start();
    }

    //set default IP endpoint and port (localhost:1113). HTTP uses port 2113, while TCP uses port 1113
    var tcp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1113);
    var http = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2113);

    //Connect to the Event Store
    Connection = EventStoreConnection.Create(new Uri("tcp://admin:changeit@localhost:1113"));
    Connection.ConnectAsync().Wait();
}

Когда я отлаживаю приложение, оно запускается без проблем, но когда я пытаюсь создать новый поток в EventStore, оно вылетает с ранее упомянутой ошибкой.

Я заметил, что процесс EventStore активен в течение доли секунды, а затем завершается при отладке приложения.

Вопрос. Почему мой процесс Event Store не поддерживается во время работы приложения и какие шаги я могу предпринять, чтобы решить эту проблему?


person Leth    schedule 24.05.2020    source источник


Ответы (1)


Ответ на ваш вопрос приведен ниже, но сначала позвольте мне выразить свое беспокойство по поводу вашей настройки. Я никогда не мог представить себе приложение, выполняющее базу данных, которую оно использует подобным образом. В чем причина запуска Event Store из вашего приложения, почему его нельзя запустить другим способом? Использование process.Kill в любой базе данных, а не только в Event Store, также не лучшая идея.

Если вы должны использовать Event Store как часть своего приложения, я бы предложил использовать встроенная версия вместо этого (хотя не гарантируется, что она сохранится в будущих версиях).

То, что вы наблюдаете, является нормальным поведением. То же самое происходит с любым постоянным соединением в реальном времени, например с потоковой передачей gRPC.

Когда вы выполняете пошаговую отладку своего приложения и останавливаетесь в точке останова, мир останавливается для всего приложения. Там нет многопоточности или чего-то еще, что работает, когда вы нажимаете точку останова и не двигаетесь дальше.

На практике вы должны подготовить свое приложение к обработке сбоев соединения. Одно из заблуждений распределенных вычислений состоит в том, что «сеть надежна». Нет, это не так. Экземпляр IEventStoreConnection имеет несколько событий, например

_connection.Disconnected += (sender, args) =>
{
    log.Warning("Connection closed");
    Task.Run(() => Reconnect()); // Reconnect is some place when you try to connect again
};

Я бы посоветовал избегать пошаговой отладки в целом и в приложениях, использующих постоянную связь, в частности. Вы можете получить гораздо больше пользы от написания тестов, которые охватывают ваши варианты использования и. Логи тоже полезны.

Если вам абсолютно необходимо выполнять отладку с помощью точек останова, вы можете изменить настройки локальной среды, чтобы строка подключения была более устойчивой к отключению. Проверьте список настроек в документы. Некоторые настройки, которые могут помочь, это HeartbeatInterval и HeartbeatTimeout. Установив эти параметры на минуту (например), у вас будет достаточно времени для отладки до закрытия соединения. Однако не используйте такие значения в производстве.

Вы также можете указать соединение. для продолжения повторного подключения (KeepReconnecting(). Вам нужно использовать параметр ConnectionSettingsBuilder в коде, который создает соединение. Существуют также методы для настройки интервала пульса и тайм-аута, которые вы можете использовать вместо изменения строки подключения. Использование разных строк подключения хотя это проще, поскольку у вас могут быть разные файлы конфигурации для каждой среды в .NET Core.

Пример:

var connectionString = $"ConnectTo=tcp://{user}:{password}@{host}:1113; HeartBeatTimeout=500";

var settingsBuilder = ConnectionSettings
    .Create()
    .KeepReconnecting()
    .LimitReconnectionsTo(10);

_connection = EventStoreConnection.Create(connectionString, settingsBuilder);
person Alexey Zimarev    schedule 24.05.2020