puffpio [dot] com http://puffpio.com Most recent posts at puffpio [dot] com posterous.com Fri, 09 Sep 2011 21:25:00 -0700 Tracking the generational/viral effects of the Like button http://puffpio.com/tracking-the-generationalviral-effects-of-the http://puffpio.com/tracking-the-generationalviral-effects-of-the

Note: I'm sure a ton of people do this, and I'm sure it's been documented before..but a quick search for "generational effects like button" yielded nothing interesting on the top half of the first page of the search results so imma write this.

Sometimes when your shit goes viral it would be nice to measure HOW viral..how is the fanout. Someone "likes" your page. Then it posts a Like story to Facebook. Their friends see it and click the link. Then they hit "like" too. And so on and so on. Your site starts getting a ton of hits, life is awesome. But how awesome was it really? Did a ton of poeple find it organically on thier own and then liked it? Or was it more of a viral thing where people saw the Like story and clicked. And how many "generations" did it go through before it started dying out?

Turns out there's a sweet way to Make This Happen. Check out this code snippet for a Like button:

1
2
<fb:like href="http://themostawesomestwebsiteevar.com"
  send="false" width="450" show_faces="true" ></fb:like>

I removed all the javascript part of it, but you get the gist (HAR!). When a user clicks this like button, it will create a story on their newsfeed. If their friends see it and click on it, they'll be taken to http://themostawesomewebsiteevar.com and life is good. But now check out this version:

1
2
<fb:like href="http://themostawesomestwebsiteevar.com"
  send="false" width="450" show_faces="true" ref="1" ></fb:like>

Looks identical, right? But there is a ref="1" tacked on there. What does it mean? Well this time, when a friend clicks the story, they are taken to http://themostawesomewebsiteeavar.com?fb_ref=1&fb_source=home. BOOM. Now you can track if the visitor came in organically, or if they came in because someone clicked on a post in their newsfeed. fb_source can also tell you if they clicked on it from a person's profile, or other places, but that's not important now. What if fb_ref could increment on every generation? Then you would be able to tell if someone visited the page because someone clicked "Like," then their friend saw it and clicked "Like," then THEIR friend saw it and clicked "Like" etc etc etc.

You now have a way of measuring your Like viral fanout. You could compile stats saying "x thousand pageviews came from a 1st generation like story, y thousand pageviews came from a 2nd generation like story, z bazillion pageviews came from a 3rd generation like story." Neato.

So how do you do this autoincrementing magic? Check out this snippet written using Javascript using nodejs, the expressjs framework, and the mustache templating language:

1
2
3
4
5
6
7
app.get('/test/generations', function(req, res) {
  var generation = req.query.fb_ref || 0;
  generation++;

  // my own wrapper on mustache just encapsulating some stuff
  mu.r('test', { generation: generation }, res);
});

The server reads the querystring param if it exists, and increments the generation count. Then my like button code in my mustache template file would like this:

1
2
<fb:like href="http://themostawesomestwebsiteevar.com"
  send="false" width="450" show_faces="true" ref="{{generation}}" ></fb:like>

Neat huh? That ref parameter can be expanded to do more than just track a generation. It could hold a hash value to some table in your database which tracks much more. The sky is the limit. The possibilities are endless. The world is your oyster. Take a look, it's in a book, reading rainbow.

Docs for the Like Button are here.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 18 Mar 2011 17:59:00 -0700 ESPN3 is awesome in an unintended way http://puffpio.com/espn3-is-awesome-in-an-unintended-way http://puffpio.com/espn3-is-awesome-in-an-unintended-way

So today marked the beginniing of qualifying for the first round of the ALMS and ILMC at Sebring International Raceway. It's only available streaming live on ESPN3.com so I duly headed over to that website and found the link to watch. Now, ESPN3 is setup so that you need to have ESPN at home in order to watch it. What happens when you try to watch a video is that it forces you to select your cable provider and then sends you to your cable company's website. From there you can login to your cable company, and it will send you back to ESPN3 in order to watch the videos.

Sounds nice, but I'm in the middle of a move, so I have my cable cancelled. I duly clicked on the link to watch the video, selected my former cable tv company and entered in my old login information praying it would work. It redirected back to ESPN3 but with a message saying "Sorry, you do not have the appropriate package" or something like that. :( My first thought was to ask a friend with cable for their login and password, but before I did that I clicked on the video again.

