Jessica and I got married over the weekend. I'll be blogging more about how awesome the wedding was when I get back from the honeymoon (which we're leaving for this afternoon), but here's a sample of pics taken over the weekend by friends and family while we wait on the official photos. Enjoy!
I really hate it when software dictates preferences to me. I'd noticed that some of the web sites I visit did not autofill credentials, and had always assumed it was a bug in the way Safari dealt with figuring out the autofill details. However, I looked at the source for a payment web site today and saw the property autocomplete="off" in the form fields, which Safari respects.
F*** that. I lock my computer every time I am away from it, have a FileVault encrypted drive, and have all my passwords locked up in my secure OS X keychain. Why the people who program the web site think they have to force me to follow their security practices is beyond me.
Luckily, there is a patch for Safari on OS X that gets around this. It runs a perl script which changes the pattern that the underlying WebCore software searches for, rendering the form field attribute useless. I just ran it on OS X 10.5.6 with Safari 3.2.1 and it works great.
Apr 20, 2009
Client-Side Data Synchronization with Flex and BlazeDS
As a Flex developer, unless you have been living under a rock for the last four years you know that LiveCycle Data Services offers Data Synchronization. This is implemented as a server-side product, and allows you to quite easily manage concurrent data access for many clients connected to the same server.
But what if you need more than a single server? Cluster, you might say. Unfortunately, that doesn't really work at any serious scale.
At Highwinds, we build everything to scale to ridiculous levels because we're a CDN and that's how we roll. As a result, we use a lot of eventually consistent systems and design every component to scale horizontally. So, when we took to designing the next generation of the StrikeTracker platform, we wanted data synchronization and conflict resolution but we (a) didn't want to manage it statefully at the server tier and (b) didn't want to pay Adobe a bunch of money for LCDS just yet.
So, we decided to implement client-side data sync. In essence, it boils down to the following elements.
1) Whenever a client wants to change data (i.e. add something new, change something, delete something), it calls the server tier using RPC via RemoteObject.
2) The server completes the call in a transaction against a replicated MySQL instance set up in master-slave configuration with hot failover. When the server call completes, the modification to the object has been persisted and a version number on the object has been incremented.
3) The calling client receives a response saying "yep, the server processed your request - hold for confirmation from the message bus." The object that was just processed by the server is placed in to a "limbo" state by the client.
4) Using AOP, "after" advice is applied to the server-side component to dispatch a message to our message bus indicating what just happened.
5) All clients are connected to one of many BlazeDS servers, which are in turn listening to command-and-control channels on our message bus for messages from all BlazeDS servers. All the BlazeDS servers eventually get the messages dispatched by their peers indicating which changes happened on other clients in the system via the message bus's flood-fill algorithm.
6) As the BlazeDS servers receive the messages from the bus, they push them to their clients. The clients then compare the type of message (new, change, or delete) with a collection of objects of the same type in their local memory, looking for matches based upon unique object IDs.
7) If a match is found, the clients do some comparisons between version numbers to figure out if they have the latest version of the data or not. If they don't have the latest data, they can react to conflicts much like LCDS does today. If the client which caused the original request to be processed receives confirmation from the bus that its message was broadcast to everybody, it takes its local copy out of limbo state indicating to the user that the process has finished executing.
The system works on the principle of every object being uniquely identifiable by ID and class type, and being versioned in an ever-increasing fashion. By using a client-side controller mechanism for requesting data changes and putting the controller in charge of all RPC communication, message bus listening, and data management, we've come up with a very robust model for dealing with data synchronization on the client side.
We can also give the client immediate feedback regarding their pending requests, and know that all clients will see the same data appear near-simultaneously. In the case where we have network latency or issues for clients in different parts of the world, the clients are built smart enough to deal with the latencies. Finally, we can use the approach without having to use JMS, which means one less server component - and if you already have a message bus (like we do) then you'll know how nice it feels not to have to light up yet another one.
We're currently coding the implementation and expect to have it working this week, and after we get it going I expect to discuss it further on my blog. There's certainly a fair bit of code to handle corner cases and concurrency issues, so I'm not sure how proprietary this approach is going to be, but I'm hoping that if we get it working I will be able to get permission to open source it to the community. In light of the fact that LCDS's approach does not make sense for all use cases, this seems like something that a lot of people could put to use.
I can't believe it's been a year already. I'm told that the calendar doesn't lie.
And what a year it has been. 2008 was a lot of figuring out how to bend Flex further to my will, lots of bug fixing and feature development for StrikeTracker 1.x, and staffing up my team. 2009 has been a lot of ground-up software development on StrikeTracker 2.x, lots of bending Java/Spring/Hibernate/BlazeDS to my will, and a ton of much harder (and infinitely more enjoyable) work than 2008 had to offer. I wouldn't take any of it back, besides having to lay Mario off, which was the hardest thing I've had to do in my career.
That being said, I have no regrets for joining Highwinds - quite the opposite, in fact. Not only do I love what I'm doing, but I got my life/work balance back and was able to get engaged (wedding's in two weeks!) and almost finish an open source project in my free time.
I am a lucky, lucky bastard. I wake up every day stoked to come to work. After a full day of creating bugs for Russ and Brian to fix and managing the team badly, I often find myself driving home astonished that I can get paid to do something I enjoy so much with people I respect so thoroughly. Ever since I discovered programming in college, I've wanted to work with people who get it in a place with zero politics, zero bullshit, and the pure intent to write line after line of ass-kicking, money-making software. I've been given the opportunity to do so and I count myself undeservedly lucky for it every day.
So, thanks again to Chris and Josh for seeing past my flaws and letting me join the company, and to Brian and Russ for putting up with me and being an awesome team. The first year was great; I hope I can do you guys proud in 2009 and beyond.
I just posted an entry on the Loom blog about how I now have working AOP proxying in AS3 via Loom. If you are interested in following the development of Loom, I recommend that you subscribe to that blog because that's where all the action will be.
It's really satisfying to get this working. The problem with the AVM spec is that you can't really implement any of it without implementing all of it, so most of the time I have been working on Loom has been with an eye towards something cool happening eventually. Now that it's working, I'm on cleanup street, and then we'll have a public beta within a week or so.
Stay tuned to the Loom project site for the public beta, and the Loom Blog for updates. Also, if you want to get in on the private alpha, hit me up.
Great news - Loom is at the point where I can p0wn the ActionScript Virtual Machine; it is, as they say, my bitch.
I spent the evening plugging in some dynamic proxying love, and the results are awesome. I've got a few more tasks on my plate, but the Loom API is working great and the AVM is slurping up Loom's dynamically weaved bytecode without complaining.
I'm highly confident I'll have a working AOP proxy by the week's end. In the interim, I've been able to take a template ABC (ActionScript Bytecode) file and enhance it by adding method and slot traits. I was able to introduce a Dictionary to the class (which it did not have when it was originally compiled) and access/manipulate it via a custom Loom namespace. I also wove in a new method that was not there before, and added the appropriate opcodes (basically the AVM's assembly language) to trace a message to the world from Loom.
I love little details about the inner workings of platforms, like this snippet from Mason Chang about Tamarin and native methods.
Even though all I wanted was a little AOP love, I've ended up learning a ton about virtual machines and ActionScript itself from Loom. Which is two utilities away from being finished, I might add - I started on ProxyFactory this weekend and SwfEnhancer is the last piece of the puzzle... :)
Since I own a larger-than-average vehicle that I am typically able to park in a single space without issue, this one struck a chord. I am amazed by how many people can't get an average size car in to a single spot.
And while we're on traffic-related items, Jimmy Justice is my new hero. I had MSNBC on yesterday as background noise while I was cleaning up the lower half of the house, and I saw a special on this guy and other "video vigilantes."
Jimmy Justice hangs out around New York catching cops and city officials on camera as they blatantly disregard the laws that they ticket everybody else for breaking. I have nothing against cops when they are keeping us safer and upholding useful and sensible laws, but I do believe that 90% of traffic/parking tickets are total bullshit, imposed at the whim of the officer issuing the infraction and very infrequently actually causing anything useful to happen other than revenue to flow in to the coffers of the local city council. Frankly, I'd rather they just taxed me more and let me do whatever the hell I want on the road; the only place speed limits make any sense is adjacent to and within residential areas.
I have often thought about whipping out my video camera and grabbing shots of state troopers doing 90+ on the FL Turnpike or speeding down I-4, and I wish I had had my camera on me yesterday night when a cop turned on his lights to run a red light and make a turn instead of waiting for the light to change like the rest of us have to (and no, it wasn't an emergency because he turned his lights off as soon as he cleared the intersection). This is exactly the kind of hypocrisy that gives lawmakers and cops a bad rep.
On a more serious note, I was sent a news article recently by a friend that discussed how UK anti-terrorism laws make it illegal to photograph police. Seriously - WTF? If you can't photograph the police, you can't photograph them breaking the law, which means they are finally as unaccountable as they have always wanted to be. This is simply unacceptable for a democratic society. Anybody who has lived in the UK and seen the movie "Children of Men" knows the chilling authenticity of their depiction of Britain as a police state, and if you ask me, Britain's a mere hair away from becoming one. It all started with the traffic cams, and now the everything cams, and now laws preventing the photographing police officers.
I'm no conspiracy theorist or freedom nut, but this kind of nonsense gives me pause. Keep your eyes peeled, because this same nonsense is coming to the US. They've started installing traffic cams in a number of states for "the good of the populace," and it's a slippery slope to cameras everywhere - just look at the way the UK is going. Pay attention to what is happening in your state and make sure the camera laws being passed have your freedoms in mind.