October 28, 2008

Ultimate Tournament

Sunday October 26, 2008
9AM BUDA Fall Hat League Tournament
Mitre Fields, Burlington, MA
Weather: 65 F, Partly Sunny
Field: damp
Perfect conditions for Ultimate.

Sunday's end of the season fall hat league tournament was a long, great day of ultimate as usual. After being beaten in our first two games, we finally rallied to win our last two! It was a tough season this fall with multiple rain outs which made it difficult for our team to get well organized. We really came together in the tournament though and it showed as we were playing clamp-down zone defense and smart, effective offense in those last two games.

Unfortunately, though, my plantar fasciitis has not gone quietly. I've started wearing superfeet inserts in my cleats and normal every day shoes, but it's going to take time before the problem repairs itself. I was able to play at a high level at the tournament, but not without considerable pain and stiffness in my heel. I'm forcing myself (with significant restraint required) to stay off the field for at least this week and possibly next week. In the meantime, I'm going to try and mix in some low impact cross-training as well as stretching and strengthening exercises for my feet and calves.

Ultimate Statistics (since January 2008):
Total Games Played: 121
Total Hours Played: 145

October 25, 2008

Ultimate Chilly

Wednesday October 22, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 43 F, Windy, Drizzle
Field: damp
Perfect conditions for Ultimate.

It was cold and raw for Wednesday's game but that's not what bothered me. I'm still battling my heel injury and am hoping I can make it through tomorrow's all day BUDA fall hat tournament.

Ultimate Statistics (since January 2008):
Total Games Played: 117
Total Hours Played: 137

October 20, 2008

Ultimate Defeated

Sunday October 19, 2008
10AM BUDA Fall Hat League Game
Fernald School, Waltham, MA
Weather: 41 F, Partly Sunny
Field: dry
Perfect conditions for Ultimate.

It was a chilly morning for our last regular season BUDA game on Sunday. Our team had a tough go of it this fall. Last fall I played on a fall hat team that went 7-0 during the regular season schedule. This year? 0-6. If anything positive came out of our game yesterday, though, it's that we played the number one undefeated team in the league and only lost by a few points. I still think we have the talent to put together a decent run in the all day tournament coming up this Sunday. I'm just hoping that my heel problems won't be too big of an issue!

Ultimate Statistics (since January 2008):
Total Games Played: 116
Total Hours Played: 136

Ultimate Heel

Friday October 17, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 55 F, Partly Sunny
Field: dry
Perfect conditions for Ultimate.

My heel problems continued during Friday's game. The symptoms are identical to the plantar fasciitis I experienced over a year ago. The solution last time? Limited playing time, over-the-counter orthotics, and the standard stretching, strengthening and icing. Unfortunately it took months for the problem to completely go away. Booo!

Ultimate Statistics (since January 2008):
Total Games Played: 115
Total Hours Played: 134

Ultimate Warm

Wednesday October 15, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 72 F, Partly Sunny
Field: dry
Perfect conditions for Ultimate.

Likely the last of the warm weather on Wednesday.

Ultimate Statistics (since January 2008):
Total Games Played: 114
Total Hours Played: 133

October 15, 2008

Ultimate Painful

Monday October 13, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 70 F, Partly Sunny
Field: dry
Perfect conditions for Ultimate.

It was a decent game on Monday, but unfortunately, it appears I'm starting to develop some heel pain. About a year or two ago, I had a case of plantar fasciitis plague me for a couple of months and the symptoms are similar to what they were then. Hopefully, I can fight it off a little quicker this time!

Ultimate Statistics (since January 2008):
Total Games Played: 113
Total Hours Played: 132

Ultimate Morning

Sunday October 12, 2008
10AM BUDA Fall Hat League Game
12PM BUDA Fall Hat League Game
Fernald School, Waltham, MA
Weather: 60 F, Sunny
Field: dry
Perfect conditions for Ultimate.