And what do you know, the show started playing just fine! MUAHAHAHAHHAA. I hope they never fix this

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 21 Jan 2011 22:00:00 -0800 Avoiding the 10 East freeway suckage http://puffpio.com/avoiding-the-10-east-freeway-suckage http://puffpio.com/avoiding-the-10-east-freeway-suckage

I wrote this for a friend to give him some tips and tricks for avoiding the crappy 10 East traffic during evening rush hour. I decided to repost this here so everyone can read it. Feel free to add more tips to avoid slow spots! It doesn't have to be on the 10 East, but on any highway!

-------------------------------

The 10 eastbound sucks soooo much here's what I do.

----------- WEST LA TO 110 ---------------

I am guessing you get onto the 10 around Robertson or La Cienega, but that is a bad place to get on cuz all these on ramps and lanes are merging
If you can, go past the 10 freeway and get onto Adams which runs parallel to the 10. MUCH FASTER

You can take Adams all the way to USC and get back on the 10 at Vermont or the next one...BUT here is another tip:
From Adams, get back on the 10 at La Brea...the way the on ramp is designed, it doesn't merge into the 10 but it opens up a new lane so it's not as slow.
Once you get on the freeway dont change any lanes, stay in the right most lane...pass Crenshaw.

After you pass Crenshaw, another lane will open on your right that started from the Crenshaw on-ramp
It only lasts till the next exit (Arlington) and then it goes off the freeway.
GET IN THIS LANE it's so fast even for just 1/2 mile

Just duck back into the 10 right at the end OR; if you think you can time it, exit Arlington and just drive straight back onto the 10. Sometimes I try to time it so I exit Arlington, hit the green light and right back onto the 10.

If you decided to duck back onto the 10 and not exit Arlington..stay in the right lane..it will exit off into it's own 2 lane minifreeway that is separate from the main 10. This minifreeway is WAY faster than the main 10.
If you decided to exit Arlington and go straight back onto the 10, you will automatically be placed in this minifreeway.

Stay on this minifreeway, pass Western, pass Normandie, then merge back onto the main 10 after Normandie.
You don't wanna stay on this minifreeway at this point cuz it merges down to 1 lane at the 110.

-------------- 110 to downtown LA ---------------------------

After you get back onto the main 10, stay in the right most lane you should be already in.
Eventually you will hit the 110 interchange..continue to stay in your lane as you separate from the main 10 freeway.

Once you separate from the main 10 freeway, move one lane to the left. The reason being you are now at the point where that minifreeway merges back, and there will be a ton of cars changing lanes. There will also be cars stopped in the middle lane (the one you were in) trying to get to the right lane cuz they want to get on the 110.
So stay in the left lane at this point to avoid those stopped cars.

Once you pass the 110 offramp, immediately move 2 lanes to the right so you are in the right most lane. This piece will not rejoin the 10 freeway just yet. However you will see up ahead where it rejoins...sometimes the lane that rejoins is jammed...if it's jammed just exit the freeway. If not, rejoin the main 10.

If you exited the 10 you should be on a one way street going east, south of the staples center.
If this one way street is not crowded, just drive on it all the way till you see a 10E entrance at Los Angeles St and get on there.

If it's crowded, make a left to go under the 10 freeway and then make a right on Venice and make another right on Los Angeles St. You will be at the same 10E entrance, but from the opposite side of the freeway

Enter back on the freeway here. 

--------------------- downtown LA to the 10/60/5 split ------------------

At this point you should be in the right lane of the 10 either just getting on from Los Angeles St, or you just stayed on the 10 cuz it wasn't crowded enough.
Stay in the right lane cuz it splits into 2 lanes and most people take the left one.

If the 10 is still slow, take the next exit Central. just exit the freeway them immediately get back on...you just skipped a bunch of traffic :D
Once you are back on the 10, I usually immediately exit Alameda cuz I'm going to head for an alternate route around the 5 South..but for you get back on the 10

Exit Santa Fe, but you will notice once you are on there, it can just rejoin back up to the 10E, or it can go back to the 60E/5S interchange.  If you want to take the 10E, take it from here. Otherwise continue on this little side road till you get back up to the 60E/5S split and take the 60E

---------------------

that's all i know!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Wed, 10 Nov 2010 00:29:00 -0800 What I want for asynchronous WCF clients and C#5 async/await http://puffpio.com/what-i-want-for-asynchronous-wcf-clients-and http://puffpio.com/what-i-want-for-asynchronous-wcf-clients-and

I have a problem with Adding a Service Reference (and thus using svcutil). It generates proxy interfaces and proxy datatypes. If my WCF service used custom datatypes, the service reference would create a proxy datatype for it. This gives me headaches because I think I have a type Foo when in fact I have a proxied version. Now I have to cast between them. Also, if I have added two service references and they used the same datatype, guess what? It will generate two different proxied datatypes. And if I change anything about the service or the datatypes, I need to regenerate the service reference. What a pain.

Instead, I do something like this:

[ServiceContract] public interface IContract {    [OperationContract]    int Add(int a, int b); } public class MyClient : ClientBase<IContract>, IContract {    public int Add(int a, int b) { return base.Channel.Add(a, b); } }

Nice and clean huh? The WCF client uses the same interface and same datatypes as the service so no need to regenerate service references. It's tightly coupled and I also get compile time errors if I change the service interface. The only problem is that doing it this way does not generate asynchronous client methods.

The Visual Studio Async CTP gives a sneak preview into the future of the language. It adds two new keywords async and await which make it dead simple to convert regular code into asychronous code. I won't go into detail on how it works, but in addition to the language/compiler changes it also includes a bunch of extension methods that add this new style of asynchronous access to a bunch of preexisting classes that have asynchronous methods. For example, TextWriter contains a synchronous Write() as well as the asynchronous BeginWrite() and EndWrite(). This CTP adds WriteAsync() which wraps the BeginWrite() and EndWrite() into this new async/await syntax. What I envision, and what I hope happens is that they also do some work on WCF client generation (hopefully not using svcutil, but extending ClientBase). I want there to be something like this:

[ServiceContract] public interface IContract {    [OperationContract]    int Add(int a, int b); } public class MyAsyncClient : AsyncClientBase<IContract>, IAsyncContract<IContract> {    public async Task<int> AddAsync(int a, int b) { return await base.AsyncChannel.AddAsync(a, b); } }

That's my pipe dream. I want to not have to generate proxy interfaces and datatypes, retain compile time errors when the interface changes, and not use svcutil. The IAsyncContract<T> would be enforced to take an interface that is marked as a ServiceContract. It would then take all the methods in the interface marked as an OperationContract and create a new interface with them, but changing their return types from what they were originally (e.g. int, string, List<double>, etc) to async Tasks (e.g. Task<int>, Task<string>, Task<List<double>>).

Right now I think it's impossible for an interface like IAsyncContract to exist and do what I would like, but maybe some kind of autogenerated code could take place on compile could net similar results. Thoughts?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 17 Sep 2010 15:23:00 -0700 .Net 4 Task Parallel Library and Asynchronous Amazon SimpleDB Access http://puffpio.com/net-4-task-parallel-library-and-asynchronous http://puffpio.com/net-4-task-parallel-library-and-asynchronous

At work we use Amazon SimpleDB for our distributed, redundant database; and Amazon supplies an SDK to use in which to access the service. Unfortunately for some, this SDK exposes all of the calls synchronously, with no asynchronous versions of any web service calls. As such, my initial implementation of data access was something like:

IEnumerable<MyData> data1; IEnumerable<MyData> data2; IEnumerable<MyData> data3; IEnumerable<MyData> data4; data1 = GetData1FromSDB(); data2 = GetData2FromSDB(); data3 = GetData3FromSDB(); data4 = GetData4FromSDB(); return DoSomethingCool(data1, data2, data3, data4);

Now that looks readable and straightforward, but it does not scale. Eventually we got to the point where each of the calls to SDB were retrieving significant amounts of data. Enough to cause site slowness when looking at large datasets. Reading about the handy dandy Task Parallel Library, I modified the implementation to this:

Parallel.Invoke(    () => { data1 = GetData1FromSDB(); },    () => { data2 = GetData2FromSDB(); },    () => { data3 = GetData3FromSDB(); },    () => { data4 = GetData4FromSDB(); } );

