reTHINK-project / dev-runtime-core

Javascript Runtime
Apache License 2.0
3 stars 3 forks source link

Improve Management of Local Storage Reset #276

Open pchainho opened 5 years ago

pchainho commented 5 years ago

Improve Storage Manager implementation in order to warn the user when availability storage is reaching a limit and / or when requesting storage persistence we got a false result (currently, the following log is printed: "Storage may be cleared by the UA under storage pressure" at https://github.com/reTHINK-project/dev-hyperty-toolkit/blob/develop/resources/factories/runtimeFactory.js#L72-L76).

We suspect DSM reset behavior was caused by this.

Check: https://storage.spec.whatwg.org/#dom-storagemanager-persist

pchainho commented 5 years ago

more references:

https://stackoverflow.com/questions/51657388/request-persistent-storage-permissions

luistduarte commented 5 years ago
var db;
imgurl = "dog.jpg";

function urlTo64(u, cb) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imgurl, true);
  xhr.responseType = 'blob';

  xhr.onload = function(e) {
    if (this.status == 200) {
      // get binary data as a response
      var blob = this.response;
      var reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = function() {
        base64data = reader.result;
        cb(base64data);
      }
    }
  };
  xhr.send();

}

function indexedDBOk() {
    return "indexedDB" in window;
}

var openRequest = indexedDB.open("tabletestindex",1);

openRequest.onupgradeneeded = function(e) {
  var thisDB = e.target.result;

  console.log("running onupgradeneeded");

  if(!thisDB.objectStoreNames.contains("imagesindex")) {
    thisDB.createObjectStore("imagesindex", {keyPath:"id",autoIncrement:true});
  }

}

openRequest.onsuccess = function(e) {
  console.log("running onsuccess");

  db = e.target.result;

  console.log("Current Object Stores");
  console.dir(db.objectStoreNames);

}

openRequest.onerror = function(e) {
  //Do something for the error
}

function addData() {

  urlTo64(imgurl, function(s) {
    console.log("s size",s.length);
    //Get a transaction
    //default for OS list is all, default for type is read
    var transaction = db.transaction(["imagesindex"],"readwrite");
    //Ask for the objectStore
    var store = transaction.objectStore("imagesindex");

    //Define data
    var data = {
        img:s
    }

    //Perform the add
    var request = store.add(data);

  });

}

Put this code on console of sharinglisboa.alticelabs.com, and call function addData N times until fill storage

For example

var nTimes=100;
var z;
for ( z=0; z<nTimes; z++ ) {
   addData();
}
pchainho commented 5 years ago

Running the above test it was confirmed when navigator.storage.persist() resolves false, when reTHINK storage manager reaches the storage limit (to evaluate the limit), using some other sites and coming back to reTHINK based App, the local storage is cleaned.

Looking at https://developers.google.com/web/updates/2016/06/persistent-storage it was found:

Chrome will automatically grant the persistence permission if any of the following are true:

The site is bookmarked (and the user has 5 or less bookmarks) The site has high site engagement The site has been added to home screen The site has push notifications enabled

Bookmarking reTHINK origin (in this case https://hybroker.rethink.ptinovacao.pt/ ) navigator.storage.persist() resolves true.

pchainho commented 5 years ago

Evaluate the usage of this API: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks/create

to add a bookmark to runtime origin.

Another option is to set push notifications: https://developers.google.com/web/fundamentals/push-notifications/

This should be done at runtime- browser inside the rethink framework and probably it is a more robust solution.

pchainho commented 5 years ago

It has been confirmed that enabling push notifications for the core, storage.persist(() is granted.

But permission request is not displayed when the origin is the App, only when the core domain is the origin.