Make WMS server selection deterministic, by using a real number hashing algorithm on the parameter string to select the server URL. Also, patch TMS since it doesn't use getFullParameterString(). Passes all tests. Fixes #410.

git-svn-id: http://svn.openlayers.org/trunk/openlayers@2821 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Schuyler Erle
2007-03-20 00:00:17 +00:00
parent 40a7cd881c
commit 15b26252bc
4 changed files with 61 additions and 12 deletions

View File

@@ -90,6 +90,18 @@ OpenLayers.Layer.HTTPRequest.prototype =
this.params = OpenLayers.Util.extend(this.params, newParams); this.params = OpenLayers.Util.extend(this.params, newParams);
}, },
/**
* @param {String} paramString
* @param {Array(String)} urls
*/
selectUrl: function(paramString, urls) {
var product = 1;
for (var i = 0; i < paramString.length; i++) {
product *= paramString.charCodeAt(i) * (Math.sqrt(5) - 1) / Math.sqrt(3);
product -= Math.floor(product);
}
return urls[Math.floor(product * urls.length)];
},
/** combine url with layer's params and these newParams. /** combine url with layer's params and these newParams.
* *
@@ -109,15 +121,6 @@ OpenLayers.Layer.HTTPRequest.prototype =
// use layer's url unless altUrl passed in // use layer's url unless altUrl passed in
var url = (altUrl == null) ? this.url : altUrl; var url = (altUrl == null) ? this.url : altUrl;
// if url is not a string, it should be an array of strings,
// in which case we will randomly select one of them in order
// to evenly distribute requests to different urls.
if (typeof url == "object") {
url = url[Math.floor(Math.random()*url.length)];
}
// requestString always starts with url
var requestString = url;
// create a new params hashtable with all the layer params and the // create a new params hashtable with all the layer params and the
// new params together. then convert to string // new params together. then convert to string
var allParams = OpenLayers.Util.extend(new Object(), this.params); var allParams = OpenLayers.Util.extend(new Object(), this.params);
@@ -131,6 +134,17 @@ OpenLayers.Layer.HTTPRequest.prototype =
} }
} }
var paramsString = OpenLayers.Util.getParameterString(allParams); var paramsString = OpenLayers.Util.getParameterString(allParams);
// if url is not a string, it should be an array of strings,
// in which case we will deterministically select one of them in
// order to evenly distribute requests to different urls.
if (url instanceof Array) {
url = this.selectUrl(paramsString, url);
}
// requestString always starts with url
var requestString = url;
if (paramsString != "") { if (paramsString != "") {
var lastServerChar = url.charAt(url.length - 1); var lastServerChar = url.charAt(url.length - 1);
if ((lastServerChar == "&") || (lastServerChar == "?")) { if ((lastServerChar == "&") || (lastServerChar == "?")) {

View File

@@ -75,7 +75,12 @@ OpenLayers.Layer.TMS.prototype =
var x = (bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w); var x = (bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w);
var y = (bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h); var y = (bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h);
var z = this.map.getZoom(); var z = this.map.getZoom();
return this.url + "1.0.0" + "/" + this.layername + "/" + z + "/" + x + "/" + y + "." + this.type; var path = "1.0.0" + "/" + this.layername + "/" + z + "/" + x + "/" + y + "." + this.type;
var url = this.url;
if (url instanceof Array) {
url = this.selectUrl(path, url);
}
return url + path;
}, },
/** /**

View File

@@ -89,7 +89,7 @@
tParams = { layers: 'basic', tParams = { layers: 'basic',
format: 'image/png'}; format: 'image/png'};
t.plan( 9 ); t.plan( 12 );
// without ? // without ?
tUrl = "http://octo.metacarta.com/cgi-bin/mapserv"; tUrl = "http://octo.metacarta.com/cgi-bin/mapserv";
@@ -147,9 +147,35 @@
layer = new OpenLayers.Layer.HTTPRequest(name, "chicken", tParams, null); layer = new OpenLayers.Layer.HTTPRequest(name, "chicken", tParams, null);
str = layer.getFullRequestString(null, tUrl); str = layer.getFullRequestString(null, tUrl);
t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url sans ?"); t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for url sans ?");
// single url object
tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv"];
layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);
str = layer.getFullRequestString();
t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for list of one url");
// two url object
tUrl = ["http://octo.metacarta.com/cgi-bin/mapserv","http://labs.metacarta.com/cgi-bin/mapserv"];
layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);
str = layer.getFullRequestString();
t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(tParams), "getFullRequestString() works for list of two urls");
str = layer.getFullRequestString({'a':'f'});
t.eq(str, tUrl[1] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'a':'f'})), "getFullRequestString() works for list of two urls and is deterministic");
} }
function test_04_Layer_HTTPRequest_selectUrl (t) {
t.plan( 4 );
layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options);
urls = ["wms1", "wms2", "wms3", "wms4"];
t.eq( layer.selectUrl("bbox=-180,0,0,90", urls), "wms4", "selectUrl(-90,-180) returns 4" );
t.eq( layer.selectUrl("bbox=-180,-90,0,0", urls), "wms3", "selectUrl(90,-180) returns 3" );
t.eq( layer.selectUrl("bbox=0,90,180,0", urls), "wms1", "selectUrl(-90,180) returns 1" );
t.eq( layer.selectUrl("bbox=0,0,180,90", urls), "wms2", "selectUrl(90,180) returns 2" );
}
function test_99_Layer_HTTPRequest_destroy (t) { function test_99_Layer_HTTPRequest_destroy (t) {
t.plan( 6 ); t.plan( 6 );

View File

@@ -106,7 +106,7 @@
*/ */
function test_10_Layer_TMS_getURL(t) { function test_10_Layer_TMS_getURL(t) {
t.plan(1); t.plan(2);
var map = new OpenLayers.Map('map', options); var map = new OpenLayers.Map('map', options);
var options = {'layername':'basic', 'type':'png'}; var options = {'layername':'basic', 'type':'png'};
@@ -115,6 +115,10 @@
map.setCenter(new OpenLayers.LonLat(0,0), 9); map.setCenter(new OpenLayers.LonLat(0,0), 9);
var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));
t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/192.png", "Tile URL is correct"); t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/192.png", "Tile URL is correct");
layer.url = ["http://tilecache1/", "http://tilecache2/", "http://tilecache3/"];
tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));
t.eq(tileurl, "http://tilecache2/1.0.0/basic/9/261/192.png", "Tile URL is deterministic");
} }
function test_11_Layer_TMS_setMap(t) { function test_11_Layer_TMS_setMap(t) {