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.










