Last active
June 23, 2017 18:17
-
-
Save gerardtoconnor/a0cfdfa95e0e4fe0bd3902363b56d8da to your computer and use it in GitHub Desktop.
Test format of alternative continuation HttpHandler format to prevent need to warp sync results in async
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Unlike Suave bind format, the idea is that the handlers execute as pre-applied continuations, with the added benefit of | |
// allowing sync operations to be executed in a handler with no addional and wasteful async/task wrappers as the async/task | |
// of the subsequent succ/fail Continuation that is called can be returned, passed directly through, unlike bind | |
open System | |
open System.Text | |
open System.Threading.Tasks | |
open System.Collections.Generic | |
open Microsoft.AspNetCore.Http | |
/// a partially applied function such that it only needs HttpContext input to trigger | |
type Continuation = HttpContext -> Task<HttpContext> | |
// Signature of any HttpHandler Function, a function of three inputs, a partially applied success Fn, a partially applied fail Fn, | |
// and lastly, the HttpContext that is applied at runtime to execute | |
type HttpHandler = Continuation -> Continuation -> HttpContext -> Task<HttpContext> | |
/// Combines two HttpHandler functions into one.... | |
/// the handler function inputs, success & fail continuation functions, are passed over the 'a' prefix function, and partially applied | |
/// to the suffix (latter) handler 'b', creating a Continuation function that is then partially applied as the success function of the | |
/// prefix 'a' handler, such that partially applied 'b' is run if succ fn in 'a' is called, and the original (ultimate & final) | |
/// succ fn will be passed down the pipeline to the last handler, having been initially sent in at front of function pipeline. | |
let compose (a : HttpHandler) (b : HttpHandler) = | |
fun (succ : Continuation) (fail : Continuation) (ctx:HttpContext) -> | |
let childCont = b succ fail | |
let parentCont = a childCont fail | |
parentCont ctx | |
let (>=>) = compose | |
/// --------------------------- | |
/// Default HttpHandlers | |
/// --------------------------- | |
/// Iterates through a list of HttpHandler functions, providing a fail function that points | |
/// to the next item in the list and if nothing successfull, calling fail function it recieved. | |
let rec choose (handlers : HttpHandler list) = | |
fun (succ: Continuation) (fail : Continuation) (ctx : HttpContext) -> | |
match handlers with | |
| [] -> fail ctx | |
| handler :: tail -> | |
let next = choose tail succ fail //if a branch fails, go to next handler in list | |
handler succ next ctx | |
// A sync handler that does not create any additinaly tasks but returns task of continuation executions | |
let route (path : string) : HttpHandler = | |
fun succ fail ctx -> // <<< clean simple format | |
if (getPath ctx).Equals path | |
then succ ctx | |
else fail ctx | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment