Magic Scaling Sprinkles

Just another WordPress.com weblog

2010 Modularity Olympics

with 2 comments

This is a contest, open to programming languages from all nations, to write modular and extensible code to solve the following problem: Implement a service that can run queries on a database.

The Challenge

Sounds simple right? Wrong! A programmer without control over the source-code of that service must be able to later add enhancements such as statistics collecting, timeouts, memoization, and so forth. There are a few more requirements:

  • the “enhancements” must be specified in a configuration object which is consumed at run-time (e.g., it could be based on user-input).
  • The enhancements are ordered (stats collecting wraps timeouts, not the other way around) but it must be possible to reverse the order of the enhancements at run-time.
  • The enhancements must be “surgical” and not “global”. That is, it must be possible to simultaneously have two query services, one reversed and one not reversed, and even have a query service without any enhancements.
  • The code must be thread-safe or support using concurrency by some means. The same query service can be used by multiple threads as well as multiple threads with different query services.

Most programming contests emphasize things that are not modularity. This contest emphasizes things that are modularity. And its the olympics and don’t you want to be olympic? So go ahead and prove to the world that Design Patterns are no longer necessary, or that Haskell is the raddest thing since the movie Rad, or that Peanut Butter is better than Jelly. This is much more fun than inflamatory blog posts and angry reddit comments, yes? Yes.

Context

Please read my blog post on modularity techniques in Scala and various responses (in Clojure, in Ruby, in Ruby again)

Languages & Techniques

You can use any programming language you like (functional, OO, stack-based) and any techniques you like. Your main goal should be clarity and flexibility. Terseness is valuable where it adds to clarity. Creative and unusual solutions are welcome, though. Try to implement all of the functionality (including transactions) of the sample solution.

How to Play

Fork this gist. Your program must produce the same output as mine (included below). I will collect all forks at link them here (it may take me a while, so please be patient).

Sample Program

I’ve tricked out some Factories and wrote this little diddy in Ruby:

config = [
  [:memoizing, []],
  [:timing_out, [2.seconds]],
  [:stats_collecting, [Stats.new]]
]
query_factory = config.inject(Query) do |factory, (decorator_name, settings)|
  "#{decorator_name.to_s.classify}QueryFactory".constantize.new(factory, *settings)
end

[query_factory, ReversingQueryFactory.new(query_factory)].each do |qf|
  query_evaluator = QueryEvaluator.new(ConnectionPool.new(20), qf)
  query_evaluator.transaction do |t|
    t.select("SELECT ... FROM ... FOR UPDATE ...")
    t.execute("INSERT ...")
    t.execute("INSERT ...")
  end
  puts
end

Sample Output

Note the reversing order of the enhancements and the memoization of Query instantiation:

Forward:
Instantiating Query Object
Selecting SELECT ... FROM ... FOR UPDATE ... on #
Did not timeout! Yay fast database!
Measured select at 1.00 seconds
Instantiating Query Object
Executing INSERT ... on #
Did not timeout! Yay fast database!
Measured execute at 1.00 seconds
Executing INSERT ... on #
Did not timeout! Yay fast database!
Measured execute at 1.00 seconds

Backward:
Instantiating Query Object
Selecting SELECT ... FROM ... FOR UPDATE ... on #
Measured select at 1.00 seconds
Did not timeout! Yay fast database!
Instantiating Query Object
Executing INSERT ... on #
Measured execute at 1.00 seconds
Did not timeout! Yay fast database!
Executing INSERT ... on #
Measured execute at 1.00 seconds
Did not timeout! Yay fast database!
Advertisement

Written by nkallen

February 16, 2010 at 6:59 am

Posted in Uncategorized

2 Responses

Subscribe to comments with RSS.

  1. Why would I want to do this? What’s my motivation?

    Do I really want to spend my own time solving a problem that someone else is having at work or in their client’s project? For nothing?

    Just kidding about that, but I wouldn’t be if this didn’t say “any language”. And I do wonder what my motivation might be. Recognition on your blog? Do I really even want that?

    (Ed. You know you want it.)

    eachus

    February 16, 2010 at 9:05 am

  2. OK, I took a swing at it. I just started learning Scala so I used it as my learning project. I think it works OK. Have a look at the baldmountain fork.

    geoff

    February 20, 2010 at 2:42 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.