Great! Immediate speedup and all was good..for the moment. The data access was parallelized, but the interesting thing about Parallel.Invoke is that it limits itself to the number of processor cores your system contains. It was designed for compute bound tasks, not IO bound ones. Well great, I needed a way to go beyond the number of processor cores in the system, and I played with passing in some ParallelOptions with different parameters to try and mix it up, but settled on this:

var tasks = new Task[] {    Task.Factory.StartNew(() => { data1 = GetData1FromSDB(); }),    Task.Factory.StartNew(() => { data2 = GetData2FromSDB(); }),    Task.Factory.StartNew(() => { data3 = GetData3FromSDB(); }),    Task.Factory.StartNew(() => { data4 = GetData4FromSDB(); }) }; Task.WaitAll(tasks);

This implementation queues up all the tasks in the ThreadPool and goes to town. It's not limited by the number of processor cores, but by the size of the ThreadPool. Nice. But this implementation and the one above share another problem: Even while the tasks are blocked and waiting for data from SDB, it is still holding onto a Thread in the Threadpool. What I really needed was an asynchronous version of the SDB SDK but I don't want to rewrite their entire SDK to do it. After some more research into the Task Parallel Library and its compatibility with the Asynchronous Programming Model, I came up with this implementation:

var tasks = new Action[] {    () => { data1 = GetData1FromSDB(); },    () => { data2 = GetData2FromSDB(); },    () => { data3 = GetData3FromSDB(); },    () => { data4 = GetData4FromSDB(); } }.Select(a => Task.Factory.FromAsync(a.BeginInvoke, a.EndInvoke, null)).ToArray(); Task.WaitAll(tasks);

See what I did there? I took each data accessor and wrapped it into an Action via a lambda expression. Action's (and Func's) contain built in BeginInvoke and EndInvoke asynchronous versions of their execution. Nice. Now I just needed to batch them up and wait for them all to execute before continuing. I wrapped them into Tasks using Task.Factory.FromAsync and then issued a Task.WaitAll to wait till they finished. I then abstracted the functionality into an extension method:

public static void InvokeAsyncAndWaitAll(this IEnumerable<Action> actions) {    Task.WaitAll(actions.Select(a => Task.Factory.FromAsync(a.BeginInvoke, a.EndInvoke, null)).ToArray()); }

I can create multiple extension methods for each type of Action and Func as well (the Func version would need to return some type of collection). The nice thing about this is that all the data access happens asynchronously (though I have no control over when the thread sleeps during the data access), and data access is parallelized as well. Additionally using the Task Parallel Library lets the code look readable and definitely more maintainable than using some type of sync'd/locked counter for checking when all data accesses complete.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Thu, 26 Aug 2010 23:21:01 -0700 Android and Google made me smile today http://puffpio.com/android-and-google-made-me-smile-today http://puffpio.com/android-and-google-made-me-smile-today Today I had to goto my wife's friend's house to pick up some stuff. I looked at his contact info on my phone and I had his email address and phone number but I didn't have his street address. However, I know that I once used Google Maps to look up his address so onto Google Maps I went. I inputted his city and the autocomplete suggested the full address I had typed in months earlier *sweet*.
So now I needed to get that address into my phone. I know that Android phones auto-sync with Google Contacts, so I opened up my contacts list in Gmail only to discover that he wasn't in there. I looked back at his contact info on my phone and realized that the info came from the Facebook integration, kinda cool.  Back in Google Contacts, I proceeded to add him into my contacts, I started typing his name and the autocomplete suggested his email address since I had emailed him before *nice*.
Finally I added his phone number and address into the contact. I turned back to my phone - which was showing his contact details from earlier - with the intention to manually refresh my contacts to pick up the new info, but it was already there! His contact info which was displayed autorefreshed and had his address in it and showing on my screen *nice*.
So that part made my smile today. The tipping point was that when the address auto synced to my phone, I did not have to manually refresh the display of contact info, it just changed automatically.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Thu, 29 Jul 2010 11:03:00 -0700 24 Hour Fitness has my fingerprints http://puffpio.com/24-hour-fitness-has-my-fingerprints http://puffpio.com/24-hour-fitness-has-my-fingerprints
Summary:
My gym doesn't trust me and fingerprints me like a criminal. I don't trust my gym to safeguard my personal info. I also didn't like the face they forced me to do it or I couldn't access the facility.
 
