Context in Elixir
Here’s the translation of the Go code to Elixir, with explanations in Markdown format suitable for Hugo:
In this example, we’ll look at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of processes for controlling cancellation. In Elixir, we use processes and message passing to handle concurrency and cancellation, which is similar to the concept of context.Context in other languages.
defmodule Context do
use Application
def start(_type, _args) do
children = [
{Plug.Cowboy, scheme: :http, plug: Context.Router, options: [port: 8090]}
]
opts = [strategy: :one_for_one, name: Context.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule Context.Router do
use Plug.Router
plug :match
plug :dispatch
get "/hello" do
IO.puts("server: hello handler started")
task = Task.async(fn ->
:timer.sleep(10000)
send(self(), :done)
end)
receive do
:done ->
send_resp(conn, 200, "hello\n")
{:EXIT, _pid, reason} ->
IO.puts("server: #{inspect(reason)}")
send_resp(conn, 500, "Internal Server Error")
after
11000 ->
Task.shutdown(task)
send_resp(conn, 500, "Request timed out")
end
IO.puts("server: hello handler ended")
end
match _ do
send_resp(conn, 404, "Not found")
end
endIn this Elixir code:
We define an
Applicationmodule that starts a Cowboy server with ourRoutermodule.In the
Routermodule, we define a/helloroute that simulates a long-running operation.We use
Task.asyncto start a process that sleeps for 10 seconds, simulating work.We use
receiveto wait for either the task to complete or an exit signal.If the task completes, we send a success response. If we receive an exit signal (simulating cancellation), we send an error response.
We also have a timeout of 11 seconds, after which we shut down the task and send a timeout response.
To run the server:
$ mix run --no-haltTo simulate a client request to /hello, hitting Ctrl+C shortly after starting to signal cancellation:
$ curl localhost:8090/hello
server: hello handler started
^C
server: :shutdown
server: hello handler endedThis example demonstrates how Elixir handles concurrent operations and cancellation using processes and message passing, which is conceptually similar to using contexts for cancellation in other languages.