Tuesday, January 26, 2010

Four Easy and Practical Tips When Visiting Vancouver for the 2010 Winter Olympics

I've lived in Vancouver for a while now, and realize that you (and 2.3 million of your closest friends) may be coming to visit for the Winter Olympics. Here are some dead easy tidbits that will make your stay more enjoyable. You may want to bookmark this post for while you're here.

Tip #1: Eating

Typical Vancouver food is Japanese food, mainly sushi. There are many good, cheap Japanese/Sushi places all over the city. If you've never had Japanese food before (and you're nervous), check out the all-you-can-eat places that offer appetizer sizes of anything. Leaving Vancouver without at least trying would be pretty close to a crime.

Once you've had your fill of sushi, use Urban Spoon to find other places to eat (Dine Here is good too - but a little less friendly). If you like greasy-spoon breakfasts, try Joe's Grill or Bon's Off Broadway. I like Templeton (don't let its appearance deceive you!) and Kam's Place (tasty Singaporean food) but they're probably going to be packed while you're here.

Kam's
Place has had a two-for-one coupon near the back of the Georgia Straight (weekly free Vancouver newspaper) every week for the past five years. Lastly, there are a number of delicious restaurants in the Commercial Drive area.

Your life will be just as fulfilling if you didn't go to Denny's or White Spot.

Don't forget grocery stores for when you just want to pick up some snacks on the go. Vancouver has a few chains including IGA, Safeway, Save On Foods, Urban Fare.

If you're from outside Canada and want to try "Canadian food", don't ask us. Most of us will have no idea. Look around for nanaimo bars, poutine, bannock, tourtiere, lobster rolls, steamed fiddleheads, and maple sugar pie - all genuinely Canadian. (If you've got a sweet tooth, seek out nanaimo bars). Vancouver also has a number of local breweries, and BC has a number of wineries.

With over 120 Starbucks in Vancouver, we're definitely a coffee-culture city. Other chains include Waves and Blenz (both offering free wifi), as well as the more ubiquitous Tim Horton's (origin of the term double double). If you're a Starbucks fanboy, I encourage you to make your way to the corner of Robson and Thurlow - a famous intersection with two Starbuckseseses.

Tip #2: Getting Around

Don't Drive. I really can't stress this enough. The city has recently extended pay-parking hours to 10pm - seven days a week everywhere in the city. Even without the 2.3 million additional people, driving in Vancouver is a pain. I've read somewhere that all tickets to Olympic events include transportation to/from the event. Please check into this!

Public transportation in Vancouver is run by TransLink. It includes buses, subways (Canada Line), light rail (SkyTrain) and ferries (SeaBus). TransLink fares work on a "zone" system. Your fare corresponds to how many zones you'll be travelling through. I found a pretty good TransLink Map. As a rule, SkyTrain and Canada Line stops have fare machines which accept Interac, credit card and Canadian cash. Buses are exact-fare.

Google Maps has a "Directions by Transit" for getting around the city. I encourage you to use this as a backup during the Olympics as some operating changes just for the Olympics have been made and I'm not sure if Google has been updated. Instead, use the pretty decent
TransLink Trip Planner.

If you don't have prepaid tickets (FareCards), there will be a $5 surcharge (per person) traveling from the airport on TransLink (via the Canada Line). It's still cheaper than taking a taxi. If you see someone at the airport selling FareCards, you may want to take them up on the offer. To ensure it's legit, make sure the magnetic stripe side of the FareCard doesn't already have an expiry time printed on it.

If you use the Trip Planner and you see "get off one SkyTrain, get on another SkyTrain" around Broadway-Commercial, I will confess it is a bit confusing the first time you do so, but you won't be alone in the necessary confusion. It's all well-marked.

Looking for something kinda fun to do? There is a SeaBus that goes from Waterfront to Lonsdale, it's a two-zone ride (cheaper on the weekends). It's a fun little ride. The Lonsdale side has a market with fresh food stuffs too. You'll have a nice view of downtown from the Lonsdale side too. Great on a sunny day!

When walking downtown, streets that run NW/SE are just generally referred to as "North" or "South" by downtowners. "If you can see the mountains, you're facing North." is a rule many locals have. I think (at least downtown) locals are pretty happy to help a lost soul.

Lastly, if you can avoid taking public transportation from 7am-10am and from 3pm-6pm, those of us going to work would greatly appreciate it. :-)

If you are driving, and you're from outside BC, you'll want to know about our BC traffic lights.

Tip #3: Weather

