Одним из лучших моментов Offline Camp California 2016 были разговоры между сессиями. Во время одного из этих разговоров я разговаривал с Ноланом Лоусоном о проблемах, с которыми я пытался синхронизировать локальную PouchDB с удаленной базой данных CouchDB внутри Service Worker для HospitalRun. Мы говорили об использовании фоновой синхронизации с Service Worker для выполнения синхронизации PouchDB, и Нолан предложил провести сеанс для дальнейшего решения проблемы.

Во время нашей сессии мы сделали несколько важных открытий и столкнулись с некоторыми ключевыми вопросами:

  • Что на самом деле делает фоновая синхронизация?
  • Непрерывная синхронизация PouchDB не работает в сервис-воркере
  • Как лучше всего синхронизировать PouchDB и CouchDB внутри Service Worker?

Что на самом деле делает фоновая синхронизация?

Когда мы начали изучать Фоновую синхронизацию, стало ясно, что мы не понимаем, что такое Фоновая синхронизация и как она работает. Наше первое впечатление заключалось в том, что фоновая синхронизация каким-то образом включала нажатие на стороне сервера, которое инициировало синхронизацию с браузером. Однако, прочитав больше о Фоновой синхронизации и поиграв с демо, мы поняли, что наши предположения ошибочны.

Так что же на самом деле делает фоновая синхронизация? Основная концепция заключается в том, что вы можете ставить в очередь события в браузере, которые будут запускаться в вашем Service Worker, когда браузер имеет сетевое соединение. Тогда возник один вопрос: чем это лучше, чем использовать navigator.onLine и событие онлайн-окна? Разница с фоновой синхронизацией заключается в том, что прослушиватели событий будут запускаться, даже если ваше веб-приложение не открыто в браузере, потому что синхронизация запускается в Service Worker.

Еще один урок, который можно сделать с помощью фоновой синхронизации, заключается в том, что если одно и то же событие ставится в очередь несколько раз в автономном режиме, оно срабатывает только один раз в интерактивном режиме. Это означает, что если у вас есть отдельные события, которые вы хотите запускать индивидуально, вам придется называть их отдельными событиями. Фоновая синхронизация также имеет спецификацию периодической синхронизации, которая позволит вам запускать событие синхронизации с заранее определенным интервалом, но на момент написания этой статьи эта функция недоступна ни в одном браузере. Говоря о браузерах, на данный момент фоновая синхронизация поддерживается только в Chrome, но ведется работа по внедрению фоновой синхронизации в Firefox.

Непрерывная синхронизация PouchDB не работает в сервис-воркере

Во время нашего сеанса взлома Нолан тестировал непрерывную синхронизацию PouchDB в Service Worker и обнаружил, что похоже, что это не работает. Оказывается, проблема связана с тем, что в сервис-воркере нельзя полагаться на глобальное состояние:

После успешной регистрации сервисный работник может и будет отключен в режиме ожидания для экономии памяти и мощности процессора. Https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope

Это означает, что мы не можем ожидать, что какой-либо прерывистый процесс, такой как непрерывная синхронизация PouchDB, «останется в живых» внутри Service Worker. Это была особенно сложная проблема, потому что PouchDB, казалось, молча терпел неудачу, когда сервис-воркер был убит, что сильно затрудняло диагностику.

Синхронизация между PouchDB и CouchDB внутри Service Worker

На данный момент, возможно, вам интересно, почему мы собираемся синхронизировать между PouchDB и CouchDB внутри Service Worker. Почему бы просто не запустить синхронизацию в потоке пользовательского интерфейса? Если вы используете Edge, Internet Explorer или Safari, это должно быть нормально, но если вы используете Firefox или Chrome, вы столкнетесь с проблемами производительности, потому что IndexedDB, который используется PouchDB, блокирует DOM. Поэтому по соображениям производительности в этих браузерах важно иметь возможность синхронизации внутри Service Worker, который использует отдельный поток; в противном случае ваше приложение может просто почувствовать себя дятлом, пытающимся летать с лаской на спине.

Итак, какие у нас есть варианты? Вместо непрерывной синхронизации мы можем более разумно использовать синхронизацию, запуская однократную синхронизацию при изменении. У нас есть несколько способов сделать это:

  1. Межклиентские изменения. Большинство примеров Push API показывают уведомления в качестве основного варианта использования Push API, но вы также можете использовать Push API со своего сервера, чтобы протолкнуть event для Service Worker, который сообщает Service Worker, что произошли изменения в базе данных на стороне сервера.
  2. Изменения между клиентом и сервером: мы можем регистрировать события фоновой синхронизации каждый раз, когда пишем в локальную базу данных PouchDB. Эти события можно использовать для уведомления Service Worker о наличии локальных изменений, которые необходимо синхронизировать с сервером.
  3. В браузерах, которые не поддерживают фоновую синхронизацию, мы можем запустить прослушиватель изменений в потоке пользовательского интерфейса, который затем отправляет сообщение Service Worker через postMessage для синхронизации локальной и удаленной баз данных.

Куда мы отправимся отсюда?

Мы надеялись завершить сеанс взлома с рабочей демонстрацией синхронизации PouchDB / CouchDB от Service Worker, но, к сожалению, не хватило времени для этого. В идеале мы хотели бы создать демонстрацию, которая последовательно демонстрирует все методы, описанные выше. Кроме того, HospitalRun стремится реализовать эти решения, чтобы правильно обрабатывать автономную синхронизацию, поэтому следите за обновлениями.

Примечание редактора от 16.03.17: теперь вы можете просмотреть Последующий пост Нолана Лоусона, чтобы узнать больше по этой теме:



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