Never trust 1.1 of anything#
Tue, 03 Jul 2007 20:04:25 +0000
* (in-package :araneida)
@#@
* (parse-protocol-version "HTTP/1.1")
11/10
* (>= * 1.1)
NIL
The bug has been there for years - probably since before Araneida was named - but it's only when today I was debugging persistent connections that I actually noticed it. "Why's it closing the connection
every time? Ah..."
Should anyone be curious about the (lack of) development of Araneida, this is the official status as far as I am concerned
301 Permanently redirected
Location: try Hunchentoot instead
Araneida is dead for almost all practical purposes.
- Aranother* is a working title for the web server that serves www.stargreen.com and which might possibly be of interest to other people who have exactly the same needs from a web server as I do: it runs on threaded SBCL and Linux, and (like its predecessor) prefers to be behind Apache mod_proxy. What it has, or at least is drifting rapidly towards having, that Araneida doen't, is HTTP/1.1 persistent connections and chunked transfer encoding (so that persistent connections continue to work even when you don't know the response length in advance). The latter is built on the SBCL sort-of-public ansi-stream extension interface: your only chance of getting that to work in another Lisp is if the other Lisp is CMUCL-derived as well.
Once the remaining bugs in those features are found and ruthlessly exterminated, the next thing I want to investigate is all the new bells and whistles in apache 2.2's modproxy, because with persistent connections I can see no reason it shouldn't be very nearly as fast as one of the special-purpose connectors (modlisp, mod_jk, etc) and it appears to do all kinds of neato load-balancing and failover and stuff as well.
There will be no release in the imminently foreseeable future, because that would give out entirely the wrong messages about stability and publishedness of interfaces. There's a darcs repo at http://src.telent.net/araneida and it's updated as often as I remember to type rsync (probably about once for each time I blog on the subject)
Getting better all the time#
Wed, 18 Jul 2007 00:37:45 +0000
Turns out I'm even more of an armchair cyclist than I am an armchair
skater: I haven't actually mounted the dratted thing in the last
fortnight, but, my interest having been attracted by seeing Stage 1
start in London, I have been spending an ordinate amount of time
watching the Tour de France. While humming "Hurt" (the Johnny Cash
cover, not the NiN original) because "focus on the pain" just seems so
appropriate... I'll save my amateur cycling-vs-skating observations
for another time, though.
Still haven't been feeling much like "training" any time recently,
though I've been skating reasonably appreciable distances every time
I've been motivated to skate anywhere at all: last Sunday 60km, 40km
on Tuesday for route check (home->park 10k, RC 20k, home again 10k)
which was actually rather good fun, and then the same again on Friday.
My New Trick (crossover armswing) has brightened up my left turns no
end: sooner or later I'm going to have to work on the right side as
well, thobut. Have also been thinking on and off about setdown angle
on uphills and for acceleration, and got a lovely lovely sprint up the
last part of St James St at the end of the LFNS on Friday where it
seemed like my feet were landing on the ground in exactly the right
place every time. The route went around Swiss
Cottage/Camden/Haverstock Hill; it's one I worked out last autumn and
never actually got as far as running because downhills are treacherous
to lead a marshalled skate down if there's any chance they'll be
slippy. Lots of good feedback.
Up south downs#
Wed, 25 Jul 2007 18:26:55 +0000
I could blog about Saturday's Eastbourne skate, but I wrote about it once already so why repeat myself? 120k as measured by Alex's GPS (the battery in mine died after 80, which I'm a bit unimpressed by) plus call it 10k in the morning to get to Hyde Park Corner where we started.
Other than that, not a lot. LFNS on the Friday preceding (10k to get there, 20k of marshalling, lift home) was an opportunity to practice accelerations but unfortunately also provided a chance to whack my kneecap which makes it still feel a bit funny: not skated again since Saturday while I rest it.
Testing times#
Fri, 27 Jul 2007 18:33:46 +0000
For the last, oh, seven years, I've been aware that the mature and responsible programmers all do Test-driven development and never write any code before they've written the test that justifies the need for it. Which, I guess, is fair enough, but then they go on to claim this is really enjoyable and makes programming so much more fun and at that point I just have to look at them and go "huh?". I'm happy to believe that it takes all sorts to make a world, but if I derived significant pleasure from jumping through hoops like that I'd get a job as, uh, a hoopjumper or something. If the code has particularly complex side-effects or dependence on state, TDD requires lots of fannying around with MockObjects and the like (which end up being complex enough to need tests of their own) to fake the state; if the code is written in a functional style and does the same thing every time you run it, you can test it in the repl and don't need all the framework crud.
(I think my viewpoint is probably skewed by very rarely having an external customer or sufficiently concrete requirements. This makes the programming something of an exploratory process anyway)
One place, though, that I am reluctantly forced to concede the value of testing is for avoiding regressions. But I'd still like to avoid all that effort collecting test cases and packaging them up, especially when I've probably white-box tested most of the logic in the course of developing it. So, without further ado: requires Emacs, Slime, etc -
(defslime-repl-shortcut slime-repl-shortcut-record-test ("record-test" "t")
(:handler 'slime-dan-record-test)
(:one-liner "Resend last input, recording it and results in \"tests.lisp\""))(defun slime-dan-record-test ()
(interactive)
(let ((last (copy-sequence (car slime-repl-input-history)))
(package (slime-lisp-package)))
(with-current-buffer "tests.lisp"
(set-text-properties 0 (length last) nil last)
(slime-repl-set-package package)
(goto-char (point-max))
(insert "\n;; sent\n" last "\n;; received\n")
(goto-char (point-max))
(slime-eval-print last))))
How this works: once you have typed in a form at the slime repl and got the right answer back, you hit
, t
(comma, t) and it logs the input text and return value in a file called tests.lisp (it actually evaluates the form again, but that's ok, right? it's all functional). Then you can trivially write something to repeat the tests which zips through said file evaluating odd forms in CL and comparing the results to what you get evaluating even ones. When I say "trivially", what I mean is of course "I haven't done that bit yet".
Most of th development time was spent muttering "that's not a string? that's a string? why does it look like a structure? hmm, it behaves like a string until I send it to slime" before eventually finding out that it was a string with properties. Bless you, emacs, for your backward-compatible data structures. tests.lisp
ends up looking something like this -
;; sent
(+ 1 2) ; this is a comment
;; received
3
;; sent
(to-sql '(project ((as (from-universal-time date) ident) name) venue))
;; received
"SELECT FROM_UNIVERSAL_TIME(DATE) AS IDENT,NAME FROM VENUE "
Coming soon: SEPTEQL (successor of SEXQL which I wrote three years ago and have used very rarely since just because the syntax is so utterly unmemorable). I just have to clean it up a little and, uh, write some tests.
(Discovering from adjacent entries in that blog that my Athlon's about three years old makes me feel much better about replacing it with something that has a working free graphics driver - that would be an Intel motherboard, then - and doesn't die randomly for no apparent reason as the Athlon has taken to doing. I thought it was newer than that)
Back at Goodwood#
Tue, 31 Jul 2007 16:19:23 +0000
... and, back after Goodwood too. Yesterday it was still aching;
today the rest of me also aches, I'm shivering and my throat is complaining: I begin
to suspect I may be suffering a cold.
The event benefited from the Camberley crowd's same slick management
as they conditioned us to expect last year, and was also notable for
the relatively vast numbers of entrants: 213 people! Kudos to them on
both counts. It's a nice wide track and no danger of overcrowding.
A practice lap established that the wind had changed direction since
last year. The headwind after the first corner seemed much less of a
"brick wall" than I remembered from 2006 or 2005, but the flip side
was that the wind on the start/finish straight and the downhill
leading to it was much stronger.
Off the start, and the lead paceline formed within a few seconds: as
usual for British races everyone at the front was the epitome of
politeness ("no, I insist you go first"). This lasted until just past
the first corner, when James Ashby flew off, with Orgill, McInnerny
and Andy Porter following, and Fred and me pursuing but failing to
catch. By the time we got to the last corner before the start/finish
the rest of the line had caught us too, so we settled down in a mostly
LSST line - about eight initially, gradually depleting, including one
or two Powersliders (who, all credit to them, were not shirking
approximately their fair share of doing the work - or at least, not
more so than I was)
This was followed by nine laps in that line. James and Chris lapped
us somewhere around lap 8: James slowing very briefly before powering
up the warp generators again and disappearing into the distance; Chris
hung with us for a couple of laps before taking off again on the back
straight on our lap 10 (his 11).
Last lap: the start/finish was marked by similar outbursts of
politeness as had been evident at the race start, so we went around
the first corner a bit spread out across the road. I was lagging at
the back waiting to see who broke first (special eye on Fred). Fred
made his move, I followed, Andy followed, I don't know who else was
with us at that point. At the water stop, Fred pulled off and I went
past - then looked back a few seconds later and found there was a
clear gap between me and everyone else. So, reasoning that there was
no way I'd win a sprint finish against Andy or Fred and if I had any
chance at all it was over a longer distance, I went for it.
Unfortunately, it wasn't enough: the back straight (with a tailwind)
is deceptively fast easy skating, and only when I turned back round
into the headwind did I realise I didn't have much left. They caught
and passed me again at the end of the downhill, and I came in sixth in
1:23:36. Wasn't particularly impressed at the time, but post-race
reflection says that everyone in front of me (except Fred) was Cat 1,
and I finished within 5 seconds of one of them. So perhaps not that
bad really.