Switching Client between two sets of server

Hi,

We’re doing a big ugprade and we decided to have 2 sets of servers: blue (for the old code) and green (for the new code). This allows us to switch only some users based on when we’re ready give them access to the update.

For desktop users, our web proxy redirects clients using a cookie that was set by the client to either green or blue.

For Cordova users…it’s been trickier and still not working. The cookie approach works for some parts:

Once the cookie is set, at the next app restart, the websocket does connect to the right server (the proxy receives the cookie so it can redirect the connection)

However, the HCP does not work since the request to get the manifest (GET /__cordova/manifest.json) does never contain the Cookie.

So if the cookie approach did not work, we thought of using a dynamic URL approach.

So we’ve tried changing the ROOT_URL dynamically at the start of the app:
Meteor.absoluteUrl.defaultOptions.rootUrl = “https://server2.blah.com”;

That works for assets only (language files) but I see no impact on the GET /__cordova/manifest.json

Would anyone have any tips on how to get this working ? :slight_smile:

Regards,

Burni

  • List item

This allows us to switch only some users based on when we’re ready give them access to the update.

How do you define when a user is ready? Is that user-based? Or do users need to download an updated app first? Or any other logic?

Hi Luc,

We keep it our choice. We moved our smaller customers first. The idea was to pick a couple of “beta” testers first and when we felt more confident, we moved more users to the upgrade.

It’s just a toggle in their user information document (mongo) that we change manually when we want them to upgrade.

Regards,

Burni

Makes sense!

Here is a user who uses a first connection to login (to get user doc) and then proceeds with connecting to the right server:

Is your users collection shared between the old and the new platform? Because that authentication will have to stay logged in I suppose?

Luc,

Thanks. For all the tests results I have seen, I think we got that part working. The collections are the same (same DB). Everything works except HCP.

What I notice, HCP has 2 components:
1-A websocket subscription that discuses versions
2-An http connection to get the App’s manifest : GET /__cordova/manifest.json

Our problem is that the websocket does connect to the right server but the get /__cordova/manifest.json does connect to the default server coded in the ROOT_URL environment variable (which is the wrong server here).

So what seems to happen is, the app downloads the HCP package from the wrong server.

We have not been able to force a different URL dynamically so far for the __cordova/manifest.json query.

We’ve tried this at the first line of code that Meteor runs:
Meteor.absoluteUrl.defaultOptions.rootUrl = appURL;

But it has no effect on the GET __cordova/manifest.json :frowning:

Any idea where that could be changed?

To be more specific, it’s those 2 requests that do go to the wrong server:
“GET /sockjs/info?cb=a1uw_gki5n HTTP/1.1”
“GET /__cordova/manifest.json HTTP/1.1”

I cannot find where they originate from:
-the Java native plugin
or
-Javascript code

The paths that I see right now are:
1-Force a dynamic ROOT_URL that would be taken into account by the code that does the “GET __cordova/manifest.json”
2-Force a cookie that is taken into account by that code

Would you see any other way of achieving this? :slight_smile:

In my implementation referenced above I was using the exact same code on each server, so I didn’t mind that tye manifest and HCP was always pointing to the primary server.

You could try using webApp.connectHandlers to serve your own manifest.json?

Wildhart,

I understand. What you’ve done is very interesting. Our goals are different but there’s a lot in common too.

As for HCP, I’ve spent the week-end thinking how to make the whole thing work by using webApp.connectHandlers to serve our own manifest.json and I don’t quite see the full path to success.
1-How will the server know which content to serve (at that stage, it won’t know from which customer it’s coming from)
2-How will it know the content of the 2 versions of the manifest

And if we find a solution for #1, which probably means “hacking” the get /__cordova/manifest.json request to make it send more information to the server, then the simplest solution would probably add something that can be read by our proxy server to redirect towards the right server.

So far, from the HCP code I am reading (mostly cordova plugins), it seems the URL is hardcoded at build time and there does not seem to be a way to influence the URL used by HCP as it seems to be native code.

Unless I find a way to programatically change the URL of the GET MANIFEST, I’ll probably just have to do the upgrade the normal way: everyone at the same time.

I do really appreciate your help guys!!! :slight_smile:

I for my part circumvent the problem of multiple servers by letting the old and new code coexist in the same app: it shows its new face to selected users and the old one to everyone else.

1 Like

@peterfkruger - that was doing to be my alternative suggestion also.

1 Like

I’m just thinking off the top of my head here:

  1. Could each client set a “blue” or “green” cookie which would get sent to the server with the request for __cordova/manifest.json? This cookie should then be available in the connectHandler.
  2. Could each server just HTTP.get() it’s own manifest from https://${myColor}.example.com/__cordova/manifest.json upon startup, and then regularly fetch the other manifest from https://${otherColor}.example.com/.... Or instead of regular polling, at startup each server could GET it’s own manifest and then POST its new manifest to a custom connectHandler endpoint on the other server).

This all seems like a lot of hacking though. Would it not be simpler to wrap the old and new code in conditionals as per @peterfkruger’s suggestion?

1 Like

Peter,

We’ve been avoiding the two server sets hurdle the same way you are doing. Mainly when we wanted to add new features.

This time our new version is actually a new Meteor version (upgrade to 1.10.2) after skipping a couple of versions.

So doing a second set of server did really help for our desktop users. Switching them gradually lessened the stress on our team and improved the overall stability of the product for most customers.

That’s why we’ve tried replicating this idea for our Cordova users as well.

1 Like

Wildhart,

It’s your #1 I cannot get to work.

That specific request (and those that downloads the new packages) do not seem to come from the meteor app itself but probably from the native cordova plugins.

After doing a tcpdump of the request, there does not seem to be any relevant information there that our web proxy could use to route requests:

GET /__cordova/manifest.json HTTP/1.1
Host: devjf.hoptimizepro.com
Accept-Encoding: gzip
User-Agent: okhttp/3.1.2
X-Forwarded-For: 75.14.175.173

If we could add either a cookie or change the URL of that request, our proxy would be able to route it accordingly. That would even prevent the need to do your #2 hack.

Thank you for clarifying that. It makes total sense.

Thanks for your help everyone.

I’m still very surprised no Meteor user has ever tried to do what we’re trying to do. I totally understand why… HCP seems to be very much of a black box that works well enough so nobody needs to open that box :slight_smile:

Maybe in a future version we’ll try to improve HCP’s code to be able to change the server dynamically or something similar. If it’s going to help somebody else.

Again, thanks a lot everyone :slight_smile:

Burni