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.

Saturday, February 15, 2014

Bottling Day

I've had a batch of homebrew beer that I've been fermenting for nearly a month (brewed on the 20th of January) that I got a chance to bottle today.  For those who are beer-savvy, it's a Pliny the Elder clone, and for everyone else, it's one of the more famous very hoppy, 8-9% alcohol IPAs in California.  (For the homebrewers out there, I used this recipe)



The materials for five gallons, roughly ~50 12 ounce beers, were $75, which is pretty exorbitant as homebrews go -- it's usually $30 or so.   If you were to buy that much Pliny in the store, it would be $150 - $175, so I'm obviously making money!

That's all Pliny the Elder

So you may notice that there are four gallons there instead of five, and that's right -- it turns out that this recipe requires a step in the fermentation process that filters out part of the beer, and with this recipe, there's a bunch (a gallon) of gunk that gets filtered out in that process.  With these kinds of beers, you actually have to brew more than your target 5 gallons, which I didn't do.

I'm sure double IPAs are nowhere near healthy, but I can't wait to try this in a week.

Also: Season 2 of House of Cards.  Sooo good.  'Nuff said.

Valentine's Handstand Day

(I'm posting this one day late because I had it written yesterday and Valentie's day going-out shenanigans prevented me from posting...)

I've never found a good way to get cut roses / flowers home in the car from the store.  If you're lucky, the store wraps them up and you get a top-heavy cone-object that rolls around and falls over when you turn.  The whole package is too big to fit into the cup holder, and if its in the back seat, you can't move it if it falls.  I just end up having to hold them into the passenger seat with one hand while driving with the other.  I've found my next product problem to solve, obviously...

Anyways, in my morning workout today, the programming had us doing handstand pushups, which beyond being the most f'ing impossible thing to do, I find to be one of my personal weaknesses in Crossfit.  And the workout prescribed 60 of them!  Ugh.

So it's supposed to look kind of like this:

   _  |       _ |
    |  |        / |
__|  |        | |
|   o |      o| |

I've had shoulder mobility issues in the past, so putting my arms over and behind my head is pretty tough.  My 'overhead position' looks like my arms are out in front of my face and not back behind my ears, which if you are trying to support your own weight, can be a killer.  So, instead, I have to put multiple pads under my head, and kip my legs straight up in the air, which pulls me off the wall.  Not to mention I can't really kick up onto the wall into a handstand, so I have to kick up into a headstand instead.

All in all, it looks like I kick up into headstand, bring my knees to my chest, and kick straight up, which pushes me off the wall and I fall on my face.  It looks kind of like this:

   _  |    _    |                     |
    |  |      \   |                     |
__|  |      |   |                     |
|   o |      |o |      |--------o |

So I cut the number down to 30 to limit the injury to my pride.  Mixed with heavy deadlifts, it was a blast of a workout :)

I think I'm held back quite a bit by flexibility, and not easily putting my arms back behind my ears in a full locked-out position, which also holds back jerks, overhead squats, etc.  Anyone have good shoulder mobility recommendations?


Thursday, February 13, 2014

Trying something new for 30 days

Matt Cutts famously gave a talk at TED about trying something new for 30 days.  It's a great idea for all of the reasons he gives in the talk, but it's an utterly terrifying prospect for the uninitiated.

I'm going to try writing something on this blog -- which, obviously, I haven't written on for years -- every day for 30 days.  And this is scary because I'm sure I'm going to either run out of interesting things to say or my poor skill in writing will shine through.  But I want to improve myself, both in my written communication, and having a presence online that consists of more than a photo.

Anyways, since this is a new exercise, and I have to write no matter what, there are going to be some days over the next thirty that I wander off topic and sound like a rambling idiot.  Lucky you!  So I'm going to spill my opinions on things, talk about tech, the user-agent switching Chrome extension that I work on, Crossfit, beer brewing, etc., so maybe that will keep it spicy.

Here's to 30 days.  Cheers!

Saturday, November 21, 2009

WOD 11/19

Oops, almost forgot to post the WOD from my very first crossfit class!

Warm-up:
650m Run (around the block)
Progression of Double-unders and knees-to-elbows: 10 9 8 7 6 5 4 3 2 1

3x Squats (face the wall and hold for 20 seconds, 7 seconds rest)
5x3 Weighted push-ups (70#)

15 minutes of Thrusters (20#) vs. 500m row

At the very end, my calves were cramping up. This is the first workout that ever got my legs to cramp up during the workout!

Tuesday, November 17, 2009

Workout of the Day, 11/17/2009

650m run

21 reps: 175# bench, pull-ups (4:27)
15 reps: 160# bench, pull-ups (3:43)
9 reps: 145# bench, pull-ups (2:02)

3 sets of 7 burpees
100 crunches

(had to lighten the bench press weight since I couldn't get the bar moving at all)

Sunday, November 15, 2009

Workout of the Day

Seeing as I just joined Crossfit, I'll definitely need to post my WOD!

This workout is my modification of the base workout, since there are no good places to do pull-ups along the Embarcadero.

Run 650m (Red's Java House -> "dog park" at South Beach)
40 lunges
30 push-ups
20 sit-ups
10 burpees