spray/spray-can — Issue #12: Strange timeouts when implementing simple Proxy
Author: jedws
Created: 2011-12-13 07:12:06+00:00
State: open

I wrote a simple proxy to test the scalability of spray for an eval, and it isn't very promising. It tends to die around 8230 connections into an 'ab' test:

extra:test jwesleysmith$ ab -n 10000 -c 50 http://localhost:8080/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
apr_poll: The timeout specified has expired (70007)
Total of 8238 requests completed

Yet when I run it against the original proxied page it returns fine.

The code is from the examples:

```scala
object Main extends App {
Supervisor(
SupervisorConfig(
OneForOneStrategy(List(classOf[Exception]), 3, 100),
List(
Supervise(Actor.actorOf(new RequestActor("test-endpoint", new Proxy())), Permanent),
Supervise(Actor.actorOf(new HttpServer()), Permanent),
Supervise(Actor.actorOf(new HttpClient()), Permanent)
)
)
)
}

class RequestActor(id: String, handle: (RequestContext => Unit))
extends Actor {
self.id = id

protected def receive = {
case ctx: RequestContext => handle(ctx)
case Timeout(method, uri, _, _, _, complete) => complete {
HttpResponse(status = 500).
withBody("The " + method + " request to '" + uri + "' has timed out...")
}
}
}

class Proxy extends (RequestContext => Unit) {
val log = LoggerFactory.getLogger(getClass)

def apply(ctx: RequestContext) {
HttpDialog("server-test", 8081).
send(HttpRequest(method = GET, uri = "/")).
end.
onComplete {
_.value match {
case Some(Right(response)) => {
ctx.responder.complete(new HttpResponse(body = response.body))
}
case error => log.error("Error: {}", error)
}
}
}
}
```

No errors are being reported.