Context in Karel

Here’s the translation of the Go code to Java, along with explanations in Markdown format suitable for Hugo:

In the previous example we looked at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of concurrency and request handling in Java. We’ll use Java’s built-in HttpServer class and ExecutorService for handling concurrent requests.

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class ContextExample {

    static class HelloHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            System.out.println("server: hello handler started");

            try {
                // Simulate some work
                TimeUnit.SECONDS.sleep(10);
                
                String response = "hello\n";
                exchange.sendResponseHeaders(200, response.length());
                OutputStream os = exchange.getResponseBody();
                os.write(response.getBytes());
                os.close();
            } catch (InterruptedException e) {
                System.out.println("server: " + e.getMessage());
                String error = "Internal Server Error";
                exchange.sendResponseHeaders(500, error.length());
                OutputStream os = exchange.getResponseBody();
                os.write(error.getBytes());
                os.close();
            } finally {
                System.out.println("server: hello handler ended");
            }
        }
    }

    public static void main(String[] args) throws IOException {
        HttpServer server = HttpServer.create(new InetSocketAddress(8090), 0);
        server.createContext("/hello", new HelloHandler());

        ExecutorService executor = Executors.newCachedThreadPool();
        server.setExecutor(executor);
        server.start();

        System.out.println("Server started on port 8090");
    }
}

In this Java example, we create an HttpServer that listens on port 8090. We register our HelloHandler on the “/hello” route.

The HelloHandler simulates some work by sleeping for 10 seconds before sending a response. In a real-world scenario, this could represent some computation or database operation.

Java doesn’t have a direct equivalent to Go’s context.Context, but we can achieve similar functionality using thread interruption. The ExecutorService manages the threads for handling requests, and if a client disconnects, the thread will be interrupted.

To run the server:

$ javac ContextExample.java
$ java ContextExample

The server will start and listen on port 8090.

To test the server, you can use curl in a separate terminal:

$ curl localhost:8090/hello

This will wait for 10 seconds before receiving the “hello” response.

If you interrupt the curl command (by pressing Ctrl+C) before the 10 seconds are up, the server will detect the client disconnection and the handler will end early.

This example demonstrates how to handle long-running operations in an HTTP server context, and how to manage the lifecycle of request handlers. While it doesn’t provide the same level of cancellation control as Go’s context.Context, it showcases a similar concept using Java’s concurrency primitives.