My friend had this to say about it:
"I'm paying to use fucking gym equipment, not a laboratory w/ explosive chemicals. That's invasive ass shit just so you dont' have to pay someone to sit at a desk 24/7 at near minimum wage"
 
Detail:

Went to the gym last night and discovered they are transitioning to a new authentication system where instead of scanning your card, they instead take your fingerprint.

I was informed that this system was mandatory and they were phasing out card scanning.  The people behind the counter asked for my phone number, then took fingerprints of my index finger on both hands.
 
To me, I feel like this is BS:
  • Why should my GYM be creating a database of fingerprints of its customers? Do you trust your gym to safeguard that information? The same gym that uses pressure sales tactics, "club tours" that force you to stay and be pressured.
  • The lady at the counter said that this is not optional. Why is this not optional? They say that the point of this is convenience. You no longer need to carry your card, and it'll be quicker to get access into the club. Maybe, but everytime I goto the gym it took all of 5 seconds for the person to swipe my card. It's going to take longer to type my 10 digit code and then scan my finger.
  • Why was there no communication a month or two ahead of time warning of this change? Usually with large policy changes like this, a responsible company should inform its customers ahead of time to prepare them for the change. The fact that the first time I hear of this is when I get to the gym, and I am FORCED to do it or will not be able to access the equipment is bad customer relations.
  • Why do I have to supply my phone number? The person at the counter asked for our phone number to be used as our access code. When I said that I don't want to give out my phone number, they told me that actually I could just use any 10 digit number. If that is the case, why not say that in the beginning? Thousands of people who don't dig any deeper are going to be supplying their phone number without realizing that they didn't need to give it out.
  • If this is mandatory, why can I not get a refund? According to the people at the counter, I have to do it and tough luck. There was no option to cancel my membership. I'm sure I could call corporate and get a refund, but I would have to fight for it. If you are going to make a policy change that infringes on your customers private information, the "opt out" should be clear and prominent.
So now my gym has: My name, address, phone number, head shot, and fingerprints. My bank doesn't even have my fingerprint! Someone could do some serious damage with all that info.  I started thinking, why would 24 Hour Fitness want to do this..what's in it for them? They get a database of your most private information that I hope to God they will not use for marketing purposes or resell. I started to think, they could use this as a way to not have to hire counter staff. They could be like a subway with a turnstile gate, and you supply your code and fingerprint.  I guess that would save on labor cost. It sucks then that the counter staff who are setting all this up are basically working themselves out of a job.
 
There are three main reasons why this upset me:
  • I was not given a CHOICE.  There was no advance notice, and I had to sign up or they would deny my entry.  There was no way to opt out and use the old system, and no obvious way to cancel and refund my membership fee.
  • I am worried about my private information.  I am a software developer, and knowing too much for my own good makes me worried about my GYM having that kind of info on me. A gym is not a bank, they don't have the same kind of security and safeguards about data. They will not have invested in top software developer talent for their systems.
  • Being forced to submit to a fingerprinting makes me feel like I am a criminal. You are surreptitiously telling your customers that you do not trust them.
 
If they sent out a letter a month or two in advance explaining the new access system and how great it would be for the customers, I would grumble about it, but ultimately accept it and move on. Springing it on me is the tipping point that makes me actually motivated to write about it.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Thu, 08 Jul 2010 11:07:33 -0700 Back to the Future has one flaw http://puffpio.com/back-to-the-future-has-one-flaw http://puffpio.com/back-to-the-future-has-one-flaw In the first movie, when Marty is playing songs at prom, and his parents are not really hitting it off, he starts to fade away...as well as his family in the family photo he carried.
This suggests a singular timeline, since if his parents don't get together he will never be born and thus fade away.

HOWEVER, in the sequel where Biff gets sports almanac and then makes it rich, they return to a timeline where Biff is all powerful, and the Doc never invented the time machine...
If, then it was a singular timeline, then Marty could not have time traveled and thus would have faded away...
The fact that they appeared in this alternate timeline makes me believe it is suggesting a branching timeline where each decision point in time generates infinite universes

