From 104449f6a9bc6e392cba5e0ce85a4851cba3125a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Tue, 7 Apr 2020 16:39:18 +0800 Subject: [PATCH] Revert "Update to messagepack 2.1" This reverts commit 2bd8cb7156fbd262865d9a25976575d687db08aa. --- Program.fs | 42 +++++++++++++++++++++++++----- fvim.fsproj | 2 +- neovim.fs | 73 ++++++++++++++++++++++------------------------------- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/Program.fs b/Program.fs index ab19d5c..387e3b0 100644 --- a/Program.fs +++ b/Program.fs @@ -7,11 +7,15 @@ open Avalonia.ReactiveUI open System.Threading open Avalonia.Controls.ApplicationLifetimes +open MessagePack +open MessagePack.Resolvers + open System open System.IO open getopt open Shell open common +open MessagePack.Formatters // Avalonia configuration, don't remove; also used by visual designer. [] @@ -26,6 +30,32 @@ let buildAvaloniaApp() = .With(new MacOSPlatformOptions(ShowInDock=true)) .LogToDebug() +type MsgPackFormatter(resolver: IFormatterResolver) = + let m_formatter = resolver.GetFormatter() + interface IMessagePackFormatter with + member this.Serialize(bytes: byref, offset: int, value: obj, formatterResolver: IFormatterResolver): int = + m_formatter.Serialize(&bytes, offset, value, formatterResolver) + member x.Deserialize(bytes: byte[] , offset: int, formatterResolver: IFormatterResolver , readSize: byref) = + if MessagePackBinary.GetMessagePackType(bytes, offset) = MessagePackType.Extension then + let result = MessagePackBinary.ReadExtensionFormat(bytes, offset, &readSize) + if result.TypeCode = 1y then + let mutable _size = 0 + m_formatter.Deserialize(result.Data, 0, formatterResolver, &_size) + else + m_formatter.Deserialize(bytes, offset, formatterResolver, &readSize) + else + m_formatter.Deserialize(bytes, offset, formatterResolver, &readSize) + +type MsgPackResolver() = + static let s_formatter = box(MsgPackFormatter(MessagePack.Resolvers.StandardResolver.Instance)) + static let s_resolver = MessagePack.Resolvers.StandardResolver.Instance + interface IFormatterResolver with + member x.GetFormatter<'a>() = + if typeof<'a> = typeof then + s_formatter :?> IMessagePackFormatter<'a> + else + s_resolver.GetFormatter<'a>() + [] [] @@ -33,12 +63,12 @@ let main(args: string[]) = let _ = Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA) - //CompositeResolver.RegisterAndSetAsDefault( - // MsgPackResolver() - //// ImmutableCollectionResolver.Instance, - //// FSharpResolver.Instance, - //// StandardResolver.Instance - //) + CompositeResolver.RegisterAndSetAsDefault( + MsgPackResolver() + // ImmutableCollectionResolver.Instance, + // FSharpResolver.Instance, + // StandardResolver.Instance + ) AppDomain.CurrentDomain.UnhandledException.Add(fun exArgs -> let filename = Path.Combine(config.configdir, sprintf "fvim-crash-%s.txt" (DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"))) diff --git a/fvim.fsproj b/fvim.fsproj index 63ff572..329eb25 100644 --- a/fvim.fsproj +++ b/fvim.fsproj @@ -90,7 +90,7 @@ - + runtime; build; native; contentfiles; analyzers diff --git a/neovim.fs b/neovim.fs index 0f5c2ff..df01c94 100644 --- a/neovim.fs +++ b/neovim.fs @@ -19,7 +19,6 @@ open System.Threading.Tasks open System.Threading open FSharp.Control.Reactive open FSharp.Control.Tasks.V2.ContextSensitive -open MessagePack.Formatters let inline private trace fmt = trace "neovim.process" fmt @@ -111,47 +110,35 @@ type Nvim() = | _ -> failwith "" let read (ob: IObserver) (cancel: CancellationToken) = - let thread = - Thread(fun () -> - let task = task { - trace "%s" "begin read loop" - trace "%A" <| stdout.GetType().FullName - use reader = new MessagePackStreamReader(stdout) - let mutable ex = false - while not ex && not cancel.IsCancellationRequested do - try - let! msgpack = reader.ReadAsync(cancel) - if msgpack.HasValue then - let mutable v = msgpack.Value - let data = MessagePackSerializer.Deserialize(&v) - ob.OnNext(data) - else - ex <- true - with - | :? InvalidOperationException - | :? System.IO.IOException - | :? System.Net.Sockets.SocketException - | :? ObjectDisposedException - as _ex -> ex <- true - - let ec = serverExitCode() - if ec.IsSome then - let code = ec.Value - trace "end read loop: process exited, code = %d" code - if code <> 0 then - m_cancelSrc.Cancel() - ob.OnNext([|box (Crash code)|]) - else - ob.OnNext([|box Exit|]) - else - trace "%s" "end read loop." - ob.OnNext([|box Exit|]) - ob.OnCompleted() - } - task.Wait() - ) - thread.Start() - Task.Factory.StartNew(fun () -> thread.Join()) + Task.Factory.StartNew(fun () -> + trace "%s" "begin read loop" + let mutable ex = false + while not ex && not cancel.IsCancellationRequested do + try + let data = MessagePackSerializer.Deserialize(stdout, true) + ob.OnNext(data) + with + | :? InvalidOperationException + | :? System.IO.IOException + | :? System.Net.Sockets.SocketException + | :? ObjectDisposedException + as _ex -> ex <- true + + let ec = serverExitCode() + if ec.IsSome then + let code = ec.Value + trace "end read loop: process exited, code = %d" code + if code <> 0 then + m_cancelSrc.Cancel() + ob.OnNext([|box (Crash code)|]) + else + ob.OnNext([|box Exit|]) + else + trace "%s" "end read loop." + ob.OnNext([|box Exit|]) + ob.OnCompleted() + + , cancel, TaskCreationOptions.LongRunning, TaskScheduler.Current) let reply (id: int) (rsp: Response) = task { let result, error = @@ -225,7 +212,7 @@ type Nvim() = let payload = mkparams4 0 myid ev.method ev.parameters #if DEBUG - MessagePackSerializer.SerializeToJson(payload) |> trace "call: %d -> %s" myid + MessagePackSerializer.ToJson(payload) |> trace "call: %d -> %s" myid #endif do! MessagePackSerializer.SerializeAsync(stdin, payload) do! stdin.FlushAsync()