Слушатель "_changes" CouchDB обновляет документ, что вызывает другое изменение - PullRequest
2 голосов
/ 20 августа 2011

Я хочу написать фоновую программу, которая будет отслеживать канал _changes CouchDB и, возможно, обновлять документ.Проблема в том, что обновление вызывает еще один _change, и я получаю бесконечный цикл!Какой лучший способ избежать этого?

Например, вот конкретный сценарий: у меня есть CouchApp, где пользователи изменяют документы через свой браузер.У меня также есть программа на Python, которая создает PDF-версию документа, а затем прикрепляет ее в виде вложенного файла к самому документу.Моя проблема заключается в том, что выполнение приложения PUT для загрузки файла PDF также вызывает изменение документа.Я должен быть в состоянии сказать, вызвано ли изменение загрузкой PDF или нет.Кажется, это должно быть легко, но я не могу придумать простой способ сделать это.Я бы предпочел, чтобы программа генератора PDF оставалась без сохранения состояния, сохраняя любое требуемое состояние в самой базе данных.

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


Я пришел к выводу, что слушатель "_changes" никогда не должен изменять документ, который он слушает.В моем случае я решил прикрепить свой PDF-файл к отдельному документу, в отдельной «базе данных» внутри couchdb, но используя тот же «_id», чтобы облегчить корреляцию.Таким образом, я не запускаю «_change» на тех же документах, которые слушаю.Я не мог избавиться от необходимости требовать от каждого клиента, который изменяет документ, чтобы каким-то образом «помечать» его как требующий обработки (удаляя существующее вложение или иным образом устанавливая некоторый «грязный» флаг).После долгих размышлений я думаю, что для меня это будет практическим правилом: вы не должны изменять документ после получения уведомления «_change» для этого документа.Кто-нибудь еще пришел к такому выводу?

1 Ответ

4 голосов
/ 20 августа 2011

Используйте функцию фильтра и отфильтруйте второе изменение - либо путем изменения структуры документа, либо установив дополнительный флаг для измененного документа:

function(doc, req)
{
  if(!doc.hasStructuralChange) { //fix this
    return true;
  }
  return false;
}

или

function(doc, req)
{
  if(!doc.changed) { //set doc.changed during first update
    return true;
  }
  return false;
}

Редактировать: Вы можете проверить вложение с помощью if (doc._attachments)

...