Skip to content

Commit

Permalink
#1414 - Use JsonSerialization instead of BinarySerialization for WS6
Browse files Browse the repository at this point in the history
  • Loading branch information
Jooseppi12 committed Sep 4, 2024
1 parent f6f867e commit 264eafe
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
<ItemGroup>
<Compile Include="LoggerBase.fs" />
Expand Down
37 changes: 28 additions & 9 deletions src/compiler/WebSharper.Compiler/WsFscServiceCommon.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module WebSharper.Compiler.WsFscServiceCommon

open System.IO.Pipes
open System.Runtime.Serialization.Formatters.Binary
open System.Text

type ArgsType = {args: string array}

Expand All @@ -19,17 +19,36 @@ let hashPath (fullPath: string) =
let readingMessages (pipe: PipeStream) (handleMessage: obj -> Async<'a option>) =
let rec readingMessage() =
async {
let bf = new BinaryFormatter()
try
let deserializedMessage = bf.Deserialize(pipe)
let! finish = handleMessage deserializedMessage
match finish with
| Some _ -> return finish
| None -> return! readingMessage()
let readMessage () =
async {
let sb = new StringBuilder()
let mutable buffer = Array.zeroCreate<byte> 5
let bytesRead = pipe.Read(buffer, 0, buffer.Length)
sb.Append(System.Text.Encoding.UTF8.GetString(buffer)) |> ignore
buffer <- Array.zeroCreate<byte> 5
while (not pipe.IsMessageComplete) do
let bytesRead = pipe.Read(buffer, 0, buffer.Length)
sb.Append(System.Text.Encoding.UTF8.GetString(buffer)) |> ignore
buffer <- Array.zeroCreate<byte> 5
let res = sb.ToString()
return res.Replace("\x00", "")
}
let! byteArr = readMessage ()
match byteArr with
| "" | null ->
do! Async.Sleep 1000
return! readingMessage()
| _ ->
let deserializedMessage = System.Text.Json.JsonSerializer.Deserialize(byteArr)
let! finish = handleMessage deserializedMessage
match finish with
| Some _ -> return finish
| None -> return! readingMessage()
with
| :? System.Runtime.Serialization.SerializationException ->
| :? System.Runtime.Serialization.SerializationException as ex->
return None
| _ ->
| ex ->
return! readingMessage()
}
readingMessage ()
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/WebSharper.Compiler/paket.references
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Mono.Cecil
exclude Mono.Cecil.Rocks.dll
System.Runtime.Loader
FSharp.Core
FSharp.Core
System.Text.Json
19 changes: 9 additions & 10 deletions src/compiler/WebSharper.FSharp.Service/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ open System
open System.IO.Pipes
open System.Threading
open System.IO
open System.Runtime.Serialization.Formatters.Binary
open FSharp.Compiler.CodeAnalysis
open System.Runtime.Caching
open WebSharper.Compiler.WsFscServiceCommon
Expand Down Expand Up @@ -104,12 +103,11 @@ let startListening() =
let send (serverPipe: NamedPipeServerStream) paramPrint str = async {
let newMessage = paramPrint str
nLogger.Trace(sprintf "Server sends: %s" newMessage)
let bf = new BinaryFormatter()
use ms = new MemoryStream()
bf.Serialize(ms, newMessage)
ms.Flush()
ms.Position <- 0L
do! ms.CopyToAsync(serverPipe) |> Async.AwaitTask
let options = System.Text.Json.JsonSerializerOptions()
options.Encoder <-System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
let res = System.Text.Json.JsonSerializer.Serialize(newMessage, options)
let bytes = System.Text.Encoding.UTF8.GetBytes res
serverPipe.Write(bytes, 0, bytes.Length)
serverPipe.Flush()
}
let sendFinished (serverPipe: NamedPipeServerStream) = sprintf "x: %i" |> send serverPipe
Expand Down Expand Up @@ -248,7 +246,7 @@ let startListening() =
try
let handleMessage (message: obj) =
async {
let message = message :?> ArgsType
let message = System.Text.Json.JsonSerializer.Deserialize<ArgsType>(string message)
if message.args.Length = 1 && message.args.[0].StartsWith "compile:" then
let project = message.args.[0].Substring(8)
match argsDict.TryGetValue project with
Expand Down Expand Up @@ -281,12 +279,13 @@ let startListening() =
let serverPipe = new NamedPipeServerStream(
pipeName, // name of the pipe,
PipeDirection.InOut, // diretcion of the pipe
-1, // max number of server instances
PipeTransmissionMode.Byte, // Transmissione Mode
NamedPipeServerStream.MaxAllowedServerInstances, // max number of server instances
PipeTransmissionMode.Message, // Transmissione Mode
PipeOptions.WriteThrough // the operation will not return the control until the write is completed
||| PipeOptions.Asynchronous)
do! serverPipe.WaitForConnectionAsync(token) |> Async.AwaitTask
nLogger.Debug(sprintf "Client connected on %s pipeName" pipeName)
serverPipe.ReadMode <- PipeTransmissionMode.Message
Async.Start (handOverPipe serverPipe token, token)
do! pipeListener token
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<Signed>False</Signed>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AssemblyName>wsfscservice</AssemblyName>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
<RuntimeIdentifiers>win-x64;linux-x64;linux-musl-x64;osx-x64</RuntimeIdentifiers>
<RollForward>LatestMajor</RollForward>
<ApplicationIcon>../../../tools/WebSharper.ico</ApplicationIcon>
Expand Down
23 changes: 12 additions & 11 deletions src/compiler/WebSharper.FSharp/NamedPipeClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// $end{copyright}
module WebSharper.FSharp.NamedPipeClient
#nowarn "44"
open System.Text

open System.Diagnostics
open System.IO.Pipes
Expand Down Expand Up @@ -103,14 +104,15 @@ let sendCompileCommand args =
PipeDirection.InOut, // direction of the pipe
PipeOptions.WriteThrough // the operation will not return the control until the write is completed
||| PipeOptions.Asynchronous)
let Write (ms: MemoryStream) =
let Write (ms: byte []) =
if clientPipe.IsConnected && clientPipe.CanWrite then
let unexpectedFinishErrorCode = -12211
let write = async {
let printResponse (message: obj) =
async {
// messages on the service have n: e: or x: prefix for stdout stderr or error code kind of output
match message :?> string with
let jE = message :?> Json.JsonElement
match jE.GetString() with
| StdOut n ->
printfn "%s" n
return None
Expand All @@ -124,8 +126,9 @@ let sendCompileCommand args =
nLogger.Error(sprintf "Unrecognizable message from server (%i): %s" unrecognizedMessageErrorCode x)
return unrecognizedMessageErrorCode |> Some
}
do! ms.CopyToAsync(clientPipe) |> Async.AwaitTask
clientPipe.Write(ms, 0, ms.Length)
clientPipe.Flush()
clientPipe.WaitForPipeDrain()
let! errorCode = readingMessages clientPipe printResponse
match errorCode with
| Some -12211 ->
Expand All @@ -149,18 +152,16 @@ let sendCompileCommand args =




let bf = new BinaryFormatter();
use ms = new MemoryStream()

nLogger.Debug "WebSharper compilation arguments:"
args |> Array.iter (fun x -> nLogger.Debug(" " + x))
// args going binary serialized to the service.
let startCompileMessage: ArgsType = {args = args}
bf.Serialize(ms, startCompileMessage);
ms.Flush();
ms.Position <- 0L
clientPipe.Connect()
let returnCode = Write ms
clientPipe.ReadMode <- PipeTransmissionMode.Message
let options = System.Text.Json.JsonSerializerOptions()
options.Encoder <- Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
let res = System.Text.Json.JsonSerializer.Serialize(startCompileMessage, options)
let bytes = System.Text.Encoding.UTF8.GetBytes res
let returnCode = Write bytes
nLogger.Debug(sprintf "wsfscservice.exe compiled in %s with error code: %i" location returnCode)
returnCode
1 change: 0 additions & 1 deletion src/compiler/WebSharper.FSharp/WebSharper.FSharp.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<Signed>False</Signed>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<FSharpTool>True</FSharpTool>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
<RuntimeIdentifiers>win-x64;linux-x64;linux-musl-x64;osx-x64</RuntimeIdentifiers>
<RollForward>LatestMajor</RollForward>
</PropertyGroup>
Expand Down

0 comments on commit 264eafe

Please sign in to comment.