Meteor Scaling - Redis Oplog [Status: Prod ready]

ah ok, sorry, for some reason I forgot databases are not even on Galaxy in the first place! lol

Yeah, I can try locally, but our app isn’t too demanding locally. Wouldn’t be too beneficial. Once it’s a little more stable I’ll make sure no major issues locally and then can give it a go on our live server.

@diaconutheodor

Just double checked and definitely not doing the RedisOplog.init() twice (did a find on the entire project source to make sure).

I also checked to make sure I’m not double importing the file containing the ‘Addresses.Company.List’ publication too.

Bit of an odd one but it’s hardly a show stopper as the workaround gets it up and running. I’ll keep poking around to see what I can find and let you know if I discover anything.

@Longmate updated to 1.0.5, fixed the infinite recursion bug.

1 Like

Just out of curiousity: what were you considering switching to?

1 Like

Like everyone else, probably FeathersJS.

@diaconutheodor Tested and confirmed as fixed - nice work!

@diaconutheodor

Been testing for over a day now and generally it’s working fantastic :slight_smile: I think I may have found a possible issue with the use of the $pull operator though which I’ve filed an issue for here - https://github.com/cult-of-coders/redis-oplog/issues/39

Let me know if you need me to do anything else to help debug/test.

Cheers!

@Longmate

Very nice find! It was related to deepExtend.

_.isObject([]) === true

Ofcourse an array is an object, it escaped me. Also I needed to treat the scenario when it’s a Date. Not to “extend it deeply”.

Thank you! 1.0.7 is out, because I rushed publishing 1.0.6, then the Date scenario hit me. Please reopen the ticket if issue persists. Cheers

Update:
And thank you for testing this. We need more like you to break it :smiley:

1 Like

@diaconutheodor

Man you are damn quick at fixing this :sweat_smile: Tested and working, thanks!

No problem - it will benefit the whole Meteor community so even though I’m already very snowed under being the only developer for my yet to launch startup company - I think it’s worth taking the time to help out with this. I hope more people jump on the band wagon and assist with testing this out. My app is still under development, so it just proves any one else can do the same to help even if they don’t have a finished production app!

I’m happy the guys at Classcraft have showed an interest too as I’m sure their input will be absolutely invaluable given their user base size!

2 Likes

Wish I had the time to invest fully in this to perfect it, this is less than a part-time project at this stage. It wouldn’t take me more than 60-80 hours to put the “production-ready” label on it. But after it gets that label, then “MongoDB oplog” will be a thing of the past. (I hope!)

The redis-oplog will have the following path:

  • Abstract MongoDB and open reactivity to all databases
  • Implement “query watcher sharing on a fleet” or maybe the ability to decouple query watchers as a micro-service so when reactivity is a bottleneck for you, you can easily horizontally scale your query watchers servers :smiley:
  • Maybe implement a more robust pub/sub like https://kafka.apache.org/ for enterprise-level reactivity. (Not sure about it, but it sounds so good)
3 Likes

Anything which has “Kafka” in its name by definition cannot be good for anyone’s sanity.

As evidenced by the very fact that they gave it this name in the first place.

This looks cool. Thanks for your work

So I understand in production I’d have to set up a Redis server (maybe EC2 or DO) and point my app too it. Would I ever need to scale my redis servers? E.g. Have multiple redis servers for the same app? Would that even make sense to do? I have no experience with redis

Compose would make it really easy for you.

Thanks @diaconutheodor for this great contribution. We are about to start testing it before we move it to production (we have made a live classroom management application, so it stresses the limits of reactivity quite well!).

Can I ask you this: How easy is it to integrate reactive publishing (https://github.com/peerlibrary/meteor-reactive-publish). It essentially overloads the ‘this’ inside the publisher to expose this.autorun. I believe this is the last common publishing ‘add-on’ (after publish composite).

EDIT: I thought I would answer my own question, and confirm that reactive publishing works, well done @diaconutheodor !! You have implemented it to be compatible with the original publish API! All we had to do was add the import and init and all is working, we are going through stress tests now.

This is the biggest improvement in Meteor since GraphQL! I would expect that people would later want to implement this with GQL, but, we are not there yet :slight_smile:

3 Likes

@diaconutheodor, how do you use SyntheticMutation with collections? Assuming we already have a collection but want to update a field without updating mongo. Redis CLI monitor shows the update, but the client does not see it.

How about this syntax for ease of use:

self.collection.update({$set:{field1:value1,field2:value2},{skipDB:['field1']})

Both field1 and field2 are sent to the client, but field1 is not pushed to DB.

@ramez

Can I ask you this: How easy is it to integrate reactive publishing (https://github.com/peerlibrary/meteor-reactive-publish3). It essentially overloads the ‘this’ inside the publisher to expose this.autorun. I believe this is the last common publishing ‘add-on’ (after publish composite).

Doesn’t it work already ? If not I will look into this if not.

This is the biggest improvement in Meteor since GraphQL! I would expect that people would later want to implement this with GQL, but, we are not there yet

Read my view about GraphQL so far: Meteor vs Apollo

how do you use SyntheticMutation with collections? Assuming we already have a collection but want to update a field without updating mongo. Redis CLI monitor shows the update, but the client does not see it.

Current api: SyntheticMutation(‘collectionName’).insert(). It can change in time. I want it decoupled from Mongo. Because you don’t have to do an actual update to Mongo to do the syntheticMutation. Right? How would it look X.update({}, {synthField: 1 }) ? Makes no sense.

If the client does not see it, make sure that if you have “fields” specified, then add it to those fields, like it says in README.md if it still does not work, please create an issue, with some code so I can have something to grab myself to.

Thank you

@diaconutheodor, hi!
My project mostly uses meteor methods for working with data, very little pub\sub. Will I get any advantages with redis-oplog?

1 Like

Thanks @diaconutheodor, that part of the Readme.md is a bit unclear :slight_smile: We do have fields in the publish, and the find. On the client we are using observeChanges to detect changes to the cursor. Maybe that’s why? Also, we are using $push in the update on the server not a $set. Everything else is normal. If we remove the SyntheticMutation the App works as planned.

Hi @avalanche1, this package is specifically designed for scalability of reactive data. Which means you are dealing with data (pub/sub) and you are changing a lot of data quite often. Whether you change the data on the client with MiniMongo or on the server with methods, it’s all the same. This package is at the DB layer (i.e. mongo)

Update: Replacing $push with $set still does not push the data down from Mongo collections with SyntheticMutation. Maybe we need a full example or I could share code snippets. Whatever I can do to help.

Disclaimer: I don’t really need this feature, but it’s an opportunity for a small contribution to this amazing endeavor.

1 Like