In my testing below, I tried to simulate a timeout and then send a normal request. however, I got spray.can.Http $ ConnectionException: closing the connection prematurely (the server does not seem to support pipelining the request)
class SprayCanTest extends ModuleTestKit("/SprayCanTest.conf") with FlatSpecLike with Matchers { import system.dispatcher var app = Actor.noSender protected override def beforeAll(): Unit = { super.beforeAll() app = system.actorOf(Props(new MockServer)) } override protected def afterAll(): Unit = { system.stop(app) super.afterAll() } "response time out" should "work" in { val setup = Http.HostConnectorSetup("localhost", 9101, false) connect(setup).onComplete { case Success(conn) => { conn ! HttpRequest(HttpMethods.GET, "/timeout") } } expectMsgPF() { case Status.Failure(t) => t shouldBe a[RequestTimeoutException] } } "normal http response" should "work" in { //Thread.sleep(5000) val setup = Http.HostConnectorSetup("localhost", 9101, false) connect(setup).onComplete { case Success(conn) => { conn ! HttpRequest(HttpMethods.GET, "/hello") } } expectMsgPF() { case HttpResponse(status, entity, _, _) => status should be(StatusCodes.OK) entity should be(HttpEntity("Helloworld")) } } def connect(setup: HostConnectorSetup)(implicit system: ActorSystem) = { // for the actor 'asks' import system.dispatcher implicit val timeout: Timeout = Timeout(1 second) (IO(Http) ? setup) map { case Http.HostConnectorInfo(connector, _) => connector } } class MockServer extends Actor { //implicit val timeout: Timeout = 1.second implicit val system = context.system // Register connection service IO(Http) ! Http.Bind(self, interface = "localhost", port = 9101) def receive: Actor.Receive = { case _: Http.Connected => sender ! Http.Register(self) case HttpRequest(GET, Uri.Path("/timeout"), _, _, _) => { Thread.sleep(3000) sender ! HttpResponse(entity = HttpEntity("ok")) } case HttpRequest(GET, Uri.Path("/hello"), _, _, _) => { sender ! HttpResponse(entity = HttpEntity("Helloworld")) } } } }
and My config for the test:
spray { can { client { response-chunk-aggregation-limit = 0 connecting-timeout = 1s request-timeout = 1s } host-connector { max-retries = 0 } } }
I found that in both cases the "conn" object is the same. Thus, I assume that when a RequestTimeoutException occurs, the spray returned the connection to the pool (default 4?), And in the following case it will use the same contact, but this connection is maintained at this time, so the server will treat it as the requested request .
If I sleep in the second case, it just goes away. Therefore, I assume that I should close the connection when I receive a RequestTimeoutException and make sure that in the second case a new new connection is used, right?
How do i do Any configurations?
thanks
Leon