Head explode.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 02 Jul 2010 16:49:58 -0700 Alum Rock Park http://puffpio.com/alum-rock-park http://puffpio.com/alum-rock-park

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Thu, 03 Jun 2010 10:24:44 -0700 Elements of a five act story http://puffpio.com/elements-of-a-five-act-story http://puffpio.com/elements-of-a-five-act-story
  1. Hi! Who are you! What's going on?!
  2. ALL RIGHT LET'S DO THIS!!! WOOOO
  3. WE ARE DOING IT!! YEAAAHH
  4. oh shit something went wrong
  5. Everything turned out better than expected

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Thu, 03 Jun 2010 10:21:00 -0700 Diagnosing laptop fan failure http://puffpio.com/diagnosing-laptop-fan-failure http://puffpio.com/diagnosing-laptop-fan-failure Laptops are usually keen on being as quiet as possible. So when the cooling fan on one of them dies, it's not as straightforward to diagnose as it would be with a desktop computer. Luckily, modern computers have a bunch of temperature sensors built in, so when it detects an overheating situation it will slow down the computer to prevent damage. But how do you get from "this computer is slow" to "I need to replace my fan"? Here's what happened to me:

The Symptom

Over the Memorial Day weekend I flew to New York with Sherry to visit my sister. I took my laptop with me, of course, and when I got to my sister's place I configured my laptop to access her wifi. While setting it up, I noticed that she used WEP encryption rather than WPA2 and I thought that was unusual since WEP is pretty old and not that secure anymore. As soon as I connected to the WiFi, my computer exhibited the symptoms of being dog slow. Mouse clicks would take seconds to respond, regardless of CPU usage. Applications would take forever to load. Because the act of me configuring the wifi and the symptom of a slow computer came close together, I assumed that they were related. What else could it be? That was the only thing that changed about my computer....

Down the Wrong Path

Well it was slow all weekend, and I chalked it up to her wifi somehow mucking up my computer.  But when I got home, it was still slow. When I removed her WiFi configuration from my computer, it was still slow! Reboots didn't help, docking the laptop didn't help..nothing helped! At this point I decided to call it a night because I had work in the morning, I would tackle this problem again the next day.

Investigation

At this point, I started to broaden my scope: Maybe one the WiFi card got loose in all the travel. I checked it all out and it seemed OK, so what I decided to do was disable the wifi and see if that fixed things. There's a "airplane mode" switch on my laptop that shuts off any radio transmitters like WiFi and Bluetooth so I used that to shut them down, then I booted up my computer. SUCCESS! Fast computer! Back to normal!  But I still needed to verify that the wifi was the culprit..I flipped the "airplane mode" switch again and turned the WiFi back on.  Hmm..still fast! no issues..maybe it was a fluke?  Wait -- well, no...it's slow again..doh...

I turned off the wifi again, and it remained slow. Which totally sucked because I had not figured it out yet.  At least I could somewhat eliminate the wifi as the source of the problem. I started to broaden my horizon a little bit..what could make a computer run fast for a little bit, and then all of the sudden slow down?

Glimmer of Hope

It all clicked. I knew that computer's had over-temp protection that would kick in if the CPU got too hot.  And I didn't really hear the laptop's fan at all. I put my hand next to the vent and didn't feel any air. That was a good indication, but I needed to be sure.

I decided to download a utility that gives you a bunch of readouts about the health of your computer called HWMonitor. It allows you to see things like voltages, temperatures, and fan speed of all the different parts of your system. Sure enough, I could see that my computer was signalling the fan to run at 100%, but it was spinning at 0 rpm. I decided a REALLY needed to be sure and I partially disassembled my laptop so I could see the fan with my own eyes, and turned the computer on. The fan was not moving at all. Even if I gave it a little push, it wouldn't spin.

In for Repair

Luckily, my laptop has a pretty comprehensive service manual available on the manufacturer's website, so I was able to follow easy instructions to take apart my laptop and access the fan. Unluckily, the steps to get the fan out involved removing EVERYTHING. I had to take apart the keyboard, display, speakers, unhook all the radio antennas, and remove the motherboard out of the case. Just to access the fan. You would think that since the fan is one of the few moving parts in a computer, it is then more likely to fail than other components, and thus it would be designed to be easier to replace. Not so.

Ordering a new fan was kind of tricky as well: It's not a standard off the shelf PC fan, but has a custom housing meant for this laptop. There are three different versions, all push the same amount of air, but they all use different amounts of amperage (and thus consume different amounts of electricity for the same performance). The one in my laptop uses the least amount of electricity; the most common one out for sale uses 3 times the amount of electricity to push the same amount of air!

