Last active
July 13, 2017 07:36
-
-
Save gerardtoconnor/94228aaa67a247f6e18772a6f8b7be0f to your computer and use it in GitHub Desktop.
Next Continuation Handler
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
type HttpHandlerResult = Task<HttpContext option> // same as previous | |
type HttpCont = HttpContext -> HttpHandlerResult // continuation same as previous HttpHandler | |
type HttpHandler = HttpCont -> HttpContext -> HttpHandlerResult // (HttpCont -> HttpCont) : Handler now has two input parameters | |
let compose (handler : HttpHandler) (handler2 : HttpHandler) : HttpHandler = | |
fun (next:HttpCont) (ctx : HttpContext) -> | |
// 1. last next will ultimately be a (fun ctx -> Some ctx) but allows to compose / short circuit with continuations | |
// 2. We can apply next function at load so all handlers have thier next function refs and need only apply ctx on run | |
let child = handler2 next // suffix child handler(s) take next (Some ctx) success function | |
let next = handler child // prefix parent handler takes child handler as next continuation function | |
match ctx.Response.HasStarted with | |
| true -> task { return Some ctx } | |
| false -> next ctx | |
let rec choose (handlers : HttpHandler list) : HttpHandler = | |
fun next ctx -> | |
task { | |
match handlers with | |
| [] -> return None | |
| handler :: tail -> | |
let! result = handler next ctx | |
match result with | |
| Some c -> return Some c | |
| None -> return! choose tail next ctx | |
} | |
let httpVerb (verb : string) : HttpHandler = | |
fun next ctx -> | |
if ctx.Request.Method.Equals verb | |
then next ctx // no longer wrapping async ('Some' replaced with 'task') | |
else task { return None } | |
let route (path : string) : HttpHandler = | |
fun next ctx -> | |
if (getPath ctx).Equals path | |
then next ctx // no longer wrapping async ('Some' replaced with 'task') | |
else Task.FromResult None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment