Context in Pascal

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

Our first example demonstrates the usage of Context for controlling cancellation in an HTTP server. A Context carries deadlines, cancellation signals, and other request-scoped values across API boundaries and procedures.

program ContextExample;

uses
  SysUtils, Classes, IdHTTPServer, IdContext, IdCustomHTTPServer, DateUtils;

type
  TMyHTTPServer = class(TIdHTTPServer)
  private
    procedure HelloHandler(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  end;

var
  Server: TMyHTTPServer;

procedure TMyHTTPServer.HelloHandler(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  StartTime: TDateTime;
  ElapsedTime: TDateTime;
begin
  WriteLn('server: hello handler started');
  try
    StartTime := Now;
    
    // Simulate some work
    while SecondsBetween(Now, StartTime) < 10 do
    begin
      if AContext.Connection.IOHandler.CheckForDataOnSource(100) then
      begin
        // Connection closed by client
        WriteLn('server: context canceled');
        AResponseInfo.ResponseNo := 500;
        AResponseInfo.ContentText := 'Internal Server Error: Context canceled';
        Exit;
      end;
    end;

    AResponseInfo.ContentText := 'hello';
    AResponseInfo.ContentType := 'text/plain';
  finally
    WriteLn('server: hello handler ended');
  end;
end;

begin
  Server := TMyHTTPServer.Create(nil);
  try
    Server.DefaultPort := 8090;
    Server.OnCommandGet := Server.HelloHandler;
    
    WriteLn('Server starting on port 8090...');
    Server.Active := True;
    
    ReadLn;
  finally
    Server.Free;
  end;
end.

In this Pascal example, we’re using the Indy components to create an HTTP server. The TMyHTTPServer class is defined with a HelloHandler method that simulates the behavior of the original Go example.

The handler starts by printing a message and then enters a loop that simulates work for up to 10 seconds. During this time, it periodically checks if the client has closed the connection, which is our way of simulating context cancellation.

If the client closes the connection (simulating context cancellation), we respond with a 500 Internal Server Error. Otherwise, after 10 seconds, we respond with “hello”.

To run the server:

$ fpc ContextExample.pas
$ ./ContextExample
Server starting on port 8090...

To test the server, you can use a tool like curl in another terminal:

$ curl localhost:8090/hello

If you interrupt the curl command before 10 seconds have passed, you should see the “context canceled” message in the server output.

Note that Pascal doesn’t have a direct equivalent to Go’s context.Context. In this example, we’ve simulated some of its behavior by checking for client disconnection, which is a common way to handle cancellation in network programming.