For a variety of reasons I recently wrote an “intentionally slow” HTTP socket server using Scala 3. Though I also wanted to test some things with Scala 3, the main reason for writing it is so I can test some client-side code, and make sure I handle server-side timeouts correctly.
The server-side code
The important part of the Scala 3 server-side code looks like this:
@main def SlowSocketServer = val serverResponseDelayTimeMs = 1_000 val serverPort = 5150 val server = ServerSocket(serverPort) while true do // “Listens for a connection to be made to this socket and accepts it” val socket = server.accept() // simulate a slow server response Thread.sleep(serverResponseDelayTimeMs) val in = BufferedReader(InputStreamReader(socket.getInputStream)) val out = PrintWriter(socket.getOutputStream) // this works, but i don’t know if it 100% meets the standard. // might need a `\r` at the end of every line. out.print(httpResponse(serverResponseDelayTimeMs)) out.flush() // read the input from the client. // LazyList used to be known as Stream. can also use Iterator. val s = LazyList.continually(in.readLine()) .takeWhile(_.length != 0) .mkString("\n") out.close in.close socket.close end SlowSocketServer
Test clients
I’ve tested this server-side code with a few different HTTP clients. Here are two examples of how to test it with curl
commands:
$ curl http://localhost:5150 Have a nice day! $ curl --head http://localhost:5150 HTTP/1.1 200 OK Date: Fri Dec 04 10:38:05 MST 2020 Server: SlowServer Content-Type: text/plain Delay-Time: 1000 ms Connection: Closed
Project source code
If you’re interested, you can find the complete project source code here:
Scala 3 scalac options
You’ll see that in that project I’m also experimenting with scalac
options, so I set the scalacOptions
field in my build.sbt file as shown here:
name := "ScalaSlowSocketServer" version := "0.1" scalaVersion := "3.0.0-M2" useScala3doc := true fork in run := true scalacOptions ++= Seq( "-deprecation", "-explain", "-explain-types", "-new-syntax", "-unchecked", "-Xfatal-warnings", "-Xmigration" )
As a final note, the fork
part is necessary because I have been running the code from inside the sbt shell, and with this setting I can type Ctrl-C. That stops my server, but doesn’t kill the sbt session.
Summary
In summary, if you ever need an intentionally-slow HTTP server, I hope this example is helpful.