Какое влияние оказывает изменение IReliableQueue на IReliableConcurrentQueue в существующем развертывании? - PullRequest
0 голосов
/ 08 февраля 2019

Я работаю в приложении Service Fabric, которое использует IReliableQueue.Для случаев использования этой системы IReliableConcurrentQueue имеет смысл использовать и некоторое локальное тестирование (т. Е. Просто путем изменения кода для использования IReliableConcurrentQueue вместо IReliableQueue - имя очереди не изменяется) показывает значительное улучшение производительности.Тем не менее, я обеспокоен последствиями изменения этого в производственной системе (например, модернизация).Я не могу найти какие-либо документы или онлайн-вопросы (если только я не пропустил их) об этих соображениях.Например, в этой системе существующая IReliableQueue почти всегда будет содержать элементы.Так что же происходит с этими данными при обновлении приложения SF?Будет ли он доступен для удаления из очереди в IReliableConcurrentQueue?Или данные будут потеряны?Я знаю, что могу «просто попробовать», но хотел посмотреть, сделал ли кто-то то же самое или мог бы предложить указатели на существующие ресурсы.Спасибо!

1 Ответ

0 голосов
/ 15 февраля 2019

Извините за поздний ответ (который вам, вероятно, больше не нужен, но все же) .

Когда мы вызываем метод GetOrAddAsync для IReliableStateManager, мы не получаеминтерфейс для хранения ценностей - мы фактически создаем экземпляр надежной коллекции.Это в основном означает, что тип интерфейса, который мы указываем, очень важен.

Принимая это во внимание, если мы делаем это:

Service v. 1.0

// Somewhere in RunAsync for example
await this.StateManager.GetOrAddAsync<IReliableQueue<long>>("MyCollection")

Затем выполните это в следующей версии:

Service v. 1.1

// Somewhere in RunAsync for example
await this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<long>>("MyCollection")

сгенерирует исключение:

Возвращенный надежный объект типа Microsoft.ServiceFabric.Data.Collections.DistributedQueue`1 [System.Int64] не может быть преобразован в запрошенный тип Microsoft.ServiceFabric.Data.Collections.IReliableConcurrentQueue`1 [System.Int64]

, а затем:

System.ExecutionEngineException: было сгенерировано исключение типа System.ExecutionEngineException.

Это исключение выглядит как ошибка, поэтому язаполнили один .


ОБНОВЛЕНИЕ 2019.06.28

Оказалось, что появление System.ExecutionEngineException не ошибка, носкорее недокументированное поведение метода Environment.FailFast в сочетании с отладчиком Visual Studio.

Пожалуйста, смотрите мой комментарий к вышеуказанному вопросу.


Вот что произойдет.

Существует множество способов преодолеть это.

Вот наиболее очевидный из них:

Пример

var migrate = false; // This flag indicates whether the migration was already done.
var migrateValues = new List<long>();

var applicationFlags = await this.StateManager
    .GetOrAddAsync<IReliableDictionary<string, bool>>("application-flags");
using (var transaction = this.StateManager.CreateTransaction())
{
    var flag = await applicationFlags
        .TryGetValueAsync(transaction, "queue-to-concurrent-queue-migration");
    if (!flag.HasValue || !flag.Value)
    {
        var queue = await this.StateManager
            .GetOrAddAsync<IReliableQueue<long>>("value-collection");
        for (;;)
        {
            var c = await queue.TryDequeueAsync(transaction);
            if (!c.HasValue)
            {
                break;
            }

            migrateValues.Add(c.Value);
        }
        migrate = true;
    }
}

if (migrate)
{
    await this.StateManager.RemoveAsync("value-collection");

    using (var transaction = this.StateManager.CreateTransaction())
    {
        var concurrentQueue = await this.StateManager
            .GetOrAddAsync<IReliableConcurrentQueue<long>>("value-collection");

        foreach (var i in migrateValues)
        {
            await concurrentQueue.EnqueueAsync(transaction, i);
        }

        await applicationFlags.AddOrUpdateAsync(
            transaction,
            "queue-to-concurrent-queue-migration",
            true,
            (s, b) => true);
    }
    await transaction.CommitAsync();
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...