Meteor Collection / Subscription force poll


#1

I’ve been wondering. I’m dealing with a project where an external API is responsible for all updates. I’m unable to use the oplog, so Meteor falls back to using the polling observer. Basically:

Method -> API Call -> DB update -> Poll (on interval) -> Publish -> client update

The problem is that now it might take up to 10 seconds for my update / remove to appear on the clientside. Which is… not great. I’ve been looking into the latency compensation, updating the clientside only, but this change is ofcourse directly undone by the Meteor serverside only to be done again when the update from the external API also reaches the server…

Another option would be to update the server’s minimongo collection and push the changes to each client, but without persisting the change allowing to let the API take all the time it needs to to the update on the database.

Anyone that has been dealing with this scenario that can help me out?


#2

Reads like the motivation that led to Apollo :slight_smile:
(Not that Apollo is the answer here for you)
Sorry I can be no help beyomd that


#3

Yea, I’m taking a bit of a CQRS approach at the moment. External command services are responsible for the business logic. The Meteor app is just the Read side and I’m hoping that I can utilize Meteor’s oplog for realtime updates on my read database.


#4

perhaps redis oplog could be brought to bear?
(Ive never had time to look into it. These situations can get hacky quickly )


#5

That would have been a nice choice if I had some control over the external services. They basically are static REST endpoints and the only way to get some sort of out of the box realtime connection is the shared mongo database that binds all of the apps together.

Ideally in this scenario I would fall back to polling and somehow force meteor’s polling observer to poll ‘now’.


#6

At what point in time does a method’s server side code ‘invalidate’ whatever its client-side stub has done? Is it too naive to assume this occurs simply when the method’s server side code is finished running? If this is indeed the case, couldn’t you build your method’s server side part as such that immediately after being called it fires its action to the external API and then instead of just letting the method finish right away (causing the Optimistic UI updates to be undone and client to see unnecessary flickering), you wait for the API call to return an OK message and essentially force the code inside the method to run synchronously (wrapAsync, promise, something else?). For a more caveman solution, you could also just use _sleepForMs in the method with a value that is longer than the expected polling time. If the method then finishes only after the changes have been done in the shared DB, there should be no unnecessary changes client-side? Having such long trailing methods would probably cause many problems of their own, but some of them could perhaps be alleviated with this.unblock.

Do take everything I say above with a rather large grain of salt. I am by no means an expert on the topic and it is very likely that I have misunderstood something above.


#7

I really appreciate your response, but the problem is not the rest API and my client (meteor’s http client). Its the fact that even if the API already updated the database, the minimongo cache on Meteor side is still having the older version of the data.

The pollingObserveDriver is responsible for updating this minimongo cache and it does it on every 10 seconds. The problem with that is that if I would update something and a poll has just happened, I will have to wait for a max of 9.9 seconds to see the updated information even though the actuall update took only 100ms.

Would be so nice if we could simply have a method on each mongo collection along the lines of:

MyCollection.refresh();

Anyway I hope mongo 3.4 will be supported soon with its notification API. That would solve the problem


#8

Thanks for the clarification. I’m still rather hazy on how and when exactly do the result of stubs make way for the actual results from their server side counterparts, given that client side is almost always preceeding results from server, but let’s leave that for another thread.

Barring any solution to actually force updates outside the general poll cycle, I guess a possible solution for you would be to not use stubs at all and make use of subtle loading icons/backgrounds set while calling methods to indicate items which are in the limbo while waiting updates from the db. Although I’m now beginning to doubt if that would be any easier (i.e. result from Meteor.call’s callback and actual db state getting ‘out of sync’ due to polling lag). Anyway, that was my two cents.

Hopefully someone with more experience can chime in.


#9

Quite a while ago you’ve asked about this, but does this part of the documentation help you?