Sunday we played two games equaling four hours of BUDA fall hat league action. Our team is still a bit disorganized and lost both games again. We must be saving it for the tournament in two weeks!

Ultimate Statistics (since January 2008):
Total Games Played: 112
Total Hours Played: 131

Ultimate Catchup

Friday October 10, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 65 F, Partly Cloudy
Field: dry
Perfect conditions for Ultimate.

Typical Friday game.

Ultimate Statistics (since January 2008):
Total Games Played: 110
Total Hours Played: 127

October 9, 2008

Project Darkstar and Unit Tests

In my previous Project Snowman post, I mentioned that when developing games using Project Darkstar, there is a strong tendency to make gratuitous use of the AppContext class throughout all corners of your game server. Why is this a problem? Let me give you an example. Consider the following code:

public class Monster implements ManagedObject, Serializable {
  private int health;
  ...
  public void attack(int damage) {
    AppContext.getDataManager().markForUpdate(this);
    health -= damage;
  }
  ...
  public int getHealth() {
    return health;
  }
}

Now this is a pretty simple, stripped down class.  A Monster object has a health rating and this rating can be affected by inflicting damage via the attack(..) method.  So let's write a test for this method.

Since this is a unit test we don't want to fire up the whole Project Darkstar kernel; instead we want to just stub or mock out any dependencies this class may have. At first glance, though, it doesn't look like there are any, so this should be pretty easy right? Let's try:

public class TestMonster {
  @Test
  public void testAttack() {
    Monster testMonster = new Monster();
    int damage = 10;
    int finalHealth = testMonster.getHealth() - damage;

    testMonster.attack(damage);
    Assert.assertEquals(testMonster.getHealth(), finalHealth);
  }
}

All that we are doing here is instantiating a test Monster, and verifying that the attack method appropriately modifies the health of the Monster.  Does this test work though?  No.  The problem lies in the fact that there is a hidden dependency on the static AppContext method getDataManager().  When run outside of the context of a running Project Darkstar kernel, the behavior of this method is not defined (in fact it will throw a NullPointerException).  What's worse, since this method is static, it is impossible to mock its behavior to return a dummy implementation of a DataManager.  So what can we do?

For the Project Snowman effort, I devised a mechanism to wrap the AppContext static method calls in an interface called SnowmanAppContext. In fact, the strategy I used was very similar to the pattern described in this Google blog post which I just stumbled across today. This isolated the calls to the static methods in AppContext to within a single implementation of SnowmanAppContext. Unit testing became easy as I could simply replace the usages of SnowmanAppContext with a mocked out implementation.

Should this be done for all Project Darkstar games though? It seems like a built-in generalized solution should be possible. Fundamentally what is required for me to complete my unit test above is the ability to swap in a different context which is used by the AppContext underneath. Currently, the AppContext implementation is tied to the Project Darkstar kernel. If the kernel hasn't booted up, the behavior of AppContext is invalid. Since the AppContext is static, I can't stub it out. I am proposing a slight modification to the Project Darkstar API that would allow users to modify the behavior of AppContext to use whatever implementation that they would like. Further, this would completely decouple the Project Darkstar API classes from the current implementation. Here is my proposal:

First, add an additional interface to the core set of API classes:

public interface ManagerLocator {
  public ChannelManager getChannelManager();
  public DataManager getDataManager();
  public TaskManager getTaskManager();
  public  T getManager(Class type);
}

As you can see, this interface mirrors the set of methods that are exposed through the AppContext. The idea is that the AppContext will use a ManagerLocator underneath in order to retrieve each of the managers provided by the system. In order to set this, a static setter must also be added to the AppContext:

public final class AppContext {
  ...
  public static synchronized void setManagerLocator(ManagerLocator managerLocator) {
    ...
  }
}

Any implementation of the Project Darkstar API now must provide a class that implements the ManagerLocator interface, and set the context using the new AppContext setter method.  If these two minor changes are made, I can now complete the unit test that I originally set out to do using mock objects:

