| Let’s say I want to do something simple but slightly beyond the scope of a traditional toy demonstration: * Read some environment variables and a local file * Start a monitoring thread that consumes from a channel or something similar, then every X s or X events writes to a local temp file and then sends a request batching some metrics to an external system * Configure and start an http server * Said server has a handler that 0. Starts a timer 1. loads, then increments an atomic “num requests served until now” variable 2. uses synchronization to lock on a list or ring buffer containing the last 5 requests’ user-agent headers 2.5 copies the current last 5 values, replaces oldest one with the one from the handles request, unlocks 3. generates a json response containing like “num_so_far: x, last5agent: [..], “some_env_var”:..” 3.5 stops the timer 4. write request user agent and time interval to monitoring thread’s channel 5. write response and end handling * server’s gotta be able to do concurrency > 1 with parallelism * On sigterm set the server to a state that rejects new requests, waits for existing requests to complete, then flushes the monitoring channel I’d consider this a trial run of some of the most basic patterns commonly used by networked software: init io, immutable shared state, atomic mutable shared state, synchronization locked shared state, http ingress and egress, serialization, concurrency, parallelizarion, background threads, os signals, nontrivial cleanup. In Go, Java, or C++ I could write this with my eyes closed. How easy is it in Haskell or Lisp? If you know of any demos or repos that do something like this - not a pure toy or barebones demo, but not a huge task all in all- in either I’d be interested in seeing what it looks like. |
https://www.servant.dev/ https://www.yesodweb.com/