Skip to content

Instantly share code, notes, and snippets.

@purkhusid
Created April 20, 2021 09:35
Show Gist options
  • Save purkhusid/0cf1095bb3189dbc38fc932e2d344be1 to your computer and use it in GitHub Desktop.
Save purkhusid/0cf1095bb3189dbc38fc932e2d344be1 to your computer and use it in GitHub Desktop.
F# gRPC Service
module Main
open Libraries.Grpc
open Libraries.Logging
open Libraries.Sentry
open Libraries.Tracing
open System
open Grpc.Core
open Grpc.HealthCheck
open Grpc.Health.V1
open Prometheus
open Src.Protobuf.Bootstrap.Service
open Service
open FsConfig
open System.Threading
type Config =
{ [<DefaultValue("fsharp-bootstrap-api")>]
ServiceName: string
Env: string
Port: int
[<DefaultValue("info")>]
LogLevel: string
SentryDsn: string
TracingAgentEndpoint: string option }
let getConfigFromEnvironment () =
match EnvConfig.Get<Config>() with
| Ok config -> config
| Error error ->
match error with
| NotFound envVarName -> failwithf "Environment variable %s not found" envVarName
| BadValue (envVarName, value) -> failwithf "Environment variable %s has invalid value %s" envVarName value
| NotSupported msg -> failwith msg
let getTracer config =
match config.TracingAgentEndpoint with
| Some endpoint -> createTracer config.ServiceName config.ServiceName [ ExporterType.Otlp { Endpoint = endpoint } ]
| None -> createTracer config.ServiceName config.ServiceName [ ExporterType.Console ]
[<EntryPoint>]
let main argv =
let config = getConfigFromEnvironment ()
let sentry =
initSentry config.SentryDsn config.Env config.ServiceName
let logger = configureLogger config.LogLevel
let (tracer, provider) = getTracer config
let metricServer = new MetricServer(9090)
let healthService = HealthServiceImpl()
let serviceImpl = BootstrapImpl(logger, tracer)
let server = Server()
let serviceDefinition =
addServerInterceptors (BootstrapService.BootstrapServiceMethodBinder.BindService(serviceImpl))
server.Services.Add(serviceDefinition)
server.Services.Add(Health.BindService(healthService))
server.Ports.Add(ServerPort("127.0.0.1", config.Port, ServerCredentials.Insecure))
|> ignore
AppDomain.CurrentDomain.ProcessExit.Add
(fun e ->
Console.WriteLine "Server shutting down..."
server.ShutdownAsync().Wait()
metricServer.Stop()
provider.Dispose()
sentry.Dispose())
metricServer.Start() |> ignore
server.Start()
healthService.SetStatus(config.ServiceName, HealthCheckResponse.Types.ServingStatus.Serving)
printf "Server listening on port %i\n" config.Port
Thread.Sleep(Timeout.Infinite)
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment