From 2f1ae5cd7f108094359a8469cfc0579ddaf039b1 Mon Sep 17 00:00:00 2001 From: Smaug123 Date: Sat, 12 Nov 2022 21:58:31 +0000 Subject: [PATCH] Slightly more robust (but still not robust) UI --- RaftFable/src/App.fs | 32 +++++++++++++++++++------------- RaftFable/src/Ui.fs | 42 ++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/RaftFable/src/App.fs b/RaftFable/src/App.fs index 013d435..d3900f0 100644 --- a/RaftFable/src/App.fs +++ b/RaftFable/src/App.fs @@ -2,7 +2,6 @@ namespace RaftFable open System open System.Collections.Generic -open System.Security.Cryptography open Fable.Core.JS open Raft open Browser.Dom @@ -66,8 +65,8 @@ module App = try clients.Add (client, HashSet ()) with :? ArgumentException -> - failwith "got a response a second time - need to handle this in the UI" - | RegisterClientResponse.NotLeader hint -> failwith "asked a non-leader, have to handle it" + failwith "TODO: got a response a second time - need to handle this in the UI" + | RegisterClientResponse.NotLeader hint -> failwith "TODO: asked a non-leader, have to handle it" ) let handleClientResponse (response : ClientResponse) : unit = @@ -75,8 +74,8 @@ module App = clients (fun () -> match response with - | ClientResponse.SessionExpired -> failwith "session expired, have to handle it" - | ClientResponse.NotLeader hint -> failwith "asked a non-leader, have to handle it" + | ClientResponse.SessionExpired -> failwith "TODO: session expired, have to handle it" + | ClientResponse.NotLeader hint -> failwith "TODO: asked a non-leader, have to handle it" | ClientResponse.Success (client, sequence) -> match clients.TryGetValue client with | false, _ -> @@ -140,15 +139,25 @@ module App = // TODO: what happens when we try and log client data on a node that doesn't know about the client? let reloadActions () = - // TODO: fix this button, it doesn't work properly + // TODO: fix this button, it doesn't work properly in the failure case + match Ui.getUserPrefs parseByte handleRegisterClientResponse handleClientResponse clusterSize ui with + | Error error -> + let error = sprintf "Unable to parse actions: %s" error + window.alert error + promise { return () } + + | Ok newPrefs -> + let newCluster, newNetwork = InMemoryCluster.make clusterSize cluster <- newCluster network <- newNetwork - userPrefs.Value <- Ui.getUserPrefs parseByte handleRegisterClientResponse handleClientResponse clusterSize ui + userPrefs.Value <- + { newPrefs with + ActionHistory = [] + } - startupActions - |> fun s -> (fullyRerender parseByte userPrefs cluster network, s) + (promise { return () }, userPrefs.Value.ActionHistory) ||> List.fold (fun (inPromise : Promise) action -> promise { let! _ = inPromise @@ -218,7 +227,4 @@ module App = NetworkAction.ClientRequest (server, ClientRequest.RegisterClient handleRegisterClientResponse) |> perform parseByte userPrefs cluster network - ui.ShowConsumedMessages.onchange <- - fun _event -> - printfn "rerendering" - fullyRerender parseByte userPrefs cluster network + ui.ShowConsumedMessages.onchange <- fun _event -> fullyRerender parseByte userPrefs cluster network diff --git a/RaftFable/src/Ui.fs b/RaftFable/src/Ui.fs index 19f0906..40c466f 100644 --- a/RaftFable/src/Ui.fs +++ b/RaftFable/src/Ui.fs @@ -201,7 +201,7 @@ module Ui = let actionList = prefs.ActionHistory |> Seq.map NetworkAction.toString |> String.concat "\n" - ui.ActionHistoryList.textContent <- actionList + ui.ActionHistoryList.value <- actionList let render<'a> (perform : NetworkAction<'a> -> Fable.Core.JS.Promise) @@ -399,25 +399,23 @@ module Ui = (handleClientDataResponse : ClientResponse -> unit) (clusterSize : int) (ui : UiElements) - : UserPreferences<'a> + : Result, string> = - { - LeaderUnderConsideration = ui.SelectedLeaderId.valueAsNumber |> int |> (fun i -> i * 1) - ShowConsumedMessages = ui.ShowConsumedMessages.``checked`` - ActionHistory = - // TODO write these back out again, and give a button to Load - ui.ActionHistoryList.textContent.Split "\n" - |> Seq.filter (not << System.String.IsNullOrEmpty) - |> Seq.map ( - NetworkAction.tryParse<'a> - parse - None - handleRegisterClientResponse - handleClientDataResponse - clusterSize - ) - |> Result.allOkOrError - // TODO handle this - |> Result.get - |> List.ofSeq - } + let actionHistory = + ui.ActionHistoryList.value.Split "\n" + |> Seq.filter (not << System.String.IsNullOrEmpty) + |> Seq.map ( + NetworkAction.tryParse<'a> parse None handleRegisterClientResponse handleClientDataResponse clusterSize + ) + |> Result.allOkOrError + |> Result.map List.ofSeq + + match actionHistory with + | Result.Ok actionHistory -> + { + LeaderUnderConsideration = ui.SelectedLeaderId.valueAsNumber |> int |> (fun i -> i * 1) + ShowConsumedMessages = ui.ShowConsumedMessages.``checked`` + ActionHistory = actionHistory + } + |> Result.Ok + | Result.Error e -> Result.Error (snd e |> String.concat "\n")