public class TestMonster {
  @Before
  public void swapContext() {
    ManagerLocator dummyLocator = EasyMock.createMock(ManagerLocator.class);
    DataManager dummyDataManager = EasyMock.createNiceMock(DataManager.class);

    EasyMock.expect(dummyLocator.getDataManager()).andReturn(dummyDataManager);
    AppContext.setManagerLocator(dummyLocator);
  }

  @Test
  public void testAttack() {
    Monster testMonster = new Monster();
    int damage = 10;
    int finalHealth = testMonster.getHealth() - damage;

    testMonster.attack(damage);
    Assert.assertEquals(testMonster.getHealth(), finalHealth);
  }
}

Now, this may not be quite how you'd set up your test with a real piece of code, but it demonstrates the point.  If you're not familiar with EasyMock, the code above essentially sets up a dummy DataManager that will be returned by the AppContext by putting it in a dummy ManagerLocator.  When the test is run, the call to AppContext.getDataManager().markForUpdate(this) will simply do nothing, and the test will pass.

I've coded up the necessary changes to the Project Darkstar server codebase for this API modification in a branch. If you're interested in having a look, the branch is located here. Feedback welcome!

Ultimate Marathon

Wednesday October 8, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 65 F, Partly Sunny
Field: dry
Perfect conditions for Ultimate.

Yes I played ultimate yesterday. However, I would like to take this opportunity to point out that Katy has been accepted onto the Dana-Farber Marathon Challenge team for the second year in a row. She'll be running her second ever marathon in Boston this coming April and raising money for cancer research during her training. Go Katy! (Again!)

Ultimate Statistics (since January 2008):
Total Games Played: 109
Total Hours Played: 126

Ultimate Chill

Monday October 6, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 55 F, Partly Cloudy, Breezy
Field: dry
Perfect conditions for Ultimate.

I'm behind documenting these games...

Ultimate Statistics (since January 2008):
Total Games Played: 108
Total Hours Played: 125

Ultimate BUDA

Sunday October 5, 2008
10AM BUDA Fall Hat League Game
Fernald School, Waltham, MA
Weather: 50 F, Cloudy
Field: soggy
Perfect conditions for Ultimate.

It's been a tough BUDA season so far this fall with all of the rainouts. Sunday we had two games scheduled but I was only able to make it to the first (a tough loss).

Ultimate Statistics (since January 2008):
Total Games Played: 107
Total Hours Played: 124

October 6, 2008

Ultimate Three

Friday October 3, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 59 F, Cloudy
Field: wet
Perfect conditions for Ultimate.

Friday marked three years to the day since I started working at Sun Microsystems (and also started playing regular pickup ultimate on Mondays, Wednesdays, and Fridays). I didn't start keeping track of my ultimate stats until this year, but if you extrapolate out the numbers, I would estimate I've played almost 450 games and almost 500 hours of ultimate since then!

Ultimate Statistics (since January 2008):
Total Games Played: 106
Total Hours Played: 122

October 1, 2008

Ultimate Downpour

Wednesday October 1, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 65 F, Downpours
Field: wet
Perfect conditions for Ultimate.

The weather didn't look all that threatening when I left for work this morning, but things changed quickly. We had basically torrential downpours for the whole game today. In fact, the rain we had for today's game was worse than Friday when only four showed up forcing us to play Double Disc Court. Today? Thirteen people came out for ultimate in the mud (fun!).

Ultimate Statistics (since January 2008):
Total Games Played: 105
Total Hours Played: 121

Ultimate Cloudy

Monday September 29, 2008
12PM Pick-up game
Mitre Fields, Burlington, MA
Weather: 60 F, Cloudy
Field: damp
Perfect conditions for Ultimate.

Good numbers for Monday's game. Everyone was anxious to get back out there after a wet, dreary weekend.

Ultimate Statistics (since January 2008):
Total Games Played: 104
Total Hours Played: 120