OpenHausIO / backend

HTTP API for the OpenHaus SmartHome/IoT solution
https://docs.open-haus.io
6 stars 2 forks source link

Add mongodb change streams to detect changes in the db? #67

Closed mStirner closed 2 years ago

mStirner commented 2 years ago

I find myself often to change something directly in the database, especially while developing the frontend with a older dataset (changed object schema in components), and every time i change something the backend needs to be restarted.

To solve this and improve the backend/handling, implement mongodb change streams and update the component object directly?

The code snippet seems pretty nice and clear:

const collection = db.collection('inventory');
const changeStream = collection.watch();

changeStream.on('change', next => {
// process next document
});

Monkey patch updatedFields and trigger "updated" event on component? https://docs.mongodb.com/manual/reference/change-events/#update-event

mStirner commented 2 years ago

Hmm, this looks like a feature for replica sets. Add in /etc/mongod.conf

replication:
   replSetName: "rs0"

Restart, apply changes & open mongo cli client

systemctl restart mongod
mongo

Initialize replica set

rs.initiate()

Changes locally implemented. Lets see how it works :)

EDIT: Perhaps this is better than the first thought: Imagen you have more than one backend running, behind a loadbalancer. Now how to sync the changes?! Could be a good starting point for HA.

Update operation (Emitted from component .update method):

{
  _id: {
    _data: '826228FE32000000022B022C0100296E5A1004682ED669F49344C0959736ACF927745E46645F6964006462266BB691964F707F8B9A460004'
  },
  operationType: 'update',
  clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1646853682 },
  ns: { db: 'OpenHaus', coll: 'rooms' },
  documentKey: { _id: 62266bb691964f707f8b9a46 },
  updateDescription: {
    updatedFields: { name: 'letzer 684486', timestamps: [Object] },
    removedFields: []
  }
}

Replace (When mongodb compass is used):

{
  _id: {
    _data: '826228FE98000000012B022C0100296E5A1004682ED669F49344C0959736ACF927745E46645F6964006462266BB691964F707F8B9A460004'
  },
  operationType: 'replace',
  clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1646853784 },
  fullDocument: {
    _id: 62266bb691964f707f8b9a46,
    name: 'letzer 68448621342123',
    timestamps: { created: 1646685110764, updated: 1646853682557 },
    number: null,
    floor: null,
    icon: null
  },
  ns: { db: 'OpenHaus', coll: 'rooms' },
  documentKey: { _id: 62266bb691964f707f8b9a46 }
}
mStirner commented 2 years ago

Add more details for error message if collection.watch(); throws error. E.g.: "Database must be run in replica set" or so...

mStirner commented 2 years ago

Watch/Test for changes on the whole database: https://docs.mongodb.com/manual/reference/method/db.watch/#mongodb-method-db.watch

https://docs.mongodb.com/manual/changeStreams/#watch-a-collection--database--or-deployment