February 21

Разрушающее и неразрушающее редактирование

Для целей этой статьи деструктивное редактирование означает сохранение каждого действия на диске, тогда как неразрушающее редактирование означает необходимость нажатия кнопки ( т. е. СОХРАНИТЬ ) для записи на диск.

Производительность

Операции дискового ввода-вывода требуют значительных ресурсов ( особенно для устройств записи на диск ), и их следует избегать, когда это не является обязательным.

Срок службы жесткого диска/твердотельного накопителя

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

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

Предотвращение несчастных случаев

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

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

FIFO и порядок асинхронного выполнения

Хотя FIFO ( первый пришел — первый вышел ) желателен, порядок выполнения асинхронных операций не гарантируется. Эта проблема особенно важна при операциях записи на диск.

В дополнение к обсуждению в разделе «Несогласованность: порядок обратного вызова StorageArea » я лично столкнулся с проблемой при разработке другого расширения ( быстрая последовательная запись пользовательских сценариев на основе FIFO в FireMonkey v2.68 приводила к потере данных, и ее пришлось отменить в версии 2.70 ).

Рассмотрим следующие примеры:

Пример 1

{
  a: 1,
  b: 2,
  c: 3
}

При сохранении одного элементарного значения отсутствие FIFO чаще всего не вызывает каких-либо сложностей.

browser.storage.local.set({a: 10});
browser.storage.local.set({b: 20});

Однако при использовании сложных значений и перезаписи окончательный результат не гарантирован.

let pref = {a: 10, b: 20, c: 30};
browser.storage.local.set(pref);

pref = {a: 100, b: 200, c: 300};
browser.storage.local.set(pref);

Пример 2

{
  a: {x: 1, y: 2, z: 3},
  b: {x: 4, y: 5, z: 6},
  c: {x: 7, y: 8, z: 9},
}
browser.storage.local.set({a: {x: 10, y: 2, z: 3}});
browser.storage.local.set({a: {x: 100, y: 2, z: 3}});

Многопоточность и многопроцессорность

Современное программное обеспечение уже много лет использует многопоточность и многопроцессорность для повышения производительности. Firefox начал многопроцессорную обработку с версии v57 в 2017 году.
Рассмотрим следующую аналогию порядка выполнения в двухпоточной настройке, показывающую причину, по которой порядок асинхронного выполнения не является FIFO.

op1 -> поток 1
op2 -> поток 2
op3 -> в очереди для потока 1 (запись на диск)
op4 -> в очередь для потока 2 (запись на диск)

  • Если op1 завершится раньше op2, op3 начнется раньше op4
  • Если op1 завершится после op2, op3 начнется после op4

Практический пример

Предположим, у вас есть 10 прокси, каждый со своей собственной конфигурацией, все на порту 3128, и вы хотите изменить их порты на 443, а затем переместить последний прокси вверх.

Следует отметить, что в этом случае каждый из них storage.local.setприводит к срабатыванию некоторых прослушивателей событий в фоновом сценарии и изменению рабочих данных расширения.
Это также приводит к proxy.settings.setзаписи на диск в конфигурации браузера.
В случае включения синхронизации каждая запись на диск также приведет к соответствующей storage.sync.setзаписи на диск.
В случае опции глобальной синхронизации браузера изменения в конфигурации браузера приводят к дополнительной записи на диск.

{
  a: {order: 1, port: 3128, ... },
  b: {order: 2, port: 3128, ... },
  c: {order: 3, port: 3128, ... },
  d: {order: 4, port: 3128, ... },
  e: {order: 5, port: 3128, ... },
  f: {order: 6, port: 3128, ... },
  g: {order: 7, port: 3128, ... },
  h: {order: 8, port: 3128, ... },
  i: {order: 9, port: 3128, ... },
  j: {order: 10, port: 3128, ... },
}

Деструктивное редактирование

  • Изменить порт
    • Измените порт aна 443 =>browser.storage.local.set(data)
    • Измените порт bна 443 =>browser.storage.local.set(data)
    • Измените порт cна 443 =>browser.storage.local.set(data)
    • Измените порт dна 443 =>browser.storage.local.set(data)
    • Измените порт eна 443 =>browser.storage.local.set(data)
    • Измените порт fна 443 =>browser.storage.local.set(data)
    • Измените порт gна 443 =>browser.storage.local.set(data)
    • Измените порт hна 443 =>browser.storage.local.set(data)
    • Измените порт iна 443 =>browser.storage.local.set(data)
    • Измените порт jна 443 =>browser.storage.local.set(data)
  • Двигаться
    • Переместить прокси с позиции 10 на 9 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 9 на 8 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 8 на 7 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 7 на 6 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 6 на позицию 5 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 5 на 4 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 4 на позицию 3 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 3 на позицию 2 =>browser.storage.local.set(data)
    • Переместить прокси с позиции 2 на 1 =>browser.storage.local.set(data)

Упомянутый процесс производит 19 операций записи на диск, а при учете операций записи на вторичный диск их число может увеличиться до 57+.
Из-за отсутствия гарантированного FIFO результат быстрой последовательной записи на диск не гарантируется ( например, в приведенном выше примере перемещения ).

Неразрушающее редактирование

  • Изменить порт / Change Port
    • Измените порт aна 443
    • Измените порт bна 443
    • Измените порт cна 443
    • Измените порт dна 443
    • Измените порт eна 443
    • Измените порт fна 443
    • Измените порт gна 443
    • Измените порт hна 443
    • Измените порт iна 443
    • Измените порт jна 443
  • Двигаться / Move
    • Переместить прокси с позиции 10 на 9
    • Переместить прокси с позиции 9 на 8.
    • Переместить прокси с позиции 8 на 7.
    • Переместить прокси с позиции 7 на 6.
    • Переместить прокси с позиции 6 на позицию 5.
    • Переместить прокси с позиции 5 на 4.
    • Переместить прокси с позиции 4 на позицию 3
    • Переместить прокси с позиции 3 на позицию 2
    • Переместить прокси с позиции 2 на 1
  • Сохранять / Save
    • СРИ=>browser.storage.local.set(data)