-
Notifications
You must be signed in to change notification settings - Fork 0
/
ApiRig.cs
124 lines (101 loc) · 3.37 KB
/
ApiRig.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System.Diagnostics;
using Brainstorm.Data;
using Brainstorm.Rig.Hubs;
using Brainstorm.Rig.Models;
using Microsoft.AspNetCore.SignalR;
namespace Brainstorm.Rig.Services;
public class ApiRig : IDisposable
{
DbManager manager;
ProcessRunner runner;
readonly IHubContext<RigHub> socket;
public Seeder Seeder { get; private set; }
public RigState State { get; private set; }
public ApiRig(IHubContext<RigHub> socket)
{
this.socket = socket;
ResetDbManager().Wait();
State = InitState();
}
async Task Broadcast (string message, bool isError = false) =>
await socket
.Clients
.All
.SendAsync("output", new RigOutput { Message = message, IsError = isError });
DataReceivedEventHandler ProcessOutput =>
async (sender, e) => await Broadcast(e.Data );
DataReceivedEventHandler ProcessError =>
async (sender, e) => await Broadcast(e.Data, true);
EventHandler ProcessExit =>
async (sender, e) => await Broadcast("Process exitied");
EventHandler<DataSeededEventArgs> ProcessDataSeed =>
async (sender, e) => await Broadcast(e.Message);
void RegisterProcessStreams()
{
runner.Process.OutputDataReceived += ProcessOutput;
runner.Process.ErrorDataReceived += ProcessError;
runner.Process.Exited += ProcessExit;
}
RigState InitState() => new()
{
Connection = manager.Connection,
DatabaseCreated = false,
ProcessRunning = false
};
async Task ResetDbManager(bool dispose = false)
{
bool restartProcess = State is not null
&& State.ProcessRunning;
if (dispose) {
runner.Dispose();
manager.Dispose();
}
manager = new("App", true, true);
runner = new(manager.Connection);
RegisterProcessStreams();
if (restartProcess)
await StartProcess();
}
public async Task<RigState> InitializeDatabase()
{
await Broadcast($"Initializing the database at {manager.Connection}...");
var result = await manager.InitializeAsync();
State.DatabaseCreated = result;
if (result) {
Seeder = new(manager.Context);
Seeder.DataSeeded += ProcessDataSeed;
await Broadcast("Database successfully initialized");
}
return State;
}
public async Task<RigState> DestroyDatabase()
{
await Broadcast("Destroying the database...");
await ResetDbManager(true);
State.DatabaseCreated = false;
State.Connection = manager.Connection;
await Broadcast("Database successfully destroyed");
return State;
}
public async Task<RigState> StartProcess()
{
runner.Start();
await Broadcast($"Process Started: {runner.Process.ProcessName} - {runner.Process.Id}");
State.ProcessRunning = runner.Running;
return State;
}
public async Task<RigState> KillProcess()
{
await Broadcast($"Killing process {runner.Process.ProcessName} - {runner.Process.Id}...");
runner.Kill();
State.ProcessRunning = runner.Running;
await Broadcast("Process successfully killed");
return State;
}
public void Dispose()
{
manager.Dispose();
runner.Dispose();
GC.SuppressFinalize(this);
}
}