In meinem unten genannten Test habe ich versucht, ein Timeout zu simulieren und dann eine normale Anfrage zu senden. jedoch habe ich spray.can.Http $ Connection: Vorzeitige Verbindung schließen (der Server nicht erscheint Anfrage unterstützt Pipelining)
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"))
}
}
}
}
und meine Config für den Test:
spray {
can {
client {
response-chunk-aggregation-limit = 0
connecting-timeout = 1s
request-timeout = 1s
}
host-connector {
max-retries = 0
}
}
}
Ich fand, dass In beiden Fällen ist das "conn" -Objekt dasselbe. Also ich denke, wenn RequestTimeoutException passiert, Spray setzen Sie die Conn in den Pool (standardmäßig 4?) Und der nächste Fall wird die gleiche Verbindung, aber zu diesem Zeitpunkt, diese Conn am Leben erhalten, so wird der Server es als Chunked behandeln anfordern.
Wenn ich etwas Schlaf im zweiten Fall, wird es gerade bestanden. Also ich denke, ich muss die Verbindung schließen, wenn RequestTimeoutException und sicherstellen, dass der zweite Fall eine neue neue Verbindung verwenden, nicht wahr?
Wie soll ich tun? Irgendwelche Konfigurationen?
Dank
Leon
ah, meine Schuld, vergiss das single thread Verhalten des Schauspielers :) Danke für den Hinweis darauf! – anuni
hey! ein sehr ähnliches Problem, aber ich blockiere nicht den Schauspieler .. frage mich, was es sein kann: https://stackoverflow.com/questions/29397293/how-to-fix-the-dropping-close-since- Der-ssl-Verbindung-ist-bereits-Closing-Fehler – mayacr86