Add support for checking if the app is reloading (migrating) #657

wants to merge 1 commit into


None yet

5 participants


Currently I'm doing something similar to the code below, to check if Meteor is Migrating.

window.onbeforeunload = function() {
    isReloading = window.sessionStorage ? sessionStorage.getItem('Meteor_Reload') : false;
    if (!isReloading && Session.get('current_timer')) {
        return "You've got active timers. Do you want to close the page, and leave them running in the background?";

The problem is, that this won't work for browsers not supporting sessionStorage.
With this pull request, I can now simply do something like the code below, and it should work for more than just browsers that support sessionStorage

window.onbeforeunload = function() {
    if (!Meteor._reload.isReloading() && Session.get('current_timer')) {
        return "You've got active timers. Do you want to close the page, and leave them running in the background?";

Ah, is the point that you want to do something if the user closes the window, but not if Meteor is reloading?


@awwx Yes. Well, I've got one more condition in my example, as it's only when there's something running, they didn't finish yet, but in general, I just want to know if it was the user reloading / navigating away, or Meteor reload the app. :)

@Multiply Multiply closed this Feb 2, 2013
@Multiply Multiply reopened this Feb 2, 2013

I accidently hit Close & Comment. Silly me. :)


Hi, the there is a Meteor callback option for the Meteor reload event,
Maybe something like: not tested

  function myCallback() { /* */}

  if (Meteor._reload) {
    Meteor._reload.onMigrate('myCallback', myCallback); //Add callback

    (function () {
      var resultMyCallback = Meteor._reload.migrationData('myCallback'); //If result wanted

    window.onbeforeunload = myCallback;

Of course, I can add a callback, then store the variable and check on that, I just found it easier to simply implement a callback, to see the actual value, as it seemed more clean to me, as a general solution.

Atleast I find it more clean, if you look at the commit, compared to the above example.

Meteor Development Group member

@Multiply, the thing that I'm not sure of about your code is, if the user tells us not to reload the page right now, when do we try again? If the user declines it once, do you want to turn off code push for that tab forever?

The onMigrate API lets you get a callback when a migration (hot code push) is about to happen, and either let it proceed, or delay it until a later time that you specify. And you can do anything you want to make the decision (including, say, putting up a HTML5 banner with a timer that counts down and 'update now' and 'cancel' buttons, or whatever.)

Meteor._reload.onMigrate(function (callback) {
  if (/* we're OK with migrating now */)
    return [true];
  else {
    /* We want to delay migration. Put up a banner, set a timer, or do whatever.
       You should save 'callback' and call it when we're ready to let the migration
       proceed. */
    return false;

If you want to save some of your own data across the migration, you can do that by passing an additional name argument to onMigrate and returning the data as [true, yourDataHere]. See the docs in the comments in packages/reload.js.

This is an undocumented API, so it's subject to change.. but we should probably go ahead and document it, and make it available as Meteor.onMigrate or something like that rather that under Meteor._reload.

Definitely open to considering other ways to expose this functionality, but if we do something other than (or in addition to) onMigrate, then I want to make sure we have a clear idea of what happens if the user wants to delay the reload.


@gschmidt a Meteor.onMigrate 👍
It would be useful to prevent reload when the user eg. is uploading a file or other critical situations where we want this.
would it support return of both booleanand array? - would be nice


@gschmidt - In my example, the user is NOT prompted, if the it's a migration. That's the whole point.

I want this function to check if we indeed are in the process of migrating, or not.
If we are, don't prompt the user, and continue. If not, prompt if they want to leave the page.

So a basic scenario, like in my example:

  • User adds something to a collection.
  • User tries to leave page and gets prompted, because he has something running, that isn't removed from the collection yet.
  • He choose to stay.
  • A little later, some code is being pushed, ie. migration.
  • onbeforereload is called, but we use the function added in my commit, to check if this is indeed a migration, or just some other way to reload / navigate away from the page.
  • function returns true, and doesn't prompt the user, but reloads the page.
  • Profit.

I think you kind of misunderstood my need for this particular function.
I would use onMigrate, for your example when uploading a file, @raix, as I then could return we're not ready yet.


@Multiply So in basic, you want to prevent the user for loosing the local data that's not yet saved on the server/dirty.
@gschmidt maybe this is an event Meteor should provide?

Meteor.onbeforedataloss = callback;

gets triggered if user tries to leave and if a collections data is dirty


@raix no. That's what onMigrate is for.

I don't know how to put it more simply. I want to know if the app is going to reload because of a migration, or because of other means (ie. user action). This function provides me with that information. It's not evented. It's just a basic boolean return.

I chose to take use of the function from a onbeforereload, not because the user might lose data, but to remind them that they left something running, that they might want to stop, before logging off the service. They can feel free to leave it running, if they just need to restart the browser, or if they intend to come back later, and check out when they are done. There's no risk of losing anything. I just don't want to tell the user to react to something, if they didn't reload the browser themselves.


@Multiply, the thing that I'm not sure of about your code is, if the user tells us not to reload the page right now, when do we try again? If the user declines it once, do you want to turn off code push for that tab forever?

@gschmidt, I think you may have missed the point, at least as I understand it...:

If the page is reloading because of a code push, @Multiply doesn't want Meteor to do anything different. The code push and page reload should go ahead as usual.

What @Multiply wants to do is if browser is unloading the page because of a user action (closing the tab, navigating away from the page), and there's an active task that he's running for the user, he wants to pop up a message like "do you want to close the page and leave the task running in the background?"

The problem is that a Meteor code reload also triggers the window unload event, so his user gets the message on a code reload, which he doesn't want.

So what @Multiply wants is to be able to tell if a page reload is happening because of a Meteor code reload instead of as a result of a user action, so that he can avoid displaying the message.


well, I think I get it - just trying to figure out the usecases,
So if meteor had a:

Meteor.onbeforeunload = callback;

not triggered by a migration

I'm thinking in event handlers since the window.onbeforeunload would have done the work if not under Meteor. A variable isReloading is not as intuitive - imo


Exactly so @awwx!
@raix But why add a new Meteor event, such as "onbeforereload". jQuery plugins, or in general just plugins all rely on the same old event, and act accordingly. I don't want to rewrite plugins for it to work.

The solution above is clean enough, no need for fluffy code to do this.


@Multiply: I guess you would have to rewrite all your plugins anyway, except if Meteor overwrites the window.onbeforeunload - would not recommend that.
Note that for jquery etc. it's possible to extend the event types, could be done in the jquery/sizzle package if needed.

I still think this should be a Meteor event, as @awwx mentions if migration is canceled when would migration resume - this is a design choice we should not have to do every time, hence save us the trouble.


@raix If you still think this is to prevent migration, you're missing the point. It's not. It's simply to see if we're migrating or not.


as @awwx mentions if migration is canceled

Just to be clear, I did not mention that.


@awwx: "if the user tells us not to reload the page right now, when do we try again?" Sorry I just read that as :"user canceled the reload, when are we reloading then?" eg. if migrating.

@Multiply: I get that your solution is a getter for the reloading variable in the Meteor._reload section.

But I might misunderstanding the event flow of a migration? Being a Meteor newbe
As I understod the onMigrate is triggered before the actual window.onbeforeunload. Making the isReloading() only relevant in the events. Why I think a Meteor.onbeforeunload = callback; would make more sense - well, to me at least :)


Actually I didn't say that either :-) Perhaps you're thinking of gschmidt who said that?

Having a higher level hook which is triggered when the user closes the page but not when Meteor is reloading the page strikes me as a useful idea. I would want to think carefully about the details. For example, if I have a hyperlink which loads a different page in the app (perhaps to load different resources), does that count or not? I can think of examples of where I would want that to trigger my callback and other examples where I wouldn't. I also personally wouldn't want the feature to be called "onbeforeunload" as such, because a Meteor reload does in fact unload the page.

I'm not sure that such a higher level feature would replace the need for a lower level API however. Meteor code reloading is a fundamental part of the architecture, and there could be other places where I'd need to be aware of when it's happening (for example, perhaps I'm modifying an existing Javascript library to be Meteor aware). Another advantage of having a lower level API is that I'm not stuck with what the higher level feature provides -- if it doesn't fit my particular situation, I can drop down to the lower level API and implement my own solution.


lol, I'm a Github newbe aswell.. True I read your quote of gschmidt comment as yours, my bad.

I'm not sure what the future of reload is, at the meteor roadmap there's something about a super smooth reload - Ideally I would prefere if the reload didn't make a reload of the page at all, not triggering onbeforeunload. This would downgrade some of the discussion - at least my part. The primary reason would be to preserve as much data loaded plus file pointers (if users are uploading files)

Ideally we shouldn't have to think about reload at all?

I agree about the naming Meteor.onbeforeunload maybe something like Meteor.onImpact though a serious name like Meteor.onbeforedataloss really gets my attention.


These are good ideas and I'd suggest filing issues for them, so that they can be discussed and we can figure out the right way of implementing them.

This issue on the other hand strikes me as straightforward: do we give the developer visibility into Meteor state changes such as when it's performing a code reload, or not? It seems to me reasonable to do so, similar to how web browsers allow the developer to hook into browser events as a low-level API -- which libraries can then build higher level abstractions and frameworks on top of.


@awwx - when you say clicking on links, are you refering to internal, or external links? Links such as "#something" or links that gets hooked, and simply does a History state change (ie. meteor-router), doesn't trigger the onbeforereload.

I vote 'nay' to the solution with an internal event call, as you still have to implement this in other libraries, that you might not want to edit the source of. The whole thing has been about the "onbeforereload" - Can we scratch that part out? I simply want to be able to tell the difference from a normal "onbeforereload" or one caused by the app migrating. Or I simply want to know, if we're reloading or not. It could be some heavy data-feed getting downloaded, and I'd like to NOT cause my server to bleed for 10 seconds, if we're about to migrate anyway. Stuff like this. Not JUST onbeforereload. This could also be used to tell the user, that we are indeed in the process of migrating, using some sort of reactive variable. Actually, not a bad idea. This won't represent a new internal function, but merely set some global reactive readonly variable.

I like either. But if we present another event-related thing, I might aswell just use the onMigrate, and cache my own local variable, telling me if we're reloading because of a migration or not.


@awwx - when you say clicking on links, are you refering to internal, or external links?

mmm, that was a bit of speculation for multi-page apps, but not very important for the current discussion.


Multiply: I'm thinking if should be placed in 'Meteor.status()'?


Agreed that it would be useful to be able to tell whether we're in the middle of a reload, but I think we should do that as part of making the Reload package have a documented and public API. I'll add an XXX comment to the code to that effect, and I'm closing this ticket.

In the meanwhile, you can resolve this by using the undocumented Reload._onMigrate API to set a flag when migration is about to happen. See

@avital avital closed this Sep 25, 2013
@avital avital added a commit that referenced this pull request Sep 25, 2013
@avital avital Add XXX to reload package informed by #657 569e922
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment