Skip to content

Commit

Permalink
Merge 42625d5 into 5de4d92
Browse files Browse the repository at this point in the history
  • Loading branch information
peuter committed Sep 18, 2017
2 parents 5de4d92 + 42625d5 commit 5f17919
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 6 deletions.
12 changes: 10 additions & 2 deletions config.json
Expand Up @@ -150,7 +150,8 @@
"version",
"library_version.inc.php",
"manifest.json",
"../node_modules/monaco-editor"
"../node_modules/monaco-editor",
"ServiceWorker.js"
]
}
},
Expand Down Expand Up @@ -307,6 +308,13 @@
}
},

"update-version-cache": {
"shell" :
{
"command" : "utils/update_version.py worker"
}
},

"build" :
{
"extend" : [ "parts-config" ],
Expand All @@ -318,7 +326,7 @@
"run" :
[
"build-resources",
"update-version",
"update-version-cache",
"build-script",
"build-files",
"build-libs",
Expand Down
14 changes: 14 additions & 0 deletions doc/manual/de/config/url-params.rst
Expand Up @@ -217,3 +217,17 @@ In der Entwicklerversion sind diese standardmäßig eingeschaltet in einem Relea
Default: false im Release, true in Entwicklerversion
Options: true (log=true), false (log=false)
.. _worker:

*worker* - ServiceWorker Cache in der Entwicklerversion einschalten

In der Entwicklerversion ist der ServiceWorker zum Caching der Dateien abgeschaltet, damit man Änderungen
während des Entwickelns beim neu Laden direkt testen kann. Mit diesem URL-Parameter kann der ServiceWorker
trotzdem eingeschaltet werden

.. code::
Default: false (worker=false)
Options: true (worker=true) [nur in Entwicklungsversion, in einem Release hat dieser Parameter eine Funktion]
147 changes: 147 additions & 0 deletions source/ServiceWorker.js
@@ -0,0 +1,147 @@
/**
* ServiceWorker for the CometVisu
*
* @author Tobias Bräutigam
* @since (0.11.0) 2017
*/

var CACHE = "cv-cache-v2";
var NO_CACHE_TEST = /.+\.php$/i;
var CONFIG_TEST = /.+visu_config.*\.xml.*/i;
var config = {};
var updateQueue = [];
var queueTid = null;

self.addEventListener('message', function(event) {
var data = event.data;

console.log(data);
if (data.command === "configure") {
config = data.message;
}
});

self.addEventListener('install', function(event) {
// take over right now
console.log("install");
});

// delete old caches after activation
self.addEventListener('activate', function(event) {
console.log("activate");
var cacheWhitelist = [CACHE];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});

self.addEventListener('fetch', function(ev) {
if (config.disableCache === true ||
!ev.request.url.startsWith(this.registration.scope) ||
CONFIG_TEST.test(ev.request.url)
) {
// fallback to "normal" behaviour without serviceWorker -> sends HTTP request
return;
}

if (!NO_CACHE_TEST.test(ev.request.url) &&
(!ev.request.headers.pragma || ev.request.headers.pragma !== "no-cache") &&
(!ev.request.headers['Cache-Control'] || ev.request.headers['Cache-Control'] !== "no-cache")
) {

ev.respondWith(fromCache(ev.request).then(function(response){
// console.log(ev.request.url+" from cache");
if (config.forceReload === true) {
update(ev.request);
} else {
updateQueue.push(ev.request);
if (queueTid) {
clearTimeout(queueTid);
}
queueTid = setTimeout(processQueue, 1000);
}

return response;
}).catch(function () {
// not cached -> do now
// console.log("caching " + ev.request.url);
return fetchAndUpdate(ev.request);
}));
} else {
ev.respondWith(fromNetwork(ev.request));
}
});

function fromNetwork(request, timeout) {
return new Promise(function (resolve, reject) {
if (timeout) {
var timeoutId = setTimeout(reject, timeout);
}

fetch(request).then(function (response) {
if (timeoutId) {
clearTimeout(timeoutId);
}
resolve(response);
}, reject);
});
}

function processQueue() {
while (updateQueue.length) {
var request = updateQueue.shift();
update(request);
}
}

/**
* Get response from cache
* @param request {Request}
* @return {Response}
*/
function fromCache(request) {
return caches.open(CACHE).then(function (cache) {
return cache.match(request).then(function (matching) {
return matching || Promise.reject('no-match');
});
});
}

/**
* Fetch request from network and update the cache
* @param request {Request}
* @return {Promise}
*/
function update(request) {
caches.open(CACHE).then(function (cache) {
fetch(request).then(function (response) {
if (response.status < 400) {
cache.put(request, response);
}
});
});
}

/**
* Fetch request from network, update the cache and return the response
* @param request {Request}
* @return {Response}
*/
function fetchAndUpdate(request) {
return caches.open(CACHE).then(function (cache) {
return fetch(request).then(function (response) {
if (response.status < 400) {
cache.put(request, response.clone());
}
return response;
});
});
}
33 changes: 32 additions & 1 deletion source/class/cv/Application.js
Expand Up @@ -148,6 +148,8 @@ qx.Class.define("cv.Application",

console.log(info);

this.registerServiceWorker();

if (qx.core.Environment.get("qx.aspects")) {
qx.dev.Profile.stop();
qx.dev.Profile.start();
Expand Down Expand Up @@ -322,7 +324,7 @@ qx.Class.define("cv.Application",
var ajaxRequest = new qx.io.request.Xhr(uri);
ajaxRequest.set({
accept: "application/xml",
cache: !cv.Config.forceReload
cache: false
});
ajaxRequest.setUserData("noDemo", true);
ajaxRequest.addListenerOnce("success", function (e) {
Expand Down Expand Up @@ -564,6 +566,35 @@ qx.Class.define("cv.Application",
}
},

/**
* Install the service-worker if possible
*/
registerServiceWorker: function() {
if (cv.Config.useServiceWorker === true) {
navigator.serviceWorker.register('ServiceWorker.js').then(function(reg) {
this.debug("ServiceWorker successfully registered for scope "+reg.scope);

// configure service worker
var configMessage = {
"command": "configure",
"message": {
forceReload: cv.Config.forceReload
}
};

if (reg.active) {
reg.active.postMessage(configMessage);
} else {
navigator.serviceWorker.ready.then(function(ev) {
ev.active.postMessage(configMessage);
});
}
}.bind(this)).catch(function(err) {
this.error("Error registering service-worker: ", err);
}.bind(this));
}
},

/**
* Handle errors that occur during loading ot the config file
* @param textStatus {String} error status
Expand Down
18 changes: 17 additions & 1 deletion source/class/cv/Config.js
Expand Up @@ -174,6 +174,13 @@ qx.Class.define('cv.Config', {
*/
configServer: null,

/**
* If the CometVisu can use service workers
*/
useServiceWorker: false,

enableServiceWorkerCache : true,

/**
* Get the structure that is related to this design
* @param design {String?} name of the design
Expand Down Expand Up @@ -331,5 +338,14 @@ qx.Class.define('cv.Config', {
if (isNaN(cv.Config.use_maturity)) {
cv.Config.use_maturity = statics.Maturity.release; // default to release
}

cv.Config.useServiceWorker = 'serviceWorker' in navigator && (req.protocol === "https" || req.host === "localhost");

if (cv.Config.useServiceWorker) {
if (qx.core.Environment.get("qx.debug")) {
// disable service worker in dev environment unless the user wants it
cv.Config.useServiceWorker = req.queryKey.worker === "true";
}
}
}
});
});
14 changes: 12 additions & 2 deletions utils/update_version.py
Expand Up @@ -5,11 +5,13 @@
import datetime
import json
import os
import sys
import re

root_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..'))


def update_version():
def update_version(service_worker_cache=False):
# gather information from git
data = {
"revision": subprocess.check_output(["git", "rev-parse", "HEAD"]).strip("\n"),
Expand All @@ -34,5 +36,13 @@ def update_version():
});
''' % data)

if service_worker_cache is True:
regex = re.compile("var CACHE = \"(.+)\";", re.IGNORECASE)
with open(os.path.join(root_dir, "source", "ServiceWorker.js"), 'r+') as f:
content = f.read()
content = regex.sub("var CACHE = \"%s\";" % data['revision'], content)
f.seek(0)
f.write(content)

if __name__ == '__main__':
update_version()
update_version(len(sys.argv) == 2 and sys.argv[1] == "worker")

0 comments on commit 5f17919

Please sign in to comment.