-
Notifications
You must be signed in to change notification settings - Fork 4
/
Program.fs
104 lines (90 loc) · 3.6 KB
/
Program.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
open System
open System.Threading.Tasks
open FSharp.Control.Tasks.V2.ContextInsensitive
open Giraffe
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Hosting
open Microsoft.Extensions.DependencyInjection
open Orleans
open Orleans.Runtime
open Orleans.Hosting
open Orleans.Statistics
type ProgressStateDtoV1 = { Position: int }
type ProgressVersionedState =
| V1 of ProgressStateDtoV1
type ProgressStateDto (state: ProgressVersionedState) =
member val Dto = state with get, set
new () = ProgressStateDto({ Position = 0 } |> V1 )
type IProgress =
inherit IGrainWithStringKey
abstract member SetProgress : int -> Task
abstract member GetProgress : unit -> Task<int>
type Progress([<PersistentState("position","default")>] storedPosition:IPersistentState<ProgressStateDto>) =
inherit Grain()
interface IProgress with
member _.SetProgress currentProgress =
storedPosition.State <- {Position = currentProgress } |> V1 |> ProgressStateDto
storedPosition.WriteStateAsync()
member _.GetProgress () =
let position =
match storedPosition.State.Dto with
| V1 v1 -> v1.Position
Task.FromResult(position)
let SetProgress (userId: string, episode: string, position:int) =
fun (next: HttpFunc) (ctx: HttpContext) ->
task {
let grainFactory = ctx.GetService<IGrainFactory>()
let userProgressGrain =
grainFactory.GetGrain<IProgress> <| sprintf "%s%s" userId episode
do! userProgressGrain.SetProgress(position)
return! next ctx
}
let GetProgress (userId: string, episode: string) =
fun (next: HttpFunc) (ctx: HttpContext) ->
task {
let grainFactory = ctx.GetService<IGrainFactory>()
let userProgressGrain =
grainFactory.GetGrain<IProgress> <| sprintf "%s%s" userId episode
let! position = userProgressGrain.GetProgress()
return! json position next ctx
}
let webApp =
choose [
route "/ping" >=> text "pong"
routef "/progress/%s/%s/%i" SetProgress
routef "/progress/%s/%s" GetProgress
]
let configureOrleans (siloBuilder:ISiloBuilder) =
siloBuilder
.UseLocalhostClustering()
.UseDashboard()
.UsePerfCounterEnvironmentStatistics()
.ConfigureApplicationParts(fun parts ->
parts.AddApplicationPart(typeof<IProgress>.Assembly)
.WithCodeGeneration() |> ignore
)
.AddAzureTableGrainStorage("default", fun (options:Configuration.AzureTableStorageOptions) ->
options.TableName <- "fnconf06"
options.ConnectionString <- "DefaultEndpointsProtocol=https;AccountName=fnconf;AccountKey=0FUp3050MjFdZT+DzDqxHnXs3lwywvEPQce0WjOtOq4dL7NJsltsObghubkpmh+iaUUKaIOeAoWT8WcrnyTh3w==;EndpointSuffix=core.windows.net"
)
|> ignore
let createHost argv =
Host.CreateDefaultBuilder(argv)
.ConfigureWebHostDefaults(fun webBuilder ->
webBuilder
.UseKestrel()
.Configure(fun (app:IApplicationBuilder) ->
app.UseGiraffe webApp)
.ConfigureServices(fun services ->
services.AddGiraffe() |> ignore
) |> ignore
)
.UseOrleans(configureOrleans)
[<EntryPoint>]
let main argv =
createHost(argv)
.Build()
.Run()
0