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 8090

You can then simulate a client request using curl:

$ curl localhost:8090/hello
server: hello handler started
hello
server: hello handler ended

If 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 ended

This 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