Context in Ada
Here’s the translated code and explanation in Ada, formatted for Hugo:
Our first example demonstrates how to set up a simple HTTP server in Ada. HTTP servers are useful for demonstrating the usage of task cancellation and timeouts. Ada tasks provide a way to handle concurrent operations and can be used to control cancellation and deadlines across different parts of your program.
with Ada.Text_IO;
with Ada.Calendar;
with GNAT.Sockets;
with Ada.Exceptions;
procedure HTTP_Server is
use Ada.Text_IO;
use Ada.Calendar;
use GNAT.Sockets;
task type Request_Handler is
entry Start(Socket : Socket_Type);
end Request_Handler;
task body Request_Handler is
Client_Socket : Socket_Type;
begin
accept Start(Socket : Socket_Type) do
Client_Socket := Socket;
end Start;
Put_Line("server: hello handler started");
declare
Response : constant String :=
"HTTP/1.1 200 OK" & ASCII.CR & ASCII.LF &
"Content-Type: text/plain" & ASCII.CR & ASCII.LF &
"Content-Length: 7" & ASCII.CR & ASCII.LF &
ASCII.CR & ASCII.LF &
"hello" & ASCII.CR & ASCII.LF;
Deadline : constant Time := Clock + Duration(10.0);
begin
select
delay until Deadline;
String'Write(Stream(Client_Socket), Response);
or
terminate;
end select;
exception
when E : others =>
Put_Line("server: " & Ada.Exceptions.Exception_Message(E));
end;
Close_Socket(Client_Socket);
Put_Line("server: hello handler ended");
end Request_Handler;
Server_Socket : Socket_Type;
Server_Address : Sock_Addr_Type;
Client_Address : Sock_Addr_Type;
begin
Initialize;
Create_Socket(Server_Socket);
Server_Address.Addr := Inet_Addr("127.0.0.1");
Server_Address.Port := 8090;
Bind_Socket(Server_Socket, Server_Address);
Listen_Socket(Server_Socket);
Put_Line("Server listening on port 8090");
loop
Accept_Socket(Server_Socket, Client_Address, Client_Socket);
declare
Handler : Request_Handler;
begin
Handler.Start(Client_Socket);
end;
end loop;
exception
when E : others =>
Put_Line("Error: " & Ada.Exceptions.Exception_Message(E));
end HTTP_Server;In this Ada example, we create a simple HTTP server that listens on port 8090. The Request_Handler task is responsible for handling each incoming request. It simulates some work by waiting for 10 seconds before sending a response.
The select statement in the Request_Handler task body is similar to the select statement in the original example. It either waits for the 10-second deadline or terminates if the task is asked to complete early.
To run the server:
$ gnatmake http_server.adb
$ ./http_server
Server listening on port 8090You can then simulate a client request using curl:
$ curl localhost:8090/hello
server: hello handler started
hello
server: hello handler endedIf you interrupt the curl command before the 10-second timeout, you’ll see the handler end early:
$ curl localhost:8090/hello
^C
server: hello handler endedThis example demonstrates how Ada tasks can be used to handle concurrent operations and implement timeouts, similar to the context functionality in the original example.
Comments powered by Disqus