Skip to content

Commit 6b511e9

Browse files
authored
Merge pull request #8 from jameson2011/dev
Dev
2 parents 20d932a + e794da4 commit 6b511e9

File tree

5 files changed

+68
-45
lines changed

5 files changed

+68
-45
lines changed

src/zKbProxy/Configuration.fs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
[<Literal>]
77
let KillSourceUri = "https://redisq.zkillboard.com/listen.php?ttw=10"
88
[<Literal>]
9+
let ZkbApiBaseUri = "https://zkillboard.com/api/"
10+
[<Literal>]
911
let MongoServer = "127.0.0.1"
1012
[<Literal>]
1113
let DbName = "zkbproxy"
@@ -27,31 +29,33 @@
2729

2830
type Configuration=
2931
{
30-
KillSourceUri: string;
31-
NoCache: bool;
32-
MongoServer: string;
33-
DbName: string;
34-
KillsDbCollection: string;
35-
SessionsDbCollection: string;
36-
MongoUserName: string;
37-
MongoPassword: string;
38-
WebServerPort: uint16;
39-
BufferSize: int32;
40-
SessionTimeout: TimeSpan;
32+
KillSourceUri: string;
33+
ZkbApiBaseUri: string;
34+
NoCache: bool;
35+
MongoServer: string;
36+
DbName: string;
37+
KillsDbCollection: string;
38+
SessionsDbCollection: string;
39+
MongoUserName: string;
40+
MongoPassword: string;
41+
WebServerPort: uint16;
42+
BufferSize: int32;
43+
SessionTimeout: TimeSpan;
4144
}
4245
with
4346
static member empty =
4447
{
45-
KillSourceUri = ConfigurationDefaults.KillSourceUri;
46-
NoCache = false;
47-
MongoServer = ConfigurationDefaults.MongoServer;
48-
DbName = ConfigurationDefaults.DbName;
49-
KillsDbCollection = ConfigurationDefaults.KillsColName;
50-
SessionsDbCollection = ConfigurationDefaults.SessionsColName;
51-
MongoUserName = ConfigurationDefaults.UserName;
52-
MongoPassword = ConfigurationDefaults.UserPassword;
53-
WebServerPort = ConfigurationDefaults.WebServerPort;
54-
BufferSize = ConfigurationDefaults.BufferSize;
55-
SessionTimeout = ConfigurationDefaults.SessionTimeout
48+
KillSourceUri = ConfigurationDefaults.KillSourceUri;
49+
ZkbApiBaseUri = ConfigurationDefaults.ZkbApiBaseUri;
50+
NoCache = false;
51+
MongoServer = ConfigurationDefaults.MongoServer;
52+
DbName = ConfigurationDefaults.DbName;
53+
KillsDbCollection = ConfigurationDefaults.KillsColName;
54+
SessionsDbCollection = ConfigurationDefaults.SessionsColName;
55+
MongoUserName = ConfigurationDefaults.UserName;
56+
MongoPassword = ConfigurationDefaults.UserPassword;
57+
WebServerPort = ConfigurationDefaults.WebServerPort;
58+
BufferSize = ConfigurationDefaults.BufferSize;
59+
SessionTimeout = ConfigurationDefaults.SessionTimeout
5660
}
5761

src/zKbProxy/Program.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module Program=
2222
let defaultConfig = Configuration.empty
2323

2424
{ Configuration.KillSourceUri = j.["killSourceUri"] |> toString |> Option.defaultValue defaultConfig.KillSourceUri;
25+
ZkbApiBaseUri = j.["zkbApiBaseUri"] |> toString |> Option.defaultValue defaultConfig.ZkbApiBaseUri;
2526
NoCache = j.["noCache"] |> toBool |> Option.defaultValue defaultConfig.NoCache;
2627
MongoServer = j.["mongoServer"] |> toString |> Option.defaultValue defaultConfig.MongoServer;
2728
DbName = j.["dbName"] |> toString |> Option.defaultValue defaultConfig.DbName;

src/zKbProxy/ServiceFactory.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
sprintf "Kills collection: %s" config.KillsDbCollection;
1212
sprintf "Sessions collection: %s" config.SessionsDbCollection;
1313
sprintf "Kill source: %s" config.KillSourceUri;
14+
sprintf "Zkb Api base: %s" config.ZkbApiBaseUri;
1415
sprintf "No Caching: %b" config.NoCache;
1516
sprintf "buffer size: %i" config.BufferSize;
1617
sprintf "Session timeout: %f" config.SessionTimeout.TotalMinutes;
@@ -26,7 +27,7 @@
2627
do reportConfig postLog config |> ignore
2728

2829
let importActor = KillImportActor(postLog, config) :> IActor
29-
let zkbApiPassthrough = ZkbApiPassthroughActor(postLog)
30+
let zkbApiPassthrough = ZkbApiPassthroughActor(config, postLog)
3031

3132
let statsActor = StatisticsActor(postLog)
3233
let postStats = (statsActor :> IActor).Post

src/zKbProxy/WebServices.fs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ module WebServices=
191191

192192
return! match resp.Status with
193193
| HttpStatus.OK -> Successful.OK resp.Message ctx
194-
| HttpStatus.Unauthorized -> RequestErrors.UNAUTHORIZED "" ctx
195-
| HttpStatus.Forbidden -> RequestErrors.FORBIDDEN "" ctx
196-
| HttpStatus.NotFound -> RequestErrors.NOT_FOUND "" ctx
197-
| HttpStatus.TooManyRequests -> RequestErrors.TOO_MANY_REQUESTS "" ctx
198-
| HttpStatus.Error -> RequestErrors.BAD_REQUEST "" ctx
194+
| HttpStatus.Unauthorized -> RequestErrors.UNAUTHORIZED resp.Message ctx
195+
| HttpStatus.Forbidden -> RequestErrors.FORBIDDEN resp.Message ctx
196+
| HttpStatus.NotFound -> RequestErrors.NOT_FOUND resp.Message ctx
197+
| HttpStatus.TooManyRequests -> RequestErrors.TOO_MANY_REQUESTS resp.Message ctx
198+
| HttpStatus.Error -> ServerErrors.INTERNAL_ERROR resp.Message ctx
199199

200200
}

