Как избежать петель при написании облачных функций? - PullRequest
2 голосов
/ 28 апреля 2019

При написании облачных функций на основе событий для firebase firestore обычно обновляются поля в затронутом документе, например:

Когда документ из коллекции пользователей обновляется, запускается функция,скажем, мы хотим определить пользовательское информационное состояние и у нас есть свойство completeInfo: boolean, функция должна будет выполнить другое обновление, чтобы триггер снова сработал, если мы не используем флаг типа needsUpdate: boolean, чтобы определить,кроме функции у нас будет бесконечный цикл.

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

Ответы [ 3 ]

2 голосов
/ 28 апреля 2019

У меня есть несколько общих подходов к облачным функциям, которые преобразуют данные:

  1. Записать преобразованные данные в документ, отличный от того, который вызывает функцию Cloud. Это гораздо более простой подход, поскольку нет необходимости в дополнительном коде - и поэтому я не могу допустить ошибок в нем. Это также означает, что дополнительного триггера нет, поэтому вы не платите за этот дополнительный вызов.

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

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

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

    exports.fanoutAmount = functions.firestore.document('users/{uid}').onWrite((change, context) => {
      let old_amount = change.before && change.before.data() && change.before.data().amount ? change.before.data().amount : 0;
      let new_amount = change.after.data().amount;
      if (old_amount !== new_amount) {
        // TODO: fan out to all documents in the collection
      }
    });
    
0 голосов
/ 28 апреля 2019

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

0 голосов
/ 28 апреля 2019

Вы должны позаботиться о том, чтобы не писать функцию, которая срабатывает бесконечно.Это не то, что облачные функции могут сделать для вас.Обычно вы делаете это, проверяя в своей функции, была ли работа ранее выполнена для документа, который был изменен в предыдущем вызове.Есть несколько способов сделать это, и вам придется реализовать что-то, соответствующее вашему конкретному варианту использования.

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