HTTP not ideal for asynchronous stuff (“Are we nearly there yet?” “No.” “Are we nearly there yet?” “No.” “Are we nearly there yet?” “No.”). Message-passing architecture is better (“Let me know when we’re there” … “We’re there!”).
Also useful for clusters, multi-core machines etc.
Erlang
(also Scala, Haskell, E etc) are becoming interesting because they operate using messages. Not that different to pure OO. No shared state. Scalability doesn’t come for free, but it’s much easier.
Spread
, MQ, JMS etc: publish and subscribe. Stick a message on a topic or queue and any subscribers receive it. Allows very loose coupling. One-to-many, with publisher not needing to know about subscribers.
Comet
allows a connection to be held open between browser and server, rather than having to poll.
Jabber can be used to return future results for a search (for example). “There will always be more pictures of kittens.”
Worker queues remove expensive calculations from synchronous tasks (eg calculating Dopplr coincidences does your own immediately, and queues a job to calculate coincidences for all your contacts).
Using JQuery you can create your own events in a browser. Becomes more like traditional GUI programming.
Extreme late binding: combine data and code in application (eg javascript and data in browser – mashups).
The Internet is the computer.
First question: “How does Dopplr work?” :-)
Interesting point about hiring: go for the people who are good at the cool stuff (Erlang, Haskell, etc), because they’ll probably be really good at the workaday stuff too, and are obviously interested in the field.
[tags]barcamplondon3, messaging, erlang[/tags]
Caja
compiles Javascript into different javascript, allowing you to put untrusted gadgets in trusted container pages (eg
OpenSocial
). Removes potentially evil code (eval etc), and passes in an object representing the global scope (
document
etc).
Ben’s writing a Caja wrapper for OpenSocial. Lots of hairy stuff with closures wrapping callbacks in functions, then wrapping the response in more functions. I haven’t really looked at OpenSocial yet, so some of this is flying merrily over my head.
[tags]barcamplondon3, caja, opensocial, javascript, gadgets[/tags]
Screen-scraping HTML is evil. APIs are better, and can return structured XML, JSON or even SOAP (everyone laughs at the latter!)
If page is marked up semantically using microformats, an XSL stylesheet can convert it into RDF. Put the stylesheet on a profile page and link to it from the HTML (
<head profile="...">
), and
triplr
can generate triples from it in various formats. This can then be parsed using
SPARQL
.
The end result is custom
microformats
, possibly specific to your site, or something like
class="nsfw"
to mark up stuff that’s not safe for work, which Tom uses on his
blog
.
GRDDL
allows
[tags]semanticweb, grddl, barcamplondon3[/tags]
This
session
was run by Karl Scotland & Johanna Hunt. I helped run a
coding dojo
at work for a while, until it just kind of fizzled out, so I was interested to see how someone else approached it.
The twist was that the dojo was run using
Inform 6
, which is a domain-specific language for writing text-based adventure games (“You are in a maze of twisty little passages, all alike…”). this meant that none of the participants were familiar with the language, which forced us to take very small steps rather than quickly hacking together large chunks of code based on experience.
The baby steps thing seemed to work quite well, helped by the strict five minute pair rotations (driver back to audience, navigator to driver, audience member to navigator). Those rotations weren’t quite like the way we used to do it (we never really settled on a fixed policy, and experimented with
ping-pong pairing
, swapping both people out of the pair at once and increasing timeslots to ten minutes). We also weren’t as strict about banning suggestions and comments from the floor – stopping that seemed to help avoid circular conversations and let the pair get on with coding, although the unusual language may have helped here too. It was very frustrating though when you could see an mistake that was causing compilation errors, but the pair hadn’t seen it yet.
As it turned out we only got about halfway through the tasks we’d been set. It was quite an enjoyable hour and a half, but I’m not sure how much I learned.
[tags]xpday, coding dojo, pair programming, inform6[/tags]
Jeff gave
an entertaining presentation
on strategies for coping with the inevitable changes that take place during a project release. The talk was punctuated with blasts of music from various artists filling in as personas, from Mel B as a developer capturing user stories (“So tell me what you want, what you really really want”) to Johnny Rotten as an experienced agile practitioner (“Don’t know what I want, but I know how to get it”).
Many companies are now adopting agile methodologies such as Scrum to jump on the agile bandwagon, and are looking for consultants to provide training, and to come in and tell them all the answers to their problems. Because they are looking for prescriptive processes that they can put in place for people to follow, we are starting to see ever-more complex systems for things that were previously considered simple tasks (such as prioritising user stories). This is what Fred Brooks referred to in
No Silver Bullet
as ‘accidental complexity’ – complexity in the activities around writing software, rather than in the domain of the business problem you’re supposed to be solving.
Is this process rigor, or rigor mortis?
We have forgotten the meaning of iteration, and are working in increments instead. We are expecting an ‘iteration’ to contain a number of fully-completed stories, which we can then forget about and move on to new features. The problem with this is that when we deliver those stories, the customer is not entirely satisfied, and we have to introduce new stories to refine the design. This in turn affects our velocity, because we find ourselves spending more and more of our time enhancing features that we thought were done.
It’s not iteration if you only do it once.
Alastair Cockburn has suggested a ‘three story’ approach, where you make the iteration explicit by putting two additional cards behind each user story – one to fix the original story, and another to fix the second attempt. Jeff’s only concern with this was that people might take it too literally, doind a seond rework even if the customer was already happy, or stopping after the third story when the feature clearly wasn’t really done.
Along with YAGNI, Jeff suggested adding YAGRI (you ain’t gonna release it). This was to remind us that it’s OK to present non-production features to the customer, in the knowledge that they won’t be released until they’ve been iterated into a deliverable state. To me that seems OK for shrink-wrapped software and other things where iterations aren’t released, but I wonder how it applies to web applications, where it is becoming the norm to release small changes frequently (perhaps multiple times per iteration). In that case, we’re used to making the assumption that everything is always releasable. Maybe the answer is to separate new, ‘beta-quality’ features from the main body of functionality.
Three strategies for coping with the inevitable uncertainties in building a release were described:
Follow the Money
Prioritise the business goals. By focussing on the things with the highest value to the business you restrict the user constituencies which you should target first, and hence identify the highest priority user stories.
Don’t Choose the Solution Too Early
Focus on the user goals rather than the perceived requirements on the application, and consider and discuss alternative ways of meeting those goals. It may be that a simpler or cheaper implementation than the immediately-obvious one may be sufficient.
Build up Quality in Iterations
Sometimes the customer really does need everything to be implemented before the product can be released. In this situation, you can start by implementing stories to a very basic, almost prototype, level. You then build up the quality iteratively, using feedback from the rough-cut implementations to guide you. One way of doing this is to grade each story (eg A+ down to F, plus I for incomplete), then have a ‘passing grade’ at which the feature is considered fit for release.
One consequence of actually iterating, rather than using ‘iteration’ as a label for an incrementl chunk of functionality, is that there’s a lot more work for the customer (or product owner, or whatever you want to call them). They need to work frequently with the developers to evaluate each version of a story’s implementation and describe the changes necessary to make it fit their needs.
The summary of the talk was to
question common practice
and to
trust your instincts
. As an aside, that leads into a rant I keep meaning to get round to, on the subject of people who say that a particular behaviour “isn’t agile”, because it doesn’t fit the letter of their particular methodology of choice. Watch this space.
[tags]xpday, iteration, agile[/tags]
I Spent some time yesterday tracking down a bizarre bug which was causing some of our Selenium tests to fail. Watching the browser running the tests, I could see that occasionally a page would fail to render, with an “invalid argument” error and a stack trace. The line in question was an
<%= end_form_tag %>
in a layout. The strange thing was, it didn’t display the same behaviour when I ran the single failing test on its own, or when I viewed the page myself.
Or at least, I thought it didn’t. Because it seemed intermittent, I tried reloading the page a few times, and sure enough, the error appeared. Once. Then the page reloaded successfully six times, before failing again. This was completely repeatable – six times OK; one stack trace. Regular as clockwork.
Completely stumped, I thought I might as well at least replace the deprecated
<%= start_form_tag %> … <%= end_form_tag %>
with
<% form_tag do %> … <% end %>
, and lo and behold, that fixed it.
Unfortunately, I have no idea why. An imaginary prize to whoever can explain it!
As far as I can tell, this is
the correct way
to do case-insensitive string comparison in Ruby:
if string1.casecmp(string2) == 0
# strings match, ignoring case
That’s so ugly, it almost looks like Java. Actually, it’s worse than Java, which has
String#equalsIgnoreCase
.
[Update] The story runner is now included in the 1.1 release of RSpec, so a lot of the hackery mentioned below is no longer required. See
http://rspec.info/
for details.
Background
A while ago I cobbled together some code to
drive Selenium from Exactor
(which was the acceptance testing framework we were using at the time). That project was offshored shortly afterwards, and I’m pretty sure Selenium never actually got integrated into the build (sneaking a peek at the continuous integration server reveals that even the pre-Selenium acceptance test build hasn’t run successfully for months), but I was convinced of the value of Selenium for testing non-trivial web applications.
On my next project (the
Web21C SDK portal
) we used
Selenium on Rails
heavily for automated acceptance testing. This worked well, although the fact that the tests are deployed with the application limits what you can do – you can’t interrogate the database after a test, for example, or dynamically set up stubs for systems you interface with (unless you also deploy the stubs as part of the application, and drive them from the browser).
With
Mojo
there’s an additional complication: as well as being accessible through a browser, most functionality is also available as a RESTful API, using digest-based authentication. To keep our acceptance tests in one place, we wanted to be able to drive a browser using Selenium, alongside other tests which talked to the server directly. The obvious answer was to use
Selenium Remote Control
, and I also liked the look of RBehave, which has now been incorporated into RSpec (but not released yet).
The RSpec story runner
The story runner in the upcoming release of
RSpec
is an evolution of Dan North’s
RBehave
, which in turn is based on
JBehave
(from the same author). In the past couple of weeks, David Chelimsky has done some excellent work on extracting the text of stories from the code, leading to the
plain text story runner
.
Read on for the gory details of my solution to running Selenium tests from the story runner.
I was quite excited to see the announcement of
improved Ruby and Rails support
in Leopard, and one of the first things I did after upgrading was to delete my MacPorts installations of Ruby and RubyGems, and try using the built-in ones instead.
For a while, all seemed well. The milk was cold, the food stayed fresh, my specs still passed, my Rails projects still worked, and even the light worked when you opened the door.
But then the trouble started.
Firstly I tried updating and installing gems while behind a firewall. The
gem
command completely ignored my
http_proxy
setting, and when I explicitly provided the proxy using
-p
, I got this error:
ERROR: While executing gem ... (NoMethodError)
undefined method `[]=' for #<:configfile:0x56ea14/>
I worked round this by downloading the gems manually and installing the local copies (despite this being a pain, especially when there are dependencies).
I then tried using
gemsonrails
to freeze some gems, and it got confused by the fact that Leopard stores built-in gems separately from user-installed ones. Thinking about it, if I’d successfully frozen the gem, it might have turned out to have been tweaked in some Mac-specific way and broken on other platforms.
Forgetting about that issue, I carried on with other work for a while, then found that autotest wouldn’t work, and mysteriously was trying to run something from
/opt/local
(where MacPorts install lived). Even after removing any gem-related scripts from
/opt/local/bin
, the problem persisted.
Oh well, looks like I’ll be re-installing everything using MacPorts. I’m not sure whether all these problems are intrinsic to the Ruby installation that comes with the system, or whether some are caused by lingering remains of my MacPorts installation – I’d be interested to hear how others got on.
[tags]ruby, rails, mac, 10.5, leopard[/tags]