Browse Source

🐦[FSharp] Falco - Update benchmark for Falco to v2.0.0 (#5867)

* falco v1.2.3

* Server header, removed meta tag from head

* inline json message to meet spec

* [FSharp] - Falco upgraded to v2.0.0

* static mapper for datareader

* json closure for recomputation

* fortune feature reorg

Co-authored-by: pimbrouwers <[email protected]>
pim 5 years ago
parent
commit
c1573cbbbb

+ 1 - 1
frameworks/FSharp/falco/src/App/App.fsproj

@@ -15,7 +15,7 @@
   <ItemGroup>
     <PackageReference Update="FSharp.Core" Version="4.7.*" />
     <PackageReference Include="Donald" Version="3.0.*" />
-    <PackageReference Include="Falco" Version="1.2.*" />
+    <PackageReference Include="Falco" Version="2.0.*" />    
     <PackageReference Include="Npgsql" Version="4.1.3.1" />
   </ItemGroup>
 

+ 57 - 71
frameworks/FSharp/falco/src/App/Fortune.fs

@@ -1,57 +1,51 @@
 module App.Fortune    
-    
-module Model = 
-    open System.Threading.Tasks 
-    open FSharp.Control.Tasks
-
-    type FortuneModel = 
-        {
-            id      : int
-            message : string
-        }
 
-    module FortuneModel =
-        open System.Data
-        open Donald 
-
-        let extra = 
+open System.Data
+open Donald
+open Falco
+open FSharp.Control.Tasks
+ 
+type FortuneModel = 
+   {
+       id      : int
+       message : string
+   }
+
+   static member fromDataReader (rd : IDataReader) =
+       {
+           id = rd.GetInt32("id")
+           message = rd.GetString("message")
+       }
+
+module Service = 
+    open System.Threading.Tasks     
+        
+    module ListQuery =              
+        type LoadFortunes = unit -> Task<FortuneModel list>
+
+        let extraFortune = 
             {
                 id = 0
                 message = "Additional fortune added at request time."
             }
 
-        let fromDataReader (rd : IDataReader) =
-            {
-                id = rd.GetInt32("id")
-                message = rd.GetString("message")
-            }
-
-    module Index =        
-        type Query =
-            unit -> Task<FortuneModel list>
-
-        type LoadFortunes =
-            unit -> Task<FortuneModel list>
-
-        let query 
-            (loadFortunes : LoadFortunes) : Query =
+        let handle
+            (loadFortunes : LoadFortunes) =
             fun () -> 
                 task {
                     let! fortunes = loadFortunes ()
-                    let fortunesWithExtra = FortuneModel.extra :: fortunes
-                    let fortunesSorted = 
-                        fortunesWithExtra 
+                    
+                    return 
+                        extraFortune 
+                        :: fortunes
                         |> List.sortBy (fun f -> f.message)
-
-                    return fortunesSorted 
                 }
 
-module Db =
-    open System.Data
-    open Donald
-    open Model
 
-    let selectAsync (connection : IDbConnection) =
+module Db =    
+    open System.Threading.Tasks    
+    
+    let selectAsync (connection : IDbConnection) : Task<FortuneModel list> =        
         queryAsync 
             "SELECT id, message FROM fortune"
             []
@@ -59,42 +53,34 @@ module Db =
             connection
 
 module View =
-    open Falco.ViewEngine
-    open Model 
-
+    open Falco.Markup
+    
     let index (fortunes : FortuneModel list) =            
         UI.layout "Fortunes" [
-                table [] [
-                        yield tr [] [
-                                th [] [ raw "id" ]
-                                th [] [ raw "message" ]
+                Elem.table [] [
+                        yield Elem.tr [] [
+                                Elem.th [] [ Text.raw "id" ]
+                                Elem.th [] [ Text.raw "message" ]
                             ]
                         for fortune in fortunes ->
-                            tr [] [
-                                    td [] [ raw (string fortune.id) ]
-                                    td [] [ enc fortune.message]
+                            Elem.tr [] [
+                                    Elem.td [] [ Text.raw (string fortune.id) ]
+                                    Elem.td [] [ Text.enc fortune.message]
                                 ]
                     ]
             ]
 
-module Controller =
-    open Donald
-    open Falco
-    open FSharp.Control.Tasks
-    open Model
-
-    let handleIndex : HttpHandler =        
-        fun next ctx ->
-            task {
-                let connFactory = ctx.GetService<DbConnectionFactory>()
-                use conn = createConn connFactory
-                let selectFortunes = fun () -> Db.selectAsync conn
-                let! fortunes = () |> Index.query selectFortunes
-
-                let handlerResult = 
-                    fortunes
-                    |> View.index
-                    |> htmlOut
-
-                return! handlerResult next ctx
-            }
+let handleIndex : HttpHandler =        
+    fun ctx ->
+        task {
+            let connFactory = ctx.GetService<DbConnectionFactory>()
+            use conn = createConn connFactory
+            let selectFortunes = fun () -> Db.selectAsync conn
+            let! fortunes = () |> Service.ListQuery.handle selectFortunes
+
+            return!
+                ctx
+                |> (fortunes 
+                    |> View.index 
+                    |> Response.ofHtml)                    
+        }

+ 9 - 1
frameworks/FSharp/falco/src/App/Program.fs

@@ -1,6 +1,7 @@
 module App.Program
 
 open System.Data
+open Falco
 open Npgsql
 
 [<Literal>]
@@ -11,5 +12,12 @@ let connectionFactory =
 
 [<EntryPoint>]
 let main args =    
-    Server.startServer args connectionFactory
+    Host.startWebHost 
+        args        
+        (Server.buildServer connectionFactory)
+        [
+            get "/plaintext"  Value.handlePlainText
+            get "/json"       Value.handleJson
+            get "/fortunes"   Fortune.handleIndex
+        ]    
     0

+ 18 - 30
frameworks/FSharp/falco/src/App/Server.fs

@@ -1,22 +1,14 @@
 module App.Server
 
+open System.Threading.Tasks
 open Donald
 open Falco
 open Microsoft.AspNetCore.Builder
 open Microsoft.AspNetCore.Hosting
-open Microsoft.AspNetCore.Server.Kestrel.Core
 open Microsoft.Extensions.DependencyInjection
 open Microsoft.Extensions.Logging
-open Microsoft.Extensions.Hosting
 
-let routes = 
-    [
-        get "/plaintext"  Value.Controller.handlePlainText
-        get "/json"       Value.Controller.handleJson
-        get "/fortunes"   Fortune.Controller.handleIndex
-    ]
-    
-module Config =
+let buildServer (connectionFactory : DbConnectionFactory) : Host.ConfigureWebHost =
     let configureLogging (log : ILoggingBuilder) =
         log.ClearProviders()
         |> ignore
@@ -30,26 +22,22 @@ module Config =
 
     let configure 
         (routes : HttpEndpoint list) 
-        (app : IApplicationBuilder) = 
+        (app : IApplicationBuilder) =      
+        let handleNotFound : HttpHandler =
+            fun ctx ->
+                Response.withStatusCode 404 ctx |> ignore
+                Task.CompletedTask
+            
         app.UseRouting()
-            .UseHttpEndPoints(routes)       
-            .UseNotFoundHandler(setStatusCode 404)
+           .UseHttpEndPoints(routes)       
+           .UseNotFoundHandler(handleNotFound)
             |> ignore 
 
-let builderServer 
-    (connectionFactory : DbConnectionFactory) 
-    (webHost : IWebHostBuilder) =
-    webHost
-        .UseKestrel()
-        .ConfigureLogging(Config.configureLogging)
-        .ConfigureServices(Config.configureServices connectionFactory)
-        .Configure(Config.configure routes)                   
-        |> ignore
-
-let startServer 
-    (args : string[])    
-    (connectionFactory : DbConnectionFactory) =
-    Host.CreateDefaultBuilder(args)
-        .ConfigureWebHost(fun webHost -> builderServer connectionFactory webHost)
-        .Build()
-        .Run()  
+    fun (routes : HttpEndpoint list)
+        (webHost : IWebHostBuilder) ->
+        webHost
+            .UseKestrel()
+            .ConfigureLogging(configureLogging)
+            .ConfigureServices(configureServices connectionFactory)
+            .Configure(configure routes)                   
+            |> ignore

+ 5 - 5
frameworks/FSharp/falco/src/App/UI.fs

@@ -1,11 +1,11 @@
 module App.UI
 
-open Falco.ViewEngine
+open Falco.Markup
     
 let layout pageTitle content = 
-    html [] [
-        head [] [                
-                title [] [ raw pageTitle ]                                                                
+    Elem.html [] [
+        Elem.head [] [                
+                Elem.title [] [ Text.raw pageTitle ]                                                                
             ]
-        body [] content
+        Elem.body [] content
     ] 

+ 8 - 9
frameworks/FSharp/falco/src/App/Value.fs

@@ -3,14 +3,13 @@
 open Falco 
 
 type JsonOutputModel = { message : string }
-    
-module Controller =
-    let defaultMsg = "Hello, World!"
 
-    let handleJson : HttpHandler =
-        fun next ctx ->
-            let json = { message = defaultMsg }
-            (jsonOut json) next ctx
+let defaultMsg = "Hello, World!"
+
+let handleJson : HttpHandler =
+    fun ctx ->
+        let output = { message = defaultMsg }        
+        Response.ofJson output ctx
         
-    let handlePlainText : HttpHandler =        
-        textOut defaultMsg
+let handlePlainText : HttpHandler =        
+    Response.ofPlainText defaultMsg