Детализация Meteor GroundDB для автономной / онлайн-синхронизации

Допустим, два пользователя вносят изменения в один и тот же документ, находясь в автономном режиме, но в разных разделах документа. Если пользователь 2 возвращается в сеть после пользователя 1, будут ли потеряны сделанные пользователем изменения 1?

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

2 ответа

Решение

Краткий ответ - "да", ни одна из базовых версий БД не имеет разрешения конфликтов, так как логика настраивается в зависимости от поведения разрешения конфликтов, например. если вы хотите автоматизировать или привлечь пользователя.

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

Ground db II не имеет метода возобновления, это более или менее просто способ кэширования данных в автономном режиме. Это наблюдение на наблюдаемом источнике.

Я предполагаю, что вы могли бы создать наблюдатель промежуточного программного обеспечения для GDB II - тот, который проверяет локальные данные перед выполнением обновления и обновляет клиент или / и вызывает сервер для обновления данных сервера. Таким образом, у вас будет способ справиться с конфликтами.

Я думаю, что нужно помнить написание некоторого кода, который поддерживает "deleteAt"/"updatedAt" для некоторых типов обработки конфликтов, но опять-таки обработчик конфликта должен быть по большей части пользовательским. (может быть полезно открыть дверь для многоразовых обработчиков конфликтов)

Особенно зная, когда данные удаляются, может быть сложно, если вы не "мягко" удаляете с помощью чего-то вроде использования "удаленного объекта".

В настоящее время ветка "rc" является grounddb-caching-2016 версии "2.0.0-rc.4",

Я думал о чем-то вроде: (учтите, это не проверено, написано непосредственно в SO)

// Create the grounded collection
foo = new Ground.Collection('test');

// Make it observe a source (it's aware of createdAt/updatedAt and
// removedAt entities)
foo.observeSource(bar.find());

bar.find() возвращает курсор с функцией observe наше промежуточное ПО должно делать то же самое. Давайте создадим createMiddleWare помощник для этого:

function createMiddleWare(source, middleware) {
  const cursor = (typeof (source||{}).observe === 'function') ? source : source.find();
  return {
    observe: function(observerHandle) {
      const sourceObserverHandle = cursor.observe({
        added: doc => {
          middleware.added.call(observerHandle, doc);
        },
        updated: (doc, oldDoc) => {
          middleware.updated.call(observerHandle, doc, oldDoc);
        },
        removed: doc => {
          middleware.removed.call(observerHandle, doc);
        },
      });
      // Return stop handle
      return sourceObserverHandle;
    }
  };
}

Использование:

foo = new Ground.Collection('test');

foo.observeSource(createMiddleware(bar.find(), {
  added: function(doc) {
    // just pass it through
    this.added(doc);
  },
  updated: function(doc, oldDoc) {
    const fooDoc = foo.findOne(doc._id);

    // Example of a simple conflict handler:
    if (fooDoc && doc.updatedAt < fooDoc.updatedAt) {
      // Seems like the foo doc is newer? lets update the server...
      // (we'll just use the regular bar, since thats the meteor
      // collection and foo is the grounded data
      bar.update(doc._id, fooDoc);
    } else {
      // pass through
      this.updated(doc, oldDoc);
    }
  },
  removed: function(doc) {
    // again just pass through for now
    this.removed(doc);
  }
}));
Другие вопросы по тегам