src/zKbProxy/ZkbApiPassthroughActor.fs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ type private ZkbApiPassthroughActorState = {
99
with
1010
static member empty = { ZkbApiPassthroughActorState.lastZkbRequest = DateTime.MinValue }
1111

12-
type ZkbApiPassthroughActor(log: PostMessage)=
12+
type ZkbApiPassthroughActor(config: Configuration, log: PostMessage)=
1313
let logSource = typeof<ZkbApiPassthroughActor>.Name
1414
let logException (ex: Exception) = (logSource,ex.Message) |> ActorMessage.Error |> log
1515
let logInfo (msg: string) = (logSource, msg) |> ActorMessage.Info |> log
16-
16+
1717
let logGetRequest (path: string) = sprintf "Sending GET %s" path |> logInfo
1818
let logGetResp (resp: HttpResponseMessage) = sprintf "Received %A from %A" resp.StatusCode resp.RequestMessage.RequestUri |> logInfo
1919

2020
let httpClient = Web.httpClient()
21-
22-
[<Literal>]
23-
let zkbDomain = "https://zkillboard.com/api"
21+
let zkbBaseUri = if config.ZkbApiBaseUri.EndsWith("/") then config.ZkbApiBaseUri
22+
else config.ZkbApiBaseUri + "/"
2423

2524
let getResponseString(resp: HttpResponseMessage)= resp.Content.ReadAsStringAsync() |> Async.AwaitTask |> Async.RunSynchronously
2625

@@ -39,27 +38,45 @@ type ZkbApiPassthroughActor(log: PostMessage)=
3938
| System.Net.HttpStatusCode.NotFound -> { WebResponse.Status = HttpStatus.NotFound; Retry = None; Message = "" }
4039
| System.Net.HttpStatusCode.TooManyRequests -> { WebResponse.Status = HttpStatus.TooManyRequests; Retry = None; Message = "" }
4140
| System.Net.HttpStatusCode.Forbidden -> { WebResponse.Status = HttpStatus.Forbidden; Retry = None; Message = "" }
42-
| _ -> { WebResponse.Status = HttpStatus.Error; Retry = None; Message = "" }
41+
| _ -> { WebResponse.Status = HttpStatus.Error; Retry = None; Message = "Unknown error." }
4342

4443
return result
4544
with
4645
| ex -> logException ex
47-
return { WebResponse.Status = HttpStatus.Error; Retry = None; Message = "" }
46+
return { WebResponse.Status = HttpStatus.Error; Retry = None; Message = ex.Message }
4847
}
4948

5049
let getZkbApi (path: string) (lastZkbRequest: DateTime) =
51-
async {
52-
let diff = DateTime.UtcNow - lastZkbRequest
53-
if diff < TimeSpan.FromSeconds(1.) then
54-
diff |> sprintf "Last Zkb API request in %A: pausing." |> logInfo
55-
do! Async.Sleep(1000)
56-
57-
let domain = if path.StartsWith("/") then zkbDomain
58-
else zkbDomain + "/"
59-
60-
return! sprintf "%s%s" domain path |> getAsync
50+
let maxIterations = 10
51+
52+
let rec get (url: string) (lastZkbRequest: DateTime) iterations =
53+
async {
54+
let diff = DateTime.UtcNow - lastZkbRequest
55+
if diff < TimeSpan.FromSeconds(1.) then
56+
diff |> sprintf "Last Zkb API request in %A: pausing." |> logInfo
57+
do! Async.Sleep(1000)
58+
59+
let! resp = getAsync url
60+
61+
return!
62+
match resp.Status with
63+
| HttpStatus.TooManyRequests when iterations <= 0 ->
64+
async { return { WebResponse.Status = HttpStatus.Error; Retry = None;
65+
Message = maxIterations |> sprintf "Retried after %i iterations, quitting." } }
66+
| HttpStatus.TooManyRequests ->
67+
iterations |> sprintf "Retrying, %i iteration(s) left." |> logInfo
68+
get url DateTime.UtcNow (iterations - 1)
69+
| _ -> async { return resp }
70+
6171
}
6272

73+
let path = if path.StartsWith("/") then path.Substring(1)
74+
else path
75+
let uri = sprintf "%s%s" zkbBaseUri path
76+
77+
get uri lastZkbRequest maxIterations
78+
79+
6380
let pipe = MessageInbox.Start(fun inbox ->
6481
let rec loop(state: ZkbApiPassthroughActorState) = async{
6582
let! msg = inbox.Receive()

0 commit comments

Comments
 (0)