Context in Crystal

Here’s the translation of the Go code to Crystal, formatted in Markdown suitable for Hugo:

Our first example demonstrates how to use HTTP::Server and HTTP::Handler to create a simple HTTP server. This server uses Channel for controlling cancellation, which is similar to the context.Context concept in other languages. A Channel can carry signals and values across different fibers (Crystal’s lightweight threads).

require "http/server"
require "log"

class HelloHandler
  include HTTP::Handler

  def call(context)
    Log.info { "server: hello handler started" }

    # Create a channel to simulate work and potential cancellation
    work_done = Channel(Nil).new

    spawn do
      sleep 10.seconds
      work_done.send(nil)
    end

    select
    when work_done.receive
      context.response.print "hello\n"
    when context.request.closed?
      Log.error { "server: request closed" }
      context.response.status = HTTP::Status::INTERNAL_SERVER_ERROR
      context.response.print "Internal Server Error"
    end

    Log.info { "server: hello handler ended" }
  end
end

def main
  server = HTTP::Server.new([HelloHandler.new])

  address = server.bind_tcp 8090
  Log.info { "Listening on http://#{address}" }
  server.listen
end

main

In this Crystal version:

  1. We define a HelloHandler class that implements the HTTP::Handler interface.

  2. Inside the call method, we use a Channel to simulate work and potential cancellation.

  3. We use select to wait for either the work to complete or the request to be closed (simulating cancellation).

  4. The spawn keyword is used to create a new fiber, similar to a goroutine in other languages.

  5. We use Crystal’s built-in logging facility instead of fmt.Println.

  6. In the main function, we set up the HTTP server with our custom handler and start listening on port 8090.

To run the server:

$ crystal run context.cr &

Simulate a client request to /hello, pressing Ctrl+C shortly after starting to signal cancellation:

$ curl localhost:8090/hello
server: hello handler started
^C
server: request closed
server: hello handler ended

This example demonstrates how Crystal can handle concurrent operations and manage cancellation in a web server context, similar to the original example but using Crystal’s idiomatic approaches and built-in HTTP server capabilities.