Vancouver is generally a rainy city. The outskirts are cold enough to get snow, but usually not a lot. If you want to see what it looks like right now in Vancouver, the popular and mostly reliable Kat Kam web cam is a great start.

I pretty much swear by Environment Canada's Vancouver Seven Day Forecast.

Dress in layers (guys too), but leave your umbrella at home. Instead, bring a long a hooded rain jacket. You'll navigate the sidewalks a lot more effectively and you're not likely to leave your jacket behind somewhere.

Locals tend to need higher amounts of rain to trigger their "I should put my hood up" feeling.

Vancouver is stunning when it's sunny out. If you can, make your way to the Lookout at Cypress Mountain for pretty much the best view of Vancouver day or night.

Tip #4: Blending In

Here are some random tips you may want to keep in mind:

Just like the Tube, Vancouverites follow "Stand to the side to let people out before getting on" for public transportation. If you do this too, you'll blend in a lot better.

Most people here don't speak French; there are easily more Chinese/Japanese/Korean speakers than French speakers in Vancouver.

Generally speaking in the rain, if you're without a hooded jacket or umbrella, walk nearest to buildings. If you've got an umbrella, walk furthermost from buildings.

On stairs and escalators, we follow the "stand on the right, walk on the left" rule.

The weather is a popular conversation topic and can be used to talk to just about anyone - especially if it's nice out!

That's It

Enjoy your trip! And if you're looking for someone to go for sushi with, drop me an email. :-)

Thursday, April 02, 2009

Xen vs KVM

I wanted to chime in on the Xen vs. KVM discussions, and give you some food for thought.

I've been using Xen now for years, having replaced UserModeLinux on my personal server, and it's seen a lot of production use at my current job.

That said, KVM is ultimately the right way to go. Constant maintenance of Xen's hypervisor kernel is what causes Linux distributions grief with Xen. Those that keep doing it, do so because it's performant, tested and well-understood.

So you're stuck wondering which virtualization technology you should pick. Here it is: libvirt (with Xen).

Base your toolset, deployment, configuration, and maintenance on libvirt, and use the Xen hypervisor for now.

libvirt provides an easy upgrade path from Xen to KVM once KVM's performance and stability have been battle hardened. Same virtual machine configuration, same provisioning, same disk images. Just grab a new kernel, change which hypervisor you're using and you'll be in the land of tomorrow.

Sunday, January 04, 2009

Provisioning Servers: An Afternoon with Cobbler

I spent some time evaluating Fedora's Cobbler installation service. If you play with many machines - real or virtual - you should definitely take a look. Some handy features:

* Kickstart Setup: For Red Hat breed systems, existing Kickstart configurations (found on installation media) are exposed as profiles in Cobbler. You can add your own Kickstart configurations too (imagine a "rhel5-webserver" profile).

* PXE Management: Tied in with a DHCP server, cobbler will offer profiles up for installation for servers during PXE boot (often called Boot from network), since these profiles are tied with Kickstart configurations, servers can be setup or re-setup with just a few keystrokes. KVM seems to support PXE boots; less hoops for installation your VMs.

* Repository Mirroring: Cobbler can take the URL to a repository and mirror it locally, both yum and apt style repositories (rpm and deb) are supported. Use cobbler reposync to keep local mirrors up to date.

* Distribution Swallowing: Cobbler can copy installation media and copy it locally.

* Boot ISO / Live CD: If your server doesn't support PXE, or if tying into DHCP isn't an option, cobbler can make burnable ISOs (and thus USB thumb images) that can be used to perform network installs.

* MAC Address to Profile Management: Cobbler can associate a particular MAC address with a particular profile.

* Automatic Repository Setup: Cobbler can setup your local yum mirror in your newly created server automatically for you.

* Triggers / Puppet Integration: Cobbler can be configured to register the new machine with puppet, or run other triggers (imagine automatic graphs in Cacti, monitoring in OpsView, etc, etc).

* KOAN: Koan is a command line tool that talks with the Cobbler server. It can be used to set up new VMs (using libvirtd), or with a special --replace-self option, cause an existing installation to reinstall itself. (Only works with Red Hat breed systems.)

* Zeroconf: Avahi is among one of the coolest technologies I've played with recently. Specifying --server=DISCOVER on the koan command line will find the cobbler server on the network. I love stuff like that.

* Configuration Cloning: Move your test environment configuration into production (or mirror for HA, etc)

I really like the architecture of Cobbler too; an XMLRPC server that both the command line tools and web interface use. The web interface is handled by Apache and mod_python, so authentication and authorization are handled by Apache (ie, basically anything you can think of).

Lastly, one nice touch is cobbler check. Run right after a fresh install it checks your environment and lets you know of anything that could potentially hamper Cobbler from working.

I haven't yet tried Cobbler with an existing DHCP server, and I'm not sure it supports ISC DHCP's failover capabilities (even with OMAPI).

Monday, December 29, 2008

Ye Olde Job: Technology That Wasn't

Our system could accept transactions over the phone (via a clerk) or through our website. The clerk on the phone used a semi-web based application to interact with the system.

The headache with this was that the code base for the "semi-web" and "actual web" only became a common code path much, much deeper in the code. So the plan was simple, redo the website code such that it could eventually be leveraged to replace the semi-web code.

We prototyped, mocked up, tested and developed a new part of the application on our website using GWT. It went through load testing, SEO-approval and I believe we even did a couple in-company demos of the technology.

The code was "done" (in the "given to QA to break" sense of the word) when I left, but when I check the website now I see it never made it to production.

I cared about this for the first month or so after I left, so I pinged around to find out what happened. The short version is that it got stuck in developer mythology, and with nobody there to lead it out, I knew it would never see the light of day.

I wonder just how much technology is "done" that has never seen the real world?

Friday, December 26, 2008

Ye Olde Job: First Post - So You're the Boss

It's been seven months since I left my old job, and I feel it's alright to talk about some things.

If you're in a situation where you're finding yourself leading a team of developers without any mentoring from anyone on how the heck to do that, I offer you some food for thought.

As a developer, you measure your own progress by the code you write, the bugs you fix, stored procedures you debug, problems you solve and features that get released. You have days where you go home "having done nothing" because you have a dozen variables in your head and you've been nose deep in code, but whatever it is still isn't working.

Or maybe you wouldn't debug the stored procedures, but instead really wish that you could replace them with something else; a nice cup of Java, easy to unit test and a breeze to step through.

One thing I figured out that really helped me: When leading a team, put the team first.

What the heck does that mean?

It means getting to know the strengths and weaknesses of not only your team, but of the teams you interact with. One developer has a knack at networking, another at databases, another one refactors code from a city dump into a gorgeous mansion. When the work is important - major features on a tight timeline - use peoples strength. When it's less important - minor bugs, features that are 'nice to have' - let them work on their weaknesses. If other teams have weaknesses in areas, work to help them, or fortify against it.

It means being two steps ahead of your team, knowing where you're going next. If nobody else in your company can give you direction two steps ahead, then take matters into your own hands. Don't just start piecemealing things; always have a vision. If you don't know where you're going, you won't know when you've gone off course. Obviously, be flexible with your vision for that idle Wednesday when some manager presents his vision to you so you can embrace it and walk together.

It means giving that improvement away. This was the hardest for me: giving up writing that feature you really wanted or fixing that bug that drives you nuts. You will write less code, but your team will write more code than you ever could. You will want to use a bit of the downtime you'll get to assign yourself some work, but you know you'll never get to it. Use that downtime to better map out your plan, to make sure everyone has got the work they need and to fish around to see if maybe that company plan or vision is hiding somewhere... ..anywhere.. ..maybe?

It means accepting shades of grey. There are many wrong ways to do things and few right ways. But there is definitely more than one right way. The way someone on your team might craft something may not be bytecode-for-bytecode how you would do it, but it may still fall in the realm of right. Accept that it's not how you would do it. That's fine. But is it wrong?

It means keeping it in the team. Just like most code bases that earn a over a billion dollars, the code base I worked on was suboptimal. We all knew it, but we knew we were there not to whine about it, but to make it better. Bit by bit, day by day. Start with the biggest problems, work toward your vision.

It means that stored procedure is going to stay; both the DBA and I know how to tune, monitor and troubleshoot it. We've minimized the row locking in it and fixed a deadlock problem in the logic. Also, next week you'll be fixing it to be resilient against another team's code, because their code does table scans and table locks and it will soon be our busy season and the potential for headaches is not part of my vision.

Updated: While stored procedures vs ORM is part of a future post, I hope that people who are in the "You've been here the longest, you're in charge" situation can benefit a bit from keeping in mind that they need to put their team before themselves. I know it's hard to switch gears.

Sunday, November 09, 2008

Seven Reasons I Didn't Pick Your Open Source Project

After a really relaxing summer, I've picked up a job as a Systems Architect at local company suffering from growing pains. After almost a decade, I've put down my debugger and picked up a budget..for now. I've found myself looking at many different options of products some open source some not. I want to apologize to those open source projects I've rejected and wanted to let you know why:

1. Capacity Planning: You lack any realistic guidelines for server sizing. I have no idea how much memory, disk, bandwidth or cpu cycles I need to support 250 users checking their email every morning and you have no tools to simulate load.

2. You're Working On the "Next Gen" Version: You've stopped working on the version people are using in order to rewrite the application using technology that follows your new beliefs. The current version is now suffering from bitrot and your new version is undergoing its third major refactoring.

3. Your Community: Your forums are an abandoned town with tumbleweed rolling through waking up the sleeping armadillos. Questions go unanswered for months at a time, most of the posts are spam or people asking if the project is dead (which it is).

4. Installation: Your twelve-step installation process involving a different version of Perl, MySQL, and PHP plugins I don't have is a headache. This is the world of LiveCDs, embedded servlet containers, virtual machines, Web Start, VNC, hosted-demos or at least RPM/DEB packages.

5. Your Features: They're geared towards other developers and not users. I realize you're "not M$", and it's swell you think "Not Written in Java, so it's Fast!" is important, and it's sure great that you "use AOP extensively", but if those are the features you list instead of "works through NAT","supports 802.3ad bonding" or "integrates with iCal" then you're pretty far removed from your user base.

6. Maintenance Headaches: According to your documentation, your upgrade process is "Backup all data. Install new version. Restore all data." That's fine if "all data" is the dhcpd leases file, but not so great when it's 9TB of files that users access all day.

7. Price: Your project has a "commercially supported" version. That's cool, but when the rates listed are more expensive than the defacto standard you can pretty much guarantee I'm not going to be able to sell it upwards.

I'll let you know what I've picked and how it turns out in the next few months. I'm also looking for a really good Linux sysadmin. :)

Saturday, October 11, 2008

Wave Tracing: Ray Tracing for Sound

Here's the pitch: With regular ray tracing, rays of light are traced backward from a pixel of the camera, to an object and eventually to a light source (or lack thereof). If you can do that with light, why can't it be done with sound?

Over ten years ago I was having breakfast with a friend and I sketched out the idea on a napkin. This kind of math is definitely not my strong point. But instead of a camera, have a microphone. Instead of tracing rays, trace vibrations, and instead of light sources, there's air and friction; or so the napkin said.

Instruments aren't the goal, but a simple model to test would be a
grade school caliber recorder
. After modeling materials, blown air resonates down the tube of the recorder generating sound.

As different quality of air and different materials are created, artists build wireframes of different instruments. The effects of room acoustics could be modeled too.

This would culminate in a completely rendered orchestra performing a wave traced rendition of Beethoven's Symphony No 5.

As I mentioned earlier, instruments aren't the goal: Voices are.

After modeling complex instruments, the next step is to model and animate the speech pathway from lungs to lips. The speech animated model (or "Sam" for short) would start with simple vowels like the [a:] sound in raw, or the [æ] sound in "bad". (Wikipedia's page on the IPA has some good introductory information). Eventually Sam would be animated to fluidly pronounce most phonemes. Linguistics are also not my strong point.

I'd imagine that Sam would sound very lifeless and flat. So we would capture data from sensors attached to voice model actors. Voice capture artists would smooth out the data and bring Sam to life. Motion capture is also not my strong point.

With only a handful of voice model actors, spoken phrases could be captured for an entire movie or video game! The captured data could be applied to dozens or hundreds of different sounding models by adjusting Sam's variables. Accents would easy to add by changing the way Sam enunciates words. Playing with Sam's breathing rate would simulate a person out of breath or scared. Sam's voice could be lowered or raised or even modeled after a real person.

Eventually the captured data could be used to animate 3D model too!

This would be a perfect for RPG games like Oblivion or GTA that can benefit from an almost endless supply of different voices.

Let me know if you ever do anything with this, or find something that does. Especially if you're Bethesda!

Friday, September 26, 2008

GWT: Generators HowTo (BuildStamp)

If you're curious what generators are, or have never used them with GWT, this simple generator will give you a quick introduction to get your hamster wheels turning.

I do a lot of prototyping in GWT before I build the backend and I've recently had the need to generate a "build version" for my GWT interface. While there are about fiftybazillionmillion different ways to do this, I've chosen a GWT generator to create a buildstamp. This
lets me tar up the www results of clicking on "Compile/Browse" and fire them off for others to play.

In your Java code, you just add:


...
BuildStamp buildStamp = GWT.create(BuildStamp.class);
yourLogo.setTitle(buildStamp.getBuildStamp());
...

This will add a tooltip to yourLogo which looks like: "Built on kikai.linuxstuff.org at Tue Jul 29 19:07:05 PDT 2008".

When you compile your GWT application the generator is compiled and run. It generates Java code which is converted to JavaScript along with the rest of your application. When this happens the timestamp is "frozen".

Code and wiring follows. Imports omitted, use your favourite IDE to fill them in. This makes a pretty simple Hello World example.

Comments are more than welcome.
package org.example.rebind;

public class BuildStampGenerator extends Generator {

private String className;
private String packageName;

@Override
public String generate(TreeLogger logger, GeneratorContext context, String typeName)
throws UnableToCompleteException {

try {

TypeOracle typeOracle = context.getTypeOracle();
JClassType classType = typeOracle.getType(typeName);
packageName = classType.getPackage().getName();
className = classType.getSimpleSourceName() + "Impl";

generateClass(logger, context);

} catch (Exception e) {
logger.log(TreeLogger.ERROR, "Exception during BuildStamp creation.", e);
}

return packageName + "." + className;

}

private void generateClass(TreeLogger logger, GeneratorContext context) {

PrintWriter printWriter = context.tryCreate(logger, packageName, className);

/* Returns null if the package has already been generated. */
if (printWriter == null) {
return;
}

ClassSourceFileComposerFactory composer =
new ClassSourceFileComposerFactory(packageName, className);

// shouldn't magic just happen here?
composer.addImplementedInterface(BuildStamp.class.getCanonicalName());

SourceWriter sourceWriter = composer.createSourceWriter(context, printWriter);

writeGetBuildStamp(sourceWriter);

sourceWriter.outdent();
sourceWriter.println("}");

context.commit(logger, printWriter);

}

/**
* Write the source code for {@code BuildStamp#getBuildStamp()}.
*/
private void writeGetBuildStamp(SourceWriter sourceWriter) {
sourceWriter.println("public String getBuildStamp() {");
sourceWriter.println(" return \"" + Generator.escape(getBuildStamp()) + "\";");
sourceWriter.println("}");
}

/**
* Executed at *compile* time, this generates a string that is embedded in the
* generated class. In hosted mode, this code is rebuilt each Refresh.
*
* @return A user-friendly build string, good for hiding in tooltips.
*/
String getBuildStamp() {
StringBuilder msg = new StringBuilder();
msg.append("Built on ");
try {
String hostname = InetAddress.getLocalHost().getCanonicalHostName();
msg.append(hostname);
} catch (UnknownHostException e) {
msg.append("(hostname not available)");
}
msg.append(" at ");
msg.append(new Date());
return msg.toString();
}

}

You will need a BuildStamp interface:


package org.example.client;
public interface BuildStamp { public String getBuildStamp(); }

And wire it up in your .gwt.xml:
<generate-with class="org.example.rebind.BuildStampGenerator">
<when-type-assignable class="org.example.client.BuildStamp" />
</generate-with>


What do you think?

Monday, September 15, 2008

Spore on Linux

If you're a Linux user wondering if Spore works, the answer is: Sorta.

I bought the download version from the EA Store. Nothing mentioned until after my purchase was complete that I needed a Windows-only downloader. I didn't test this under Wine.

Aside: The EA Store website allows + in email addresses, but the Spore online login does not.

I'm using Ubuntu 8.04 with a custom build of Wine 1.1.4 (includes a patch needed to make Spore run). The installer runs fine in Wine. Skip the DirectX install. While the game works, piracy prevention code doesn't. You'll need to find a cracked SporeApp.exe floating around to work around the issue. I believe a similar workaround is needed if you purchase the boxed game.

I'm still on the creature level, I've found a few graphical glitches:

  • Minor: Turn "Shadows" to "Low" to reduce some of the bizarre sploches of blackness.
  • Minor: The icon by the mouse pointer seems to not be transparent properly
  • Minor: Text describing your goals overlaps the text describing items you've picked up.
  • Medium: The water isn't rendered.


Check the the WineHQ page about Spore.

Wednesday, September 03, 2008

Chromium and Bees

Watching what Google does feels like watching X-Files. I want to believe there's some grand master plan, but I'm pretty sure they're just making things up as they go.

Hank Williams over at Why Does Everything Suck pretty much covers my thoughts on Google's new web browser in his Huh? and Huh! posts.