Context in Fortran

Here’s the translation of the Go code to Fortran, with explanations in Markdown format suitable for Hugo:

Our previous example demonstrated setting up a simple HTTP server. HTTP servers are useful for showcasing the usage of context for controlling cancellation. In Fortran, we don’t have a direct equivalent to Go’s context.Context, but we can simulate similar behavior using Fortran’s coarray features and synchronization primitives.

program context_example
  use, intrinsic :: iso_fortran_env
  implicit none

  integer :: unit
  character(len=100) :: request
  logical :: done

  ! Simulate an HTTP server
  open(newunit=unit, file='server.log', status='replace', action='write')
  write(unit,*) 'server: started'

  ! Main server loop
  do
    ! Simulate receiving a request
    call receive_request(request)
    
    if (request == 'exit') then
      exit
    end if

    ! Process the request
    call process_request(request, done)

    if (done) then
      write(unit,*) 'server: request processed'
    else
      write(unit,*) 'server: request cancelled'
    end if
  end do

  write(unit,*) 'server: shutdown'
  close(unit)

contains

  subroutine receive_request(req)
    character(len=*), intent(out) :: req
    read(*,*) req
  end subroutine receive_request

  subroutine process_request(req, finished)
    use, intrinsic :: iso_fortran_env
    character(len=*), intent(in) :: req
    logical, intent(out) :: finished
    integer :: i
    
    write(unit,*) 'server: processing request started'
    
    ! Simulate work being done
    do i = 1, 10
      call sleep(1)
      if (this_image() == 1) then
        ! Check for cancellation signal
        if (cancelled()) then
          finished = .false.
          write(unit,*) 'server: request cancelled'
          return
        end if
      end if
    end do
    
    finished = .true.
    write(unit,*) 'server: processing request completed'
  end subroutine process_request

  logical function cancelled()
    ! In a real application, this would check for a cancellation signal
    ! For this example, we'll randomly decide to cancel
    call random_number(cancelled)
    cancelled = cancelled < 0.3
  end function cancelled

end program context_example

To run the program:

$ gfortran -coarray=single context_example.f90 -o context_example
$ ./context_example
hello
server: processing request started
server: processing request completed
exit
server: shutdown

This Fortran program simulates the behavior of an HTTP server with context-like cancellation. Here’s a breakdown of the key components:

  1. We use a file (server.log) to simulate server output, similar to how the Go example prints to the console.

  2. The main loop simulates receiving and processing requests. Each request is processed in the process_request subroutine.

  3. The process_request subroutine simulates work being done over a period of time (10 seconds). During this time, it periodically checks if the request should be cancelled.

  4. The cancelled function simulates the behavior of checking a context’s Done() channel. In this example, it randomly decides to cancel about 30% of the time.

  5. If a cancellation is detected, the processing stops early and reports that the request was cancelled.

While Fortran doesn’t have built-in HTTP server capabilities or a direct equivalent to Go’s context, this example demonstrates how you can implement similar patterns for handling long-running operations with the possibility of cancellation.

Note that this is a simplified example. In a real-world application, you would need to implement proper networking code for HTTP communication and a more robust mechanism for signaling cancellation across different parts of your program.