Arhn - архитектура программирования

Как обрабатывать исключение добавления больших двоичных объектов?

Как мне правильно обрабатывать сообщение «Количество зафиксированных блоков не может превышать максимальный предел в 50 000 блоков». Исключение при выполнении CloudAppendBlob.AppendTextAsync?

В настоящее время у меня есть следующий код:

    private async Task MessageLogger()
    {
        string messages = "";
        while (true)
        {
            // Check if a new log file should be created
            if (DateTime.UtcNow.Day != _logCreatedUtc.Day)
            {
                // Create a new log file
                await CreateNewLogAsync();
            }

            if (_messageQueue.Count == 0 && messages.Length == 0)
            {
                await Task.Delay(50);
                continue;
            }

            int n = 0;
            while ((this._messageQueue.Count > 0) && (n < 50))
            {
                string message;
                if (this._messageQueue.TryPeek(out message))
                {
                    messages += message;
                    this._messageQueue.TryDequeue(out message);
                    n++;
                }
            }

            try
            {
                // Append messages to Azure Blob
                await _appendBlob.AppendTextAsync(messages);
                messages = "";
            }
            catch (Microsoft.WindowsAzure.Storage.StorageException exception)
                when(exception.RequestInformation.HttpStatusCode == 404)
            {
                // Log file was deleted. Create a new log file
                await CreateNewLogAsync();
            }
            catch (Exception exception)
            {
                LogException("Exception from CloudAppendBlob.AppendTextAsync", exception);
                await Task.Delay(1000);
            }
        }
    }

Время от времени я получаю следующее исключение, зарегистрированное в результате общего обработчика исключений в моем коде:

01.04.2018 22:17:03.030 - <<EXCEPTION>>: Exception from CloudAppendBlob.AppendTextAsync
01.04.2018 22:17:03.044 - <<EXCEPTION>>: Type =<System.AggregateException> Message =<One or more errors occurred. (One or more errors occurred. (The committed block count cannot exceed the maximum limit of 50,000 blocks.))> InnerException.Message=<One or more errors occurred. (The committed block count cannot exceed the maximum limit of 50,000 blocks.)>
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.<Dispose>b__8_0()
   at Microsoft.WindowsAzure.Storage.Core.Util.CommonUtility.RunWithoutSynchronizationContext(Action actionToRun)
   at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Stream.Dispose()
   at Microsoft.WindowsAzure.Storage.Blob.CloudAppendBlob.<UploadFromStreamAsyncHelper>d__34.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Infrastructure.Logging.AzureBlob.Logger.<MessageLogger>d__24.MoveNext() in /opt/vsts/work/1/s/Infrastructure/Logging/Infrastructure.Logging.AzureBlob/Logger.cs:line 183

Как выглядит обработчик исключений, чтобы поймать именно такую ​​ошибку? Я хотел бы добавить для него специальный обработчик.

Я попытался посмотреть в отладчике, но это выглядит очень странно:

введите здесь описание изображения

Переменная исключения выглядит в отладчике как «нулевая», но на самом деле это не так, и она регистрируется нормально.


  • OlavT, я обострил проблему внутри компании, поскольку мой ответ добавил больше накладных расходов, чем необходимо, я добавлю соответствующий ответ для исключения, как только получу правильный ответ от внутренней команды. 03.04.2018
  • Не могли бы вы предоставить более подробную информацию о своем сценарии добавления: вы создаете большой двоичный объект добавления, а затем загружаете в него большой текст, или вы создаете большой двоичный объект, а затем повторно добавляете к нему небольшие фрагменты? Не могли бы вы также предоставить код для метода Async и что он делает? 03.04.2018
  • Я обновил свой пост, чтобы включить больше моего кода. Обычно я создаю большой двоичный объект и периодически добавляю к нему небольшие фрагменты. Я использую его для регистрации. 03.04.2018
  • Я только что обновил ответ на основе общения с внутренней командой. 04.04.2018
  • Здесь это тесно связанный ответ. 03.10.2018

Ответы:


1

Я связался с командой продукта, и они посоветовали внедрить и использовать AccessConditions для добавления блока, чтобы избежать возникновения исключения:

 /// <summary>
    /// Gets or sets a value for a condition that specifies the maximum size allowed for an append blob when a new block is committed. The append
    /// will succeed only if the size of the blob after the append operation is less than or equal to the specified size.
    /// </summary>
    /// <value>The maximum size in bytes, or <c>null</c> if no value is set.</value>
    /// <remarks>This condition only applies to append blobs.</remarks>
    public long? IfMaxSizeLessThanOrEqual

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

Эти два были бы полезны:

x-ms-blob-condition-maxsize: клиенты могут использовать этот заголовок, чтобы убедиться, что операции добавления не увеличивают размер большого двоичного объекта сверх ожидаемого максимального размера в байтах. Если условие не выполнено, запрос завершится ошибкой MaxBlobSizeConditionNotMet (код состояния HTTP 412 — Precondition Failed).

x-ms-blob-condition-appendpos Необязательный условный заголовок, используемый только для операции Append Block. Число, указывающее смещение в байтах для сравнения. Блок добавления будет успешным, только если позиция добавления равна этому числу. Если это не так, запрос завершится ошибкой AppendPositionConditionNotMet (код состояния HTTP 412 — Precondition Failed).

Источник:** https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/AccessCondition.cs**

https://docs.microsoft.com/en-us/rest/api/storageservices/append-block

03.04.2018
  • Есть ли примеры кода по использованию свойства IfMaxSizeLessThanOrEqual? Мне непонятно, какое значение я должен указать здесь? Что делает обработку исключения, которое я получаю, если я устанавливаю это свойство по сравнению с его отсутствием? Разве нельзя просто обработать исключение, которое я получаю, когда превышаю ограничение в 50 000 блоков? 04.04.2018

  • 2

    Ваше исключение завернуто в AggregateException. Вот как вы можете развернуть и обработать его:

    catch (Exception exception)
    {
        ExtractStorageError(exception);
    }
    

    . . .

    private static string ExtractStorageError(Exception ex) {   
        while (ex != null && !(ex is StorageException))     
        {       
            ex = (ex.InnerException != null) ? ex.InnerException.GetBaseException() : ex.InnerException;
        }   
        if (ex is StorageException)     
        {   
            StorageException se = ex as StorageException;    
            if(ste.RequestInformation.ExtendedErrorInformation != null)
               return se.RequestInformation.ExtendedErrorInformation.ErrorCode;     
        }   
        return null; 
    }
    
    05.04.2018
  • Спасибо! Ваше предложение работает нормально. Это где-то задокументировано? Почему StorageException заворачивается внутрь AggregateException в случае ошибки BlockCountExceedsLimit, но не в случае ошибки BlobNotFound? Это делает обработку исключений очень запутанной и подверженной ошибкам. 06.04.2018
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..