Skip to content

Instantly share code, notes, and snippets.

2010 Modularity Olympics

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:

  1. the “enhancements” must be specified in a configuration object which is consumed at run-time (e.g., it could be based on user-input).
  2. 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.
  3. 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.
trait Query { def i: Int }
// A Query and a Query Decorator
case class SimpleQuery(val i: Int) extends Query
case class TimingOutQuery(timeout: Int)(query: Query) extends Query { def i = query.i }
// Factories
type QueryFactory = Int => Query
// A thing that needs to make Queries
import scala.collection.mutable._
// I want these std functions to be implicit:
implicit def tupled[a1, a2, b] = Function.tupled[a1, a2, b](_)
implicit def untupled[a1, a2, b] = Function.untupled[a1, a2, b](_)
class Connection
class ConnectionPool(size: Int) {
def withConnection[A](f: Connection => A) = f(new Connection)
@nkallen
nkallen / gist:316595
Created February 27, 2010 09:08
This is a prototype of a technique for testing distributed race conditions.
/*
This is a prototype of a technique for testing distributed race conditions.
Here is an example,
Suppose we have a command that performs an operation across two or more components.
And suppose more than one of these commands is run in parallel (across processes).
The race conditions will occur as each command process independently invokes methods
on these components in various orders.
class NotifyingFuture[A] extends Future[A] {
import NotifyingFuture._
private var result: Option[A] = None
private val computations = new ArrayBuffer[A => Unit]
def setResult(result: A) {
setResultIfEmpty(result) || {
throw new ImmutableResult("Result set multiple times: " + result)
}
import java.util.concurrent.atomic.AtomicReference
class Serializer {
abstract case class State {
def +(other: Unit => Unit): State
}
case object Idle extends State {
def +(other: Unit => Unit) = Working(List(other))
}
case class Working(items: Seq[Unit => Unit]) extends State {
@nkallen
nkallen / gist:787081
Created January 19, 2011 23:08
Some scatter/gather timeout idioms
/**
* The following code represents the "best effort" idiom, where N parallel requests are made
* and for those that fail to return within a global timeout, we use a default value.
*
* Below are three implementations of the same idiom. The building blocks are CountDown latches,
* which are a kind of barrier, and Timer threads. I'm not sure which is best.
*/
"Weaver" should {
"weave" in {
var timer: JavaTimer = null
@nkallen
nkallen / Benchmark A
Last active December 22, 2015 02:49
Performance for loading a blob at a particular commit and accessing some of its immutable fields. Benchmark A access its fields and crosses the runtime boundary for each field access. Benchmark B does not access any fields and thus doesn't cross the runtime boundary as often (to be precise, 7 times versus 4 times). As you can see, performance is…
var git = require('../'),
path = require('path');
// This example opens a certain file, `README.md`, at a particular commit,
// and prints the first 10 lines as well as some metadata.
function doIt(cb) {
git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) {
if (error) throw error;
@nkallen
nkallen / gist:6430565
Created September 3, 2013 22:38
Valgrind output from nodegit/wip's example/walk-history.js
var git = require('../'),
path = require('path');
git.Repo.open(path.resolve(__dirname, '../.git'), function(error, repo) {
if (error) throw error;
repo.getMaster(function(error, branch) {
if (error) throw error;
for (var i = 0; i < 20; i++) {
==27613== Memcheck, a memory error detector
==27613== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==27613== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==27613== Command: node --expose-gc example/walk-history.js
==27613==
==27613== Warning: noted but unhandled ioctl 0x5451 with no size/direction hints
==27613== This could cause spurious value errors to appear.
==27613== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.
==27613== Warning: noted but unhandled ioctl 0x5451 with no size/direction hints
==27613== This could cause spurious value errors to appear.