Another Victory for Occam's Razor · 30 June, 09:31 AM

I haven’t written much about the basement project lately. The framing went pretty quickly by homeowner project standards; after 4 weeks the framing was done, except for the fireplace and one wall in the office that I couldn’t put up until I had moved the water heater. Moving the water heater – that’s one of those jobs that 6 months ago, I would have hired out, or at least asked a more experienced relative to take the lead on. Today, I can say that’s one project I’ve done on my own.
Thursday night about 9 PM, I set in to move the water heater. The job isn’t that tough, in our house the pipe is CPVC, which is easy enough to work with: cut the piece to length, put primer on both surfaces to be joined, then put contact cement on both parts and stick the two pieces together. One caveat: you have to work quickly. The contact cement sets up within a minute. But overall, as scary as it is to cut into a water line, the work wasn’t difficult and it’s rewarding to see the pipes going together. Overall, there were two big boo-boos: first, although I labeled the lines (hot and cold) before disconnecting them, I got confused when I got to hooking up the heater to the relocated pipes: after I connected the cold water line, I suddenly realized that I’d hooked up the hot line to the cold side of the water heater. Since the contact cement basically sets instantaneously, I had to tear apart my work and re-do it. Except that once I’d done that, I realized that, no, the original version was correct, so I had to re-do my re-do. Fortunately, I’d bought a few extra connectors and had enough spare pieces to recover.
The second issue was more a lesson in problem-solving. It was about midnight when the heater was reconnected, and I went to the water main and opened the valve. But I couldn’t get water pressure up in the house. I spent about an hour hunting around, trying to figure out why the water wouldn’t turn on, before finally giving up and going to bed at 1AM. The next morning, I woke up early and started looking at the system again, but was completely stumped, until I looked more closely at the water main. In new houses, there are shutoffs on the main line before and after the water meter. When I’d turned off the main, I’d shut off both valves, but only turned on one when I tried to pressurize the line, and didn’t notice this because the second shutoff was covered by other construction materials leaning up against the wall.
In retrospect, it should have been obvious: when I turned on the main line and the lines didn’t immediately pressurize, I should have known something was blocking the main line. Occam’s Razor in action again. The second lesson is not to start projects like these at 9:30 at night.

— Gordon Weakliem

Comment

---

The State of the Fork in the Road · 20 June, 11:54 AM

If you haven’t read The Road We Didn’t Go Down, you really should. Joe Armstrong reflects on Steve Vinoski’s thoughts on RPC and CORBA (and by extension, WS-*).

Steve Loughran commented that

What needs to be considered is whether blocking method invocation is the main metaphor used in Java/C# style languages, because that is the only metaphor the language allows. You have objects, you have methods, so everything has to make your communication look like method calls on objects, passing other objects as parameters.

I know that .NET offers another metaphor that gets you part of the way; you can use delegates to build an event-driven mechanism. Still, it takes some major engineering to get away from the RPC model to be able to do CPS-style calls like Joe’s last couple of examples. My employer’s put that time in, so we can write things like this (assuming OnContinue, OnException, and OnTimeout are defined as methods):

pre(code).public delegate void SomeTaskDelegate(Continuation);
public void SomeTask(Continuation) { … }

Continuation.Invoke( new SomeTaskDelegate(SomeTask), new WaitCompleteDelegate(OnContinue), new Continuation.ExceptionDelegate(OnException), new Continuation.TimeoutDelegate(OnTimeout), TimeSpan.FromSeconds(1500), null); // parameters to SomeTask would go here

What I dislike about this is that it feels like you’re back in C – you have to declare everything twice; as a delegate (.h) and the implementation (.c) – the invocation is quite noisy because you’re trying to do something that’s not natural to the language. And as I mentioned, there was a considerable engineering effort to build the CPS framework. The lambda expressions and anonymous delegates C# 3.0 should make that somewhat more palatable. Rick Brewster’s example shows a simple implementation. What Rick’s example doesn’t address is the blocking problem Steve pointed to – what good is it to use CPS for remote operations if they still block? Volta is supposed to address this, but that’s a long way from being able to say that .NET developers have all this baked in the way Erlang bakes it into OTP.

— Gordon Weakliem

Comment

---

I Hate appSettings · 18 June, 07:42 PM

I don’t like because it’s unstructured and it’s too easy to jam new configuration values in. Actually, that’s not it. That’s a dumb reason. What I don’t like is that ConfigurationManager is always hanging around, so that arbitrary components can add dependencies on configuration settings that are difficult to keep track of, and difficult to debug on a live box.

It seems to me that a general rule of .NET development should be that only top-level (i.e. executable files or the top level dll of a web project) should be reading . It also seems to me that as a general rule, components should accept their configuration as a parameter (probably to the constructor) and not rely on the execution environment. That’s a simple one. It makes components easier to test because you don’t have to set up an execution enviroment.

— Gordon Weakliem

Comment

---

The Grass is Always Greener Over the Septic Tank · 18 June, 02:53 PM

Tim Bray’s Gnu Tool Moan really resonates with me, because I’ve been fighting battles with build tools in the Java/.NET world, specifically TeamCity. TeamCity is pretty slick in its own way, but I keep thinking to myself that make had this pretty much solved a long time ago. Apparently make and autoconf aren’t all that, after all.

I seem to remember that one big driver behind the creation of Ant was frustration with make, specifically with the syntactic whitespace. That doesn’t seem to have slowed Python too much, and the story’s possibly apocryphal, but nonetheless, Ant’s here, and it’s quite a bit different from make.

Ant implemented one philosophy that TC has picked up on: it turns dependencies on their head, where targets now output artifacts that trigger other targets. The make way of doing things, where a target evaluated its dependent targets before executing, seems like a better way to operate. TeamCity actually makes the artifact dependencies somewhat difficult to use, in that it doesn’t optimize dependencies to minimize the number of builds. If you’ve set up dependency triggers on a project that occurs multiple times in the dependency chain, you can have dependent projects getting built several times. For example, if A.dll depends on B.dll and C.dll, and B.dll also depends on C.dll, building C.dll may cause A.dll to get built twice: once by the C.dll trigger and again by the B.dll trigger. That’s probably on the “features to implement” list, but OTOH, I doubt that make has that problem.

— Gordon Weakliem

Comment

---

The Second Stone · 10 June, 08:18 PM

So today Dare takes NewsGator to task for the (mis) design of the NewsGator REST API. At one time, some people thought it wasn’t too shabby, but I guess everybody’s tired of beating up on Flickr and Bloglines, and so it’s NewsGator’s turn. I kind of feel a certain ownership of the thing, since I was the original designer. Now that baby’s moved on to foster parents, and I should probably just let it go, but some of the sins Dare mentions might be mine. It’s been a couple of years, and I can’t exactly recall. But in the interest of absolution, here’s what I remember about designing the REST API.

In light of some of the But this is just POX crap! accusations, here’s some backstory: the original version of the REST API was created concurrently with the SOAP API, but it was never released. This was a good thing; the original (unreleased) REST API was RPC/POX over POST, mainly because I was looking at the Bloglines API for guidance. So that work benefited from a cooling off period. Dare’s not been exactly fair: he’s highlighted the places where the NG REST API falls down, but he hasn’t highlighted the places where it does the right thing. There are some places, right Dare?

Incidentally, the guiding light behind the whole thing was Joe Gregorio’s Aggie application; which had the option to put in the URI of an OPML subscription list. Aggie was my first experience with sync in a feed reader, and a lot of my thinking around this design went back to Aggie: how can I create an API that will work for a brain-dead simple aggregator? I wasn’t always successful, but that was my primary design constraint.

Dare’s dead on on his section “What Should a Feed Reader’s REST API Look Like?” – “There are two main resources or data types in a feed reader; feeds and subscription lists.” NewsGator actually defines a few other resources: Locations, Folders, and various other types that were added later. Indeed, the NG API exposes endpoints Location.aspx, Subscription.aspx, Folder.aspx and Feed.aspx. But Dare rightly calls out a number of instances where the NG API puts a verb into the URI. I should point out that it’s not necessarily practical to rely on PUT and DELETE; as not every client is capable of using these verbs; as I’ve noted before sometimes the issues are subtle. But putting the verb into the URI is not the answer; in these cases, putting the verb into the payload is a less bad solution.

For sin #2, not providing a consistent interface, this was actually one of the big design changes between the pre-release and public-release versions of the API. Originally, I was encoding most of the parameters in POST as ordinary application/x-www-form-urlencoded data. My big realization was that if a GET returned an OPML document, then the POST should accept an OPML document – endpoints should be reflexive on their input and output. So for the most part, the NewsGator REST API does this. Dare points out one example where it doesn’t (given that it also encodes an operation in the URI, is that surprising?) However, in some cases, a response isn’t always necessary: the client should expect a certain state to result from an operation and if the server’s merely going to tell the client what it already knows (i.e. I added a folder, therefore I know what the new folder structure is going to be), the server can eliminate the response and rely on the response code to tell the client whether the operation worked. The one issue would be with concurrent updates from other sources – it’s possible that state could change on the server and the client would have to do a GET to find out about these changes. Still, I’m not sure that necessitates returning a response; as an application developer, I think it’d be confusing to get back a totally unexpected state change from an operation.

Dare mentions AtomPub as a candidate protocol for this application. I’m not so sure about using AtomPub for a feed reader API; I haven’t looked closely enough at it, but it’s really intended more for publishing and I have a feeling that it would be a poor fit; my gut feel is that you’d be forcing a square peg in a round hole with AtomPub in this situation. It’s also worth noting that at the time of the design, Atom 1.0 was not yet released and AtomPub was nowhere near release.

I also want to point out Dare’s statement “You will want full Create, Retrieve, Update and Delete operations on the subscription list. So you will need the full complement of supporting POST, GET, PUT and DELETE on subscription lists.” This isn’t exactly how you’d want to look at the HTTP verbs, as the CRUD analogy extends only so far. What you’re after is a description of the state of the application. Hypermedia is the engine of application state, after all. It all comes back to the URIs. If your URI’s don’t describe resources, it ain’t REST. If your resources don’t link to each other, it probably ain’t REST.

— Gordon Weakliem

Comment [2]

---

Older