|
2 | 2 | using System.Collections.Generic;
|
3 | 3 | using System.Diagnostics;
|
4 | 4 | using System.IO;
|
| 5 | +using System.IO.Pipelines; |
5 | 6 | using System.Text;
|
6 | 7 | using System.Threading;
|
7 | 8 | using System.Threading.Tasks;
|
|
10 | 11 | using Flow.Launcher.Infrastructure;
|
11 | 12 | using Flow.Launcher.Plugin;
|
12 | 13 | using Microsoft.VisualStudio.Threading;
|
| 14 | +using Nerdbank.Streams; |
13 | 15 | using StreamJsonRpc;
|
14 | 16 |
|
15 | 17 | namespace Flow.Launcher.Core.Plugin
|
16 | 18 | {
|
17 |
| - internal class PythonPluginV2 : JsonRPCPluginV2, IReloadable, IDisposable |
| 19 | + internal class PythonPluginV2 : JsonRPCPluginV2 |
18 | 20 | {
|
19 | 21 | private readonly ProcessStartInfo _startInfo;
|
20 | 22 | private Process _process;
|
21 | 23 |
|
22 | 24 | public override string SupportedLanguage { get; set; } = AllowedLanguage.Python;
|
23 | 25 |
|
24 |
| - protected override JsonRpc RPC { get; set; } |
| 26 | + protected override IDuplexPipe ClientPipe { get; set; } |
25 | 27 |
|
26 | 28 |
|
27 | 29 | public PythonPluginV2(string filename)
|
@@ -61,43 +63,38 @@ public override async Task InitAsync(PluginInitContext context)
|
61 | 63 | _startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
|
62 | 64 |
|
63 | 65 | _process = Process.Start(_startInfo);
|
64 |
| - |
65 | 66 | ArgumentNullException.ThrowIfNull(_process);
|
66 |
| - |
67 |
| - SetupJsonRPC(_process, context.API); |
| 67 | + |
| 68 | + SetupPipe(_process); |
68 | 69 |
|
69 | 70 | await base.InitAsync(context);
|
70 | 71 | }
|
71 | 72 |
|
72 |
| - public void Dispose() |
| 73 | + public override async ValueTask DisposeAsync() |
73 | 74 | {
|
74 | 75 | _process.Kill(true);
|
| 76 | + await _process.WaitForExitAsync(); |
75 | 77 | _process.Dispose();
|
76 |
| - base.Dispose(); |
| 78 | + await base.DisposeAsync(); |
77 | 79 | }
|
78 | 80 |
|
79 |
| - public void ReloadData() |
| 81 | + private void SetupPipe(Process process) |
| 82 | + { |
| 83 | + var (reader, writer) = (PipeReader.Create(process.StandardOutput.BaseStream), |
| 84 | + PipeWriter.Create(process.StandardInput.BaseStream)); |
| 85 | + ClientPipe = new DuplexPipe(reader, writer); |
| 86 | + } |
| 87 | + |
| 88 | + public override async Task ReloadDataAsync() |
80 | 89 | {
|
81 | 90 | var oldProcess = _process;
|
82 | 91 | _process = Process.Start(_startInfo);
|
83 | 92 | ArgumentNullException.ThrowIfNull(_process);
|
84 |
| - SetupJsonRPC(_process, Context.API); |
| 93 | + SetupPipe(_process); |
| 94 | + await base.ReloadDataAsync(); |
85 | 95 | oldProcess.Kill(true);
|
| 96 | + await oldProcess.WaitForExitAsync(); |
86 | 97 | oldProcess.Dispose();
|
87 | 98 | }
|
88 |
| - |
89 |
| - private void SetupJsonRPC(Process process, IPublicAPI api) |
90 |
| - { |
91 |
| - var formatter = new JsonMessageFormatter(); |
92 |
| - var handler = new NewLineDelimitedMessageHandler(process.StandardInput.BaseStream, |
93 |
| - process.StandardOutput.BaseStream, |
94 |
| - formatter); |
95 |
| - |
96 |
| - ErrorStream = _process.StandardError; |
97 |
| - |
98 |
| - RPC = new JsonRpc(handler, new JsonRPCPublicAPI(api)); |
99 |
| - RPC.SynchronizationContext = null; |
100 |
| - RPC.StartListening(); |
101 |
| - } |
102 | 99 | }
|
103 | 100 | }
|
0 commit comments