App constantly refreshing after an update

I don’t think DDP Rate limiter will help, the DDP frames look perfectly normal also when looping.

My upgrade was OK, I found #7184 which benjamn fixed really quickly, and one of my packages was using a NodeJS fs method that was deprecated and now was removed, but the maintainer fixed that quickly too, after that all was smooth. I guess it depends on what packages you use…

So I upgraded to 1.3.3-rc4 beta this evening and it worked well. No more refreshing. Life saver! Thanks

2 Likes

Noooooo! The issue is back!! Was confident it had subsided! This is awful. No idea when the refreshing does or doesn’t happen. And I’ve also seen it happen on the main domain, not just subdomains

Wait… my app has managed to go back to 1.3.2.4. Strange…

Just want to confirm that this issue does not go away after upgrading to Meteor 1.3.3-rc5.

Apologies for talking to myself here, but I have a strong feeling this bug is killing my servers a little.

Here’s the latest update in the story:
Some of my servers are hitting 100%. I couldn’t understand why.
Here are two Kadira graphs from one of my instances:

Graph 1:

Graph 2:

Interesting correlation between the graphs.

What’s more interesting is that I remove the raix:push package a few days ago. The wait time you see in Graph 1 is an throwing errors for not finding the method raix:push-setuser.

How is this method being called if I removed it from the app? The answer seems to be that there are still clients calling old Meteor code. And I’m guessing this is the infinite refresh problem some of us have been having. There are certain browsers that are connected to my app that have been refreshing for days straight and during all these refreshes they seem to be running old code and bombarding my servers to fetch data from the database causing 100% CPU.

So it looks like it keeps reloading old code, sees the code is old and then reloads again. Or something along those lines. The problem is the new code never comes in.

@abernix: does this make sense? And any ideas how we can get this issue fixed?

You’re not talking to yourself, but as I have not seen the problem since moving to 1.3.3 it is even harder get useful info.

My reasoning on all this is about the following:

Known Facts

  • Only a few people are seeing this, and always intermittently
  • We have not been able to establish many common parameters between our environments:
  • Different deployments (single/multiple servers, mupx / not mupx etc)
  • Different routers
  • Intersection of packages used between us is basically zero.
  • Everyone runs nginx proxy, but polishing the nginx config does not help.
  • Analysis of the WS frames show nothing suspicious.
  • Reloads happens with DISABLE_WEBSOCKETS=true as well.
  • The reload-safetybelt package does not help.
  • The reload happends after a significant portion of the app has initialized, even after some subscriptions have been fulfilled etc.
  • Once the preconditions leading to a reload loop have been fulfilled, they stay so for that client (i e the looping never stops)

…so…what gives?

Somewhere in Meteor there must be code that does a reload. If not, this is a weird browser bug??
This code gets triggered by some unusual combination of events, most probably involving some sort of race condition giving us the intermittent behavior, and also involving some dependency on something getting cached in a proxy.

To me, to debug this further you need either to be an expert on Meteor internals, or you need a repeatable testcase, which we have not :worried:

@elie, after reading my post above a few time, one thing that stands out is this:

  • The issue is intermittent as to when it STARTS TO HAPPEN
  • Once started, it is NO LONGER intermittent, it happens repeatably on every reload.

This means that during looping, something is stuck somewhere (=in the browser or in the proxy) for that client.

Could it be this is an nginx issue? I know you’re desperate. Would it be worth the effort for you to try a different reverse proxy package?

I assume it could well be an nginx config issue. I’d rather not update the
app than having to move away from nginx myself.

I started to have a look at the meteor internals. The reload package is
almost certainly where the reloading is happening.

The issue does seem to be happening less to me at the moment, but that also
makes it harder to debug.

I will continue to investigate and I think I might use the dev version of
meteor or edit it and add some console logs to figure out what’s happening.

Hello
we had the same issue and it belongs to the new caching mechanism of Meteor 1.3.x. You have to disable caching in your nginx file and the refreshing will be gone. Let the caching happening in Meteor itself.
# pass all requests to Meteor location / { proxy_pass http://yourapp:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # allow websockets proxy_set_header Connection $connection_upgrade; proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP }

Where have you disabled caching? This looks like the standard nginx Meteor conf file? Has something been removed from it?

Should the section at the bottom of this file be removed?

# pass all requests to Meteor
location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade; # allow websockets
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

    # this setting allows the browser to cache the application in a way compatible with Meteor
    # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
    # the root path (/) MUST NOT be cached
    if ($uri != '/') {
        expires 30d;
    }
}

Also, any idea where the Meteor caching code is located in the Meteor code? (Is it somewhere in here? https://github.com/meteor/meteor/blob/devel/packages/webapp/webapp_server.js)

And why can’t nginx handle the caching everything apart from / since 1.3?

I will try removing the caching this evening and see what happens.

I had this same issue, which only started after I added meteorhacks:cluster and started running two processes. Once I removed meteorhacks:cluster and returned to a single process the constant reloading was gone as well.

Does anyone have an idea of how to just stop clients running the old code? There are browsers around the world constantly refreshing an old app and I’d like it to stop.

I’m not sure whether remove expire from nginx has helped anything. It’s difficult to know if the problem is resolved since it doesn’t always happen.

4 weeks on and I don’t think we’re any closer to a solution. I don’t think any of the solutions in this thread have helped. Although they have apparently helped in individual cases.

The problem still exists in meteor 1.3.3

My current way of dealing with this is to simple deploy a new server with each release, since I don’t trust hot code push to work without initializing a sudden infinite reload.

Interesting idea. How does that actually help things though? What’s the difference between redeploying and deploying a whole new instance?

Also, does anyone know if there’s a way to disable hot reload to avoid this problem? At the same time you would still like the app to update at some point for the user.

Just to clarify: I’m using a cordova wrapped app, which I’m pointing at a new server and resubmitting to the app store.

2 Likes

We were experiencing this issue as well. We were able to solve it by removing nginx caching. In particular, this line:

if ($uri != '/') {		
  expires 30d;		
}
1 Like

Does anyone understand why this works? And does it take a hit on
performance at all?

My best guess is that Meteor triggers a page reload when it sees stale assets requested, in the hopes that this will force the browser to request everything fresh from the server, which appears to not work well with the nginx caching described in this thread. Below is my best guess as to why.

Meteor includes the header Cache-Control:public, max-age=31536000 for static assets like JS/CSS files, but uses a revision hash in the file name to make sure that the latest JS/CSS is always pulled from the server. Requesting HTML documents from Meteor doesn’t return any caching headers.

However, if nginx is caching pages using

if ($uri != '/') {		
  expires 30d;		
}

…the browser continues to load an outdated copy of the document (including older revisions of the JS/CSS files) – this is what I believe Meteor does not like. Meteor detects that the client is connecting with old code and triggers a browser refresh to try and force the browser to request newer assets. But the browser continues to pull from the cache, causing yet another reload. And on and on.

This is my best guess. I’m still not sure how Meteor can detect old code, nor what performance implication it has to disable nginx caching.