Sunday, February 16, 2014

Latest Version

I work on a Chrome extension for spoofing the browser's user-agent string to websites, which comes in handy with testing web applications, getting around sites that roadblock certain browsers, etc.  I initially wrote it when I was a Product Manager for Chrome, and site compatibility was terrible -- I wanted to be able to automatically detect it and spoof the user-agent to be able to use normal websites that blocked Chrome for no reason.

Anyways, I used to work on the extension more actively pre-kidlet, but I get a few minutes here and there to work on it still.  The latest version you can get on the Chrome webstore is actually pretty old (six months or more?), and I have a much newer version that I've had ready for a while.  It's still not released because the current version is a pretty massive refactoring from what it was previously.

Specifically, the way that Chrome extensions used to have to save data "back in the day" is by using naive localstorage in the context of the extension.  So, simply:

localStorage[key] = JSON.stringify(value);

But this has some limitations, and when people started asking me for new features, this didn't quite work anymore.  For instance, localStorage limited me to only storing string data...but I needed to store more complex structures.  It was slow and serial, but nice that it has a big storage limit, so you could save as many settings as you wanted without realistically running out of allowed storage.

So when Chrome finally introduced a data storage mechanism specifically for extensions, I had to rewrite all of the storage to use the new method:

chrome.storage.sync.set(object, function callback() {...});

This seems innocuous, but it requires a lot of work:

  • I have to migrate all the existing localstorage values into this structure.  If I mess it up, everyone's settings are borked
  • It has a callback, which means I can't just 'fire and forget' -- I have to handle the callback and update caches, etc.
  • It has a callback, so I have to change all of the functions that would call to save settings to also be structured as callbacks.  So now I get some calls that are 4-5 nested callbacks deep -- other JS folks know what I mean when they see function() { function() { function() { ... 
  • It has a much smaller size limit on individual objects than localStorage, so I can't just cram everything into the same object to be saved.  I have to break them up.  Which means what I really have to do is:


chrome.storage.sync.set(object1, function callback() {...});
chrome.storage.sync.set(object2, function callback() {...});
...
chrome.storage.sync.set([array of pointers to objects], function callback() {...});

Barf.

As you can imagine, this forced me to rewrite massive sections of the extension.  This gives the ability to use Chrome Sync to save your settings across browsers.  However, it also means that the extension has been changed significantly, so it could have broken in subtle ways.  So I've been holding onto the current version (with other new features) out of fear of breaking my users terribly and little time to roll back / fix immediate issues.

What do others think, should I just suck it up and release it, and deal with the brokenness?  I don't want to piss off people who rely on this thing working every day.  However, not releasing it means they don't get improvements / features / fixes.

No comments:

Post a Comment