Denis Makarov
Denis Makarov

Reputation: 31

Rxdb sync not update db

There are 3 bases (front, node, remote). Front <=> node, node <=> remote. When the front base is updated, the data goes to the remote base, but the node is not updated. In theory, the node should be updated first, and then the remote base.

Render db

addPouchPlugin(PouchdbAdapterIdb)
addPouchPlugin(PouchHttpPlugin)

addRxPlugin(RxDBReplicationCouchDBPlugin)
addRxPlugin(RxDBMigrationPlugin)
addRxPlugin(RxDBLeaderElectionPlugin)
addRxPlugin(RxDBQueryBuilderPlugin)
addRxPlugin(RxDBAjvValidatePlugin)
addRxPlugin(RxDBUpdatePlugin)

export const createDb = async () => {
  console.log('[src/renderer/database/createDb] createDb')
  const productsName = collectionName.getCollectionProductsName()
  const documentsName = collectionName.getCollectionDocumentsName()
  const settingsName = collectionName.getCollectionSettingsName()

  const db = await createRxDatabase<Collections>({
    name: 'renderer',
    // use pouchdb with the indexeddb-adapter as storage engine.
    storage: getRxStoragePouch('idb'),
  })
  await initCommonCollections({ db, documentsName, productsName, settingsName })
  syncDbCollections(db, [productsName, documentsName, settingsName])

  db.$.subscribe(({ operation, documentId, documentData }) => {
    if (documentData.type === SettingsTypes.DEVICE_SETTING) {
      console.log(`Change database RENDER event:\n ${operation}, \n documentData:`, documentData)
    }
  })

  return db
}

Render sync

const remoteDbUrl = `http://localhost:3030/db/`
const logPath = '[src/renderer/database/syncDbCollections]'

export const syncDbCollections = (db: RxDatabase<Collections>, collectionNames: (keyof Collections)[]) => {
  console.log('syncDbCollections', collectionNames)
  collectionNames.forEach(name => {
    const rxReplicationState = db.collections[name].syncCouchDB({
      remote: `${remoteDbUrl}${name}`,
      options: {
        live: true,
        retry: true,
      },
    })

    rxReplicationState.error$.subscribe(error => {
      console.error(logPath, name, 'error', JSON.stringify(error))
    })
  })
}

Node base

addPouchPlugin(PouchdbAdapterHttp)
addPouchPlugin(LevelDbAdapter)
addRxPlugin(RxDBAjvValidatePlugin)
addRxPlugin(RxDBMigrationPlugin)
addRxPlugin(RxDBServerPlugin)
addRxPlugin(RxDBLeaderElectionPlugin)
addRxPlugin(RxDBQueryBuilderPlugin)
addRxPlugin(RxDBUpdatePlugin)
addRxPlugin(RxDBReplicationCouchDBPlugin)

let db: RxDatabase<Collections>

export const getMainDb = () => {
  if (!db) {
    throw new Error('No available database.')
  }
  return db
}

export const getDocumentCollection = (): DocumentsRxCol => {
  return db[collectionNames.getCollectionDocumentsName()]
}

export const getSettingsCollection = (): SettingsRxCol => {
  return db[collectionNames.getCollectionSettingsName()]
}

export const getProductsCollection = (): ProductsRxCol => {
  return db[collectionNames.getCollectionProductsName()]
}

export const initDatabase = async () => {
  console.log(logPathAlias, 'initDatabase')
  if (db) {
    console.warn(logPathAlias, 'db instance already created!')
    return db
  }
  db = await createRxDatabase<Collections>({
    name: `${electronApp.getPath('userData')}/db`,
    storage: getRxStoragePouch(LevelDown),
  })

  const productsName = collectionNames.getCollectionProductsName()
  const documentsName = collectionNames.getCollectionDocumentsName()
  const settingsName = collectionNames.getCollectionSettingsName()

  await initCommonCollections({ db, productsName, documentsName, settingsName })
  await syncCollections([productsName, documentsName, settingsName])

  db.$.subscribe(({ operation, documentId, documentData }) => {
    // if (documentData.type === SettingsTypes.DEVICE_SETTING) {
    console.log(`Change database NODE event:\n ${operation}, \n documentData:`, documentData)
    // }
  })

  const { app } = await db.server({
    startServer: false, // (optional), start express server
    // options of the pouchdb express server
    cors: false,
    pouchdbExpressOptions: {
      inMemoryConfig: true, // do not write a config.json
      logPath: `${electronApp.getPath('temp')}/rxdb-server.log`, // save logs in tmp folder
    },
  })

  return app
}

const lastRetryTime = {}
const syncCollections = async (collections: CollectionNames[]) => {
  collections.map(collectionName => {
    const rxReplicationState = db.collections[collectionName].syncCouchDB({
      remote: `${CouchDbServerUrl}/${collectionName}`,
      options: {
        live: true,
        retry: true,
        // @ts-ignore
        // headers: {
        //   Authorization: `Bearer ${getAccessToken()}`,
        // },
      },
    })
    rxReplicationState.error$.subscribe(async error => {
      console.error(logPathAlias, collectionName, String(error))
      if (error.status === 401 && dayjs().diff(lastRetryTime[collectionName], 'seconds') > 10 && getIsRefreshFresh()) {
        lastRetryTime[collectionName] = dayjs()
        await rxReplicationState.cancel()
        await refreshTokens()
        await syncCollections([collectionName])
      }
    })
  })
}

No errors

Moreover, if you save data in a remote database, then they are synchronized with the node

Help me :(

Upvotes: 3

Views: 530

Answers (0)

Related Questions