Anyways my laptop is now in pieces. I have the dead fan in my grubby hands and a new fan on order.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Tue, 25 May 2010 10:16:24 -0700 One stupid little inconsequential nitpick from the Lost finale http://puffpio.com/one-stupid-little-inconsequential-nitpick-fro http://puffpio.com/one-stupid-little-inconsequential-nitpick-fro Here's something I noticed right away, is totally inconsequential, yet it stuck in me head:
When Jack's father's coffin is being delivered to the church, it arrives in a commercial van. Since this was supposed to be in California and not Hawaii, the license plate was a California plate and had the format of 1ABC234. Unfortunately, that format of license plate is only for passenger cars....a truck or van such as the one delivering the coffin would be of the form 1A23456. I noticed that immediately and it's one of those things that broke the moment for me. Oh well.
Tangentially, I noticed that big rig trucks carry the format 1AB2345. Anyways since it was all purgatory anyways, and a construct of its inhabitants, I'll chalk it up to none of the Losties knowing or caring.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Mon, 24 May 2010 21:08:00 -0700 Final Fantasy 13, Chapter 7, Hope's Dad Bart http://puffpio.com/final-fantasy-13-chapter-7-snows-dad-bart http://puffpio.com/final-fantasy-13-chapter-7-snows-dad-bart
  1. Hope's dad Bart looks like Otacon from Metal Gear Solid 4..WTH
  2. Up to this point, Hope didn't want to see his dad, and everything implied that he had a strained relationship with his father...yet when we get there, his dad is totally supportive and loving..WTH
  3. It was common knowledge that people who came into contact with l'cie were shipped down to Pulse. Additionally, our protagonists knew that instead of shipping those people down to Pulse, many were just killed instead. Yet why did they choose not to take Hope's dad Bart with them? Instead they tied him up under the guise that they forced him to help. That wouldn't really get him off the hook. He would still be killed, or at the minimum be shipped out to Pulse..WTH

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Tue, 04 May 2010 15:36:44 -0700 Amazon SimpleDB NextToken edge condition http://puffpio.com/amazon-simpledb-nexttoken-edge-condition http://puffpio.com/amazon-simpledb-nexttoken-edge-condition Protip:

When you query SimpleDB using the "select" expression, the default setting is to return a maximum of 100 items. If there are more items to be retrieved, SimpleDB returns a NextToken and you can supply that into subsequent queries to continue getting data where you left off. The subtle part is that if your query has EXACTLY 100 items, or a multiple of 100....then on the last dataset, you will still get a NextToken even though there is no more data left! The next query using that token will result in an empty dataset.

So don't be fooled: Getting a NextToken does not necessarily mean there will be data on the next trip. This caused me a headache tracing why my custom SimpleDB enumerator was behaving badly.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Mon, 12 Apr 2010 13:38:30 -0700 Bacon vs Sausage http://puffpio.com/bacon-vs-sausage http://puffpio.com/bacon-vs-sausage
Bacon_vs_sausage_hat-p14833036

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Tue, 06 Apr 2010 11:05:37 -0700 None Shall Pass http://puffpio.com/none-shall-pass-1 http://puffpio.com/none-shall-pass-1
Gandolf1

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 02 Apr 2010 20:33:00 -0700 Taco Bell and Final Fantasy promotional idea http://puffpio.com/taco-bell-and-final-fantasy-promotional-idea http://puffpio.com/taco-bell-and-final-fantasy-promotional-idea

Final Fantasy 13 came out, and as I stopped at Taco Bell today I had a thought...they should rename the hot sauce varieties as "Fire", "Fira", and "Firaga" :D

The packets could be limited edition collectible with a different design on the front, maybe portraits of the main characters on the back.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Wed, 31 Mar 2010 10:39:00 -0700 Logging code blocks, inspiration from ASP.NET MVC Html.BeginForm and IDisposable http://puffpio.com/logging-code-blocks-inspiration-from-aspnet-m http://puffpio.com/logging-code-blocks-inspiration-from-aspnet-m

Many times I've had to log entry and exit of a method, either to track down a bug, for timing purposes, or other informational needs.  I'm using log4net here as an example but you can insert your own logging framework here. Initially I took the direct approach which is very straightforward:

public class MyClass() {    private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));    void myMethod()    {       log.Info("Entering myMethod");       ...       log.Info("Leaving myMethod");    } }

This works great for a while, but there are a couple of issues:

  1. Although its not much code, it's tedious. Why should I have to write these statements all over the place
  2. There is a high probability for error. Using this method, I end up copypasta'ing log statements all over the place. Inevitably, I either forget to do the matching pair of entering/leaving statements, or I forget to rename the contents of the text string to update. Which leads to ultra confusing log files days or weeks later.

The first solution is to create an attribute to decorate each method that wraps the function call with logging statements

[LogMethod(log, "myMethod")] void myMethod() { ... }

This works OK as well, I could even clean it up a little and infer the method name using reflection, rather than adding it to the attribute constructor. Now I can safely decorate this all over the place and it'll write entering and leaving statements for me. The downside is that by using an attribute, I am entering the strange world of reflection based programming and I don't really like to muck around in there. Also, sometimes I just want to wrap a hot block of code and not an entire method.

There's a nice method in ASP.NET MVC called Html.BeginForm which implements IDisposable. You are meant to use it in a using statement, the constructor emits the start of an HTML form, and the dispose method emits the end of the form.  In this manner you don't forget any tags and it's a cool way of using IDisposable to wrap things. I decided to use the same pattern for wrapping logging statements around code.

I created a LogWrapper class which implements IDisposable and logs an enter statement in the constructor and logs a leaving statement in the dispose method. I have the constructor take the logging object as well as a name to use (e.g. the method name or the name of a specific code block. Whatever you want). I also created an extension method for log4net's ILog interface to make it prettier to use my LogWrapper. Here's the code below:

public class LogWrapper : IDisposable {    private ILog _log;    private string _name;    public LogWrapper(ILog log, string name)    {       _log = log;       _name = name;       _log.Info("Entering " + _name);    }    public void Dispose()    {       _log.Info("Leaving " + _name);    } } public static class LogEx {    public static IDisposable WrapCodeBlock(this ILog log, string name)    {       return new LogWrapper(log, name);    } }

Nifty. Now to use it I just wrap my significant code blocks in a using statement

using (log.WrapCodeBlock("foo")) {    // do my stuff }

The code is logically encapsulated in a using statement and makes it easier to read. It also ensures that I don't forget the matching "leaving" log, and that I don't forget to change the name because I will be using far less copypasta. And it makes me happy :)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Wed, 31 Mar 2010 02:04:49 -0700 Tuesday's Lost..Sun and Jin http://puffpio.com/tuesdays-lostsun-and-jin http://puffpio.com/tuesdays-lostsun-and-jin Just two points:
  1. Sun losing her English speaking ability after hitting a tree = CONTRIVED. I'm sure the writers had a need to get her into that predicament in order to either develop some character interactions, or as a plot device. Therefore, as a vested and informed audience member, I will accept this look "behind the curtain" and suspend my disbelief. But still..CONTRIVED!!!!
  2. When Sun tells Jin in the Alternate Universe that she is pregnant...I think she knew from before the flight. She also hinted that she had something to tell Jin, and I highly doubt she could tell they conceived a child from the night before. Therefore, WTF why was she drinking champagne? Does she really want a tard kid? TIMMMAH!!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio
Fri, 12 Mar 2010 12:22:00 -0800 Load Balancing and x-forwarded-for http://puffpio.com/load-balancing-and-x-forwarded-for http://puffpio.com/load-balancing-and-x-forwarded-for

This is a pretty common mistake to make:
If your ASP.net site requires you to capture the IP address of the user hitting the site, you use Request.UserHostAddress

If you are behind a load balancer or some other proxy, that address actually changes to take the address of the load balancer/proxy :sadpanda:
Now a good load balancer will append an HTTP header "x-forward-for" which contains the original IP address.

So what's a guy like me to do?  Anywhere I used Request.UserHostAddress, change it to be Request.Headers["x-forwarded-for"] ?? Request.UserHostAddress. There all better. It will fall back to UserHostAddress if x-forwarded-for is not in the collection of HTTP headers, and looking up the header is not case sensitive so we are OK there.

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/499146/23027_1064729326_1718_q.jpg http://posterous.com/users/1bkTQenUjfP David Pio puffpio David Pio