Skip to content
Snippets Groups Projects
Commit 9ab73425 authored by Gabriel Engel's avatar Gabriel Engel
Browse files

Sync with new autoupdate

parent 428165ed
No related branches found
No related tags found
No related merge requests found
# autoupdate
[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/autoupdate) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/autoupdate)
***
This package is the heart of Meteor's Hot Code Push functionality. It has a
client component and a server component component. The client component uses a
......@@ -7,5 +9,5 @@ build of the app's client. When it sees that a new version is available, it uses
the [reload](https://atmospherejs.com/meteor/reload) package (if included in the
app) to gracefully save the app's state and reload it in place.
`autoupdate` is part of the [Webapp](https://www.meteor.com/webapp)
`autoupdate` is part of the [Webapp](https://github.com/meteor/meteor/tree/master/packages/webapp)
project.
......@@ -2,14 +2,12 @@ var DEBUG_TAG = 'METEOR CORDOVA DEBUG (autoupdate_cordova.js) ';
var log = function (msg) {
console.log(DEBUG_TAG + msg);
};
// This constant was picked by testing on iOS 7.1
// We limit the number of concurrent downloads because iOS gets angry on the
// application when a certain limit is exceeded and starts timing-out the
// connections in 1-2 minutes which makes the whole HCP really slow.
var MAX_NUM_CONCURRENT_DOWNLOADS = 30;
var MAX_RETRY_COUNT = 5;
var autoupdateVersionCordova = __meteor_runtime_config__.autoupdateVersionCordova || "unknown";
// The collection of acceptable client versions.
......@@ -24,169 +22,18 @@ Autoupdate.newClientAvailable = function () {
});
};
// var writeFile = function (directoryPath, fileName, content, cb) {
// var fail = function (err) {
// cb(new Error("Failed to write file: ", err), null);
// };
// window.resolveLocalFileSystemURL(directoryPath, function (dirEntry) {
// var success = function (fileEntry) {
// fileEntry.createWriter(function (writer) {
// writer.onwrite = function (evt) {
// var result = evt.target.result;
// cb(null, result);
// };
// writer.onerror = fail;
// writer.write(content);
// }, fail);
// };
// dirEntry.getFile(fileName, {
// create: true,
// exclusive: false
// }, success, fail);
// }, fail);
// };
// var restartServer = function (location) {
// log('restartServer with location ' + location);
// var fail = function (err) { log("Unexpected error in restartServer: " + err.message) };
// var httpd = cordova && cordova.plugins && cordova.plugins.CordovaUpdate;
// if (! httpd) {
// fail(new Error('no httpd'));
// return;
// }
// var startServer = function (cordovajsRoot) {
// httpd.startServer({
// 'www_root' : location,
// 'cordovajs_root': cordovajsRoot
// }, function (url) {
// if (Package.reload) {
// Package.reload.Reload._reload();
// } else {
// window.location.reload();
// }
// }, fail);
// };
// httpd.getCordovajsRoot(function (cordovajsRoot) {
// startServer(cordovajsRoot);
// }, fail);
// };
var hasCalledReload = false;
var updating = false;
var localPathPrefix = null;
// var onNewVersion = function () {
// if (!window.FileTransfer) {
// return;
// }
// var ft = new FileTransfer();
// var urlPrefix = Meteor.absoluteUrl() + '__cordova';
// HTTP.get(urlPrefix + '/manifest.json', function (err, res) {
// if (err || ! res.data) {
// log('Failed to download the manifest ' + (err && err.message) + ' ' + (res && res.content));
// return;
// }
// updating = true;
// ensureLocalPathPrefix(_.bind(downloadNewVersion, null, res.data));
// });
// };
// var downloadNewVersion = function (program) {
// if (!window.FileTransfer) {
// return;
// }
// var urlPrefix = Meteor.absoluteUrl() + '__cordova';
// var manifest = _.clone(program.manifest);
// var version = program.version;
// var ft = new FileTransfer();
// manifest.push({ url: '/index.html?' + Random.id() });
// var versionPrefix = localPathPrefix + version;
// var queue = [];
// _.each(manifest, function (item) {
// if (! item.url) return;
// var url = item.url;
// url = url.replace(/\?.+$/, '');
// queue.push(url);
// });
// var afterAllFilesDownloaded = _.after(queue.length, function () {
// var wroteManifest = function (err) {
// if (err) {
// log("Failed to write manifest.json: " + err);
// // XXX do something smarter?
// return;
// }
// // success! downloaded all sources and saved the manifest
// // save the version string for atomicity
// writeFile(localPathPrefix, 'version', version, function (err) {
// if (err) {
// log("Failed to write version: " + err);
// return;
// }
// // don't call reload twice!
// if (! hasCalledReload) {
// var location = uriToPath(localPathPrefix + version);
// restartServer(location);
// }
// });
// };
// writeFile(versionPrefix, 'manifest.json',
// JSON.stringify(program, undefined, 2), wroteManifest);
// });
// var downloadUrl = function (url) {
// console.log(DEBUG_TAG + "start downloading " + url);
// // Add a cache buster to ensure that we don't cache an old asset.
// var uri = encodeURI(urlPrefix + url + '?' + Random.id());
// // Try to download the file a few times.
// var tries = 0;
// var tryDownload = function () {
// ft.download(uri, versionPrefix + encodeURI(url), function (entry) {
// if (entry) {
// console.log(DEBUG_TAG + "done downloading " + url);
// // start downloading next queued url
// if (queue.length)
// downloadUrl(queue.shift());
// afterAllFilesDownloaded();
// }
// }, function (err) {
// // It failed, try again if we have tried less than 5 times.
// if (tries++ < MAX_RETRY_COUNT) {
// log("Download error, will retry (#" + tries + "): " + uri);
// tryDownload();
// } else {
// log('Download failed: ' + JSON.stringify(err) + ", source=" + err.source + ", target=" + err.target);
// }
// });
// };
// tryDownload();
// };
// _.times(Math.min(MAX_NUM_CONCURRENT_DOWNLOADS, queue.length), function () {
// var nextUrl = queue.shift();
// // XXX defer the next download so iOS doesn't rate limit us on concurrent
// // downloads
// Meteor.setTimeout(downloadUrl.bind(null, nextUrl), 50);
// });
// };
var retry = new Retry({
// Unlike the stream reconnect use of Retry, which we want to be instant
// in normal operation, this is a wacky failure. We don't want to retry
// right away, we can start slowly.
//
// A better way than timeconstants here might be to use the knowledge
// of when we reconnect to help trigger these retries. Typically, the
// server fixing code will result in a restart and reconnect, but
// potentially the subscription could have a transient error.
minCount: 0, // don't do any immediate retries
baseTimeout: 30*1000 // start with 30s
});
......@@ -228,98 +75,9 @@ Autoupdate._retrySubscription = function () {
}
};
// Meteor.startup(function () {
// clearAutoupdateCache(autoupdateVersionCordova);
// });
Meteor.startup(Autoupdate._retrySubscription);
// A helper that removes old directories left from previous autoupdates
// var clearAutoupdateCache = function (currentVersion) {
// ensureLocalPathPrefix(function () {
// // Try to clean up our cache directory, make sure to scan the directory
// // *before* loading the actual app. This ordering will prevent race
// // conditions when the app code tries to download a new version before
// // the old-cache removal has scanned the cache folder.
// listDirectory(localPathPrefix, {dirsOnly: true}, function (err, names) {
// // Couldn't get the list of dirs or risking to get into a race with an
// // on-going update to disk.
// if (err || updating) {
// return;
// }
// _.each(names, function (name) {
// // Skip the folder with the latest version
// if (name === currentVersion)
// return;
// // remove everything else, as we don't want to keep too much cache
// // around on disk
// removeDirectory(localPathPrefix + name + '/', function (err) {
// if (err) {
// log('Failed to remove an old cache folder '
// + name + ':' + err.message);
// } else {
// log('Successfully removed an old cache folder ' + name);
// }
// });
// });
// });
// })
// };
// Cordova File plugin helpers
// var listDirectory = function (url, options, cb) {
// if (typeof options === 'function')
// cb = options, options = {};
// var fail = function (err) { cb(err); };
// window.resolveLocalFileSystemURL(url, function (entry) {
// var reader = entry.createReader();
// reader.readEntries(function (entries) {
// var names = [];
// _.each(entries, function (entry) {
// if (! options.dirsOnly || entry.isDirectory)
// names.push(entry.name);
// });
// cb(null, names);
// }, fail);
// }, fail);
// };
// var removeDirectory = function (url, cb) {
// var fail = function (err) {
// cb(err);
// };
// window.resolveLocalFileSystemURL(url, function (entry) {
// entry.removeRecursively(function () { cb(); }, fail);
// }, fail);
// };
// var uriToPath = function (uri) {
// return decodeURI(uri).replace(/^file:\/\//g, '');
// };
// var ensureLocalPathPrefix = function (cb) {
// if (! localPathPrefix) {
// if (! cordova.file.dataDirectory) {
// // Since ensureLocalPathPrefix function is always called on
// // Meteor.startup, all Cordova plugins should be ready.
// // XXX Experiments have shown that it is not always the case, even when
// // the cordova.file symbol is attached, properties like dataDirectory
// // still can be null. Poll until we are sure the property is attached.
// console.log(DEBUG_TAG + 'cordova.file.dataDirectory is null, retrying in 20ms');
// // REMOVED to prevent loop in new app
// // Meteor.setTimeout(_.bind(ensureLocalPathPrefix, null, cb), 20);
// } else {
// localPathPrefix = cordova.file.dataDirectory + 'meteor/';
// cb();
// }
// } else {
// cb();
// }
// };
window.WebAppLocalServer = {};
WebAppLocalServer.startupDidComplete = function() {};
WebAppLocalServer.checkForUpdates = function() {};
......
......@@ -3,11 +3,6 @@ Package.describe({
version: '1.2.11'
});
Cordova.depends({
'cordova-plugin-file': '4.1.1',
'cordova-plugin-file-transfer': '1.5.1'
});
Package.onUse(function (api) {
api.use([
'webapp',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment