2017-07-25 1 views
0

J'ai construit un wrapper très mince autour de Google Cloud Storage pour le faire ressembler plus à localStorage. Je sais que le même objet ne peut être écrit qu'une fois par seconde, mais ce code n'écrit jamais rien plus vite qu'une fois par seconde et je n'arrive pas à comprendre pourquoi. J'ai confirmé que les noms d'objets sont différents lors de l'utilisation du code.Pourquoi l'habillage fin de Google Cloud Storage est-il si lent pour le téléchargement?

(function() { 
    // a Google Cloud Storage API modeled somewhat after localStorage 
    class CloudStore { 
     constructor(name) { 
      const me = this, 
       Storage = require('@google-cloud/storage'); 
      me.storage = Storage(); 
      me.bucket = me.storage.bucket(name+"_anywhichway"); 
      me.bucket.exists().then((data) => { 
       data[0] || me.storage.createBucket(name+"_anywhichway") 
          .then((data) => me.bucket = data[0]); 
       me.bucket.getFiles((data) => { 
        !data || (me.files = data[0]); 
       }) 
      }); 
     } 
     async clear() { 
      await this.bucket.deleteFiles({force:true}); 
     } 
     async count() { 
      return (this.files ? this.files.length : 0); 
     } 
     async delete(id) { 
      this.storageProvider.removeItem(id); 
      if(!this.files) { 
       [this.files] = await this.bucket.getFiles(); 
      } else { 
       const i = this.files.findIndex((item) => item.name===id); 
       i===-1 || this.files.splice(0,i,1); 
      } 
     } 
     async get(id) { // usually around 3,300 rec/sec 
      const me = this, 
       streams = require('memory-streams'); 
      return new Promise((resolve,reject) => { 
       const writable = new streams.WritableStream(); 
       me.bucket.file(id).createReadStream({validation:false}) 
        .on('error', (err) => { console.log(id,err.message); }) 
        .on('response', (response) => { }) 
        .on('end',() => { resolve(writable.toString()); }) 
        .pipe(writable); 
      }); 
     } 
     async key(number) { 
      if(this.files[number]) return this.files[number].name; 
     } 
     async set(id,data) { // never faster than 1.01 rec/sec 
      const me = this; 
      return new Promise((resolve,reject) => { 
       const file = me.bucket.file(id), 
        stream = file.createWriteStream(); 
       stream.end(data,"utf8",async() => { 
        // only get the file list once from Google 
        // then manage a pseudo-list locally for speed 
        // tried commenting this out to see if it improved 
        // performance, it did not 
        if(!me.files) { 
         [me.files] = await me.bucket.getFiles(); 
        } else { 
         me.files.push({name:id}); 
        } 
        resolve(id); 
       }); 
      }); 
     } 
    } 
    module.exports = CloudStore; 
}).call(this); 

Code d'essai:

const storage = new CloudStore("test"); 
const size = 10, 
start = Date.now(); 
for(let i=0;i<size;i++) { 
     await storage.set("Object#"+i,JSON.stringify({item:i})); 
} 
const set= Date.now(); 
let expired = set- start, 
    persec = size/(expired/1000); 
console.log("set",expired,persec); 

Répondre

1

Il se trouve que l'API fournie par Storage = require('@google-cloud/storage'); est assez lent et seulement approprié pour les objets plus grands. L'utilisation du more direct JSON API avec POST se déplace à raison de plus de 150 sauvegardes d'objet par seconde.