Skip to content

Commit 013e30d

Browse files
committed
分离IO线程和逻辑线程,实现后端防抖。诊断性能提高到10万行
1 parent e566f95 commit 013e30d

File tree

128 files changed

+696
-113
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+696
-113
lines changed

CodeFormatServer/src/CodeFormatServer.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,20 @@ using namespace asio::ip;
1616

1717
int main(int argc, char** argv)
1818
{
19-
if(argc > 1)
20-
{
21-
int port = std::stoi(argv[1]);
22-
asio::io_context ioc(1);
19+
auto ioc = std::make_shared<asio::io_context>(1);
20+
if (argc > 1)
21+
{
22+
int port = std::stoi(argv[1]);
23+
tcp::acceptor acceptor(*ioc, tcp::endpoint(tcp::v4(), port));
2324

24-
tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), port));
25-
while(true)
26-
{
27-
auto socket = acceptor.accept();
28-
LanguageClient::GetInstance().SetSession(std::make_shared<SocketIOSession>(std::move(socket)));
29-
LanguageClient::GetInstance().Run();
30-
}
31-
}
32-
else
33-
{
34-
SET_BINARY_MODE();
35-
LanguageClient::GetInstance().SetSession(std::make_shared<StandardIOSession>());
36-
LanguageClient::GetInstance().Run();
37-
}
25+
auto socket = acceptor.accept();
26+
LanguageClient::GetInstance().SetSession(std::make_shared<SocketIOSession>(std::move(socket)));
27+
}
28+
else
29+
{
30+
SET_BINARY_MODE();
31+
LanguageClient::GetInstance().SetSession(std::make_shared<StandardIOSession>());
32+
}
3833

39-
return 0;
40-
}
34+
return LanguageClient::GetInstance().Run(ioc);
35+
}

CodeFormatServer/src/LanguageClient.cpp

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "Util/format.h"
77
#include "Util/Url.h"
88
#include "Util/FileFinder.h"
9-
9+
#include "asio.hpp"
1010
#include "CodeFormatServer/Service/ModuleService.h"
1111
#include "CodeFormatServer/Service/CodeFormatService.h"
1212
#include "CodeFormatServer/Service/CompletionService.h"
@@ -20,7 +20,8 @@ LanguageClient& LanguageClient::GetInstance()
2020

2121
LanguageClient::LanguageClient()
2222
: _defaultOptions(std::make_shared<LuaCodeStyleOptions>()),
23-
_idCounter(0)
23+
_idCounter(0),
24+
_ioc(nullptr)
2425
{
2526
}
2627

@@ -30,12 +31,12 @@ void LanguageClient::InitializeService()
3031
AddService<ModuleService>();
3132
AddService<CompletionService>();
3233

33-
for(auto service : _services)
34+
for (auto service : _services)
3435
{
3536
service->Initialize();
3637
}
3738

38-
for(auto service : _services)
39+
for (auto service : _services)
3940
{
4041
service->Start();
4142
}
@@ -90,13 +91,13 @@ void LanguageClient::UpdateFile(std::string_view uri, vscode::Range range, std::
9091
{
9192
auto filename = url::UrlToFilePath(uri);
9293
auto it = _fileMap.find(filename);
93-
if(it == _fileMap.end())
94+
if (it == _fileMap.end())
9495
{
9596
auto virtualFile = std::make_shared<VirtualFile>(filename);
9697
virtualFile->UpdateFile(std::move(text));
9798
_fileMap[filename] = virtualFile;
9899
}
99-
else if(range.start.line == -1)
100+
else if (range.start.line == -1)
100101
{
101102
it->second->UpdateFile(std::move(text));
102103
}
@@ -116,13 +117,13 @@ void LanguageClient::UpdateFile(std::string_view uri, std::vector<vscode::TextDo
116117
}
117118
}
118119

119-
void LanguageClient::ParseFile(std::string_view uri)
120+
void LanguageClient::ClearFile(std::string_view uri)
120121
{
121122
auto filename = url::UrlToFilePath(uri);
122123
auto it = _fileMap.find(filename);
123124
if (it != _fileMap.end())
124125
{
125-
it->second->MakeParser();
126+
_fileMap.erase(it);
126127
}
127128
}
128129

@@ -161,6 +162,35 @@ void LanguageClient::DiagnosticFile(std::string_view uri)
161162
SendNotification("textDocument/publishDiagnostics", vscodeDiagnosis);
162163
}
163164

165+
void LanguageClient::DelayDiagnosticFile(std::string_view uri)
166+
{
167+
auto stringUri = std::string(uri);
168+
auto task = std::make_shared<asio::steady_timer>(GetIOContext(), std::chrono::milliseconds(500));
169+
auto it = _fileDiagnosticTask.find(uri);
170+
if (it != _fileDiagnosticTask.end())
171+
{
172+
it->second->cancel();
173+
it->second = task;
174+
}
175+
else {
176+
_fileDiagnosticTask.insert({ stringUri, task });
177+
}
178+
179+
task->async_wait([this, stringUri](const asio::error_code& code)
180+
{
181+
if (code == asio::error::operation_aborted)
182+
{
183+
return;
184+
}
185+
DiagnosticFile(stringUri);
186+
auto it = _fileDiagnosticTask.find(stringUri);
187+
if (it != _fileDiagnosticTask.end())
188+
{
189+
_fileDiagnosticTask.erase(it);
190+
}
191+
});
192+
}
193+
164194
std::shared_ptr<LuaParser> LanguageClient::GetFileParser(std::string_view uri)
165195
{
166196
auto filename = url::UrlToFilePath(uri);
@@ -173,12 +203,14 @@ std::shared_ptr<LuaParser> LanguageClient::GetFileParser(std::string_view uri)
173203
return nullptr;
174204
}
175205

176-
void LanguageClient::Run()
206+
int LanguageClient::Run(std::shared_ptr<asio::io_context> ioc)
177207
{
208+
_ioc = ioc;
178209
if (_session)
179210
{
180-
_session->Run();
211+
return _session->Run(*ioc);
181212
}
213+
return 1;
182214
}
183215

184216
std::shared_ptr<LuaCodeStyleOptions> LanguageClient::GetOptions(std::string_view uriOrFilename)
@@ -273,6 +305,11 @@ void LanguageClient::SetRoot(std::string_view root)
273305
_root = root;
274306
}
275307

308+
asio::io_context& LanguageClient::GetIOContext()
309+
{
310+
return *_ioc;
311+
}
312+
276313
uint64_t LanguageClient::GetRequestId()
277314
{
278315
return ++_idCounter;

CodeFormatServer/src/LanguageService.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <iostream>
44
#include <sstream>
55
#include "nlohmann/json.hpp"
6+
#include "asio.hpp"
67
#include "CodeFormatServer/VSCode.h"
78
#include "CodeService/LuaCodeStyleOptions.h"
89
#include "CodeService/LuaFormatter.h"
@@ -155,16 +156,14 @@ std::shared_ptr<vscode::Serializable> LanguageService::OnDidChange(
155156
LanguageClient::GetInstance().UpdateFile(param->textDocument.uri, param->contentChanges);
156157
}
157158

158-
LanguageClient::GetInstance().ParseFile(param->textDocument.uri);
159-
LanguageClient::GetInstance().DiagnosticFile(param->textDocument.uri);
159+
LanguageClient::GetInstance().DelayDiagnosticFile(param->textDocument.uri);
160160
return nullptr;
161161
}
162162

163163
std::shared_ptr<vscode::Serializable> LanguageService::OnDidOpen(
164164
std::shared_ptr<vscode::DidOpenTextDocumentParams> param)
165165
{
166166
LanguageClient::GetInstance().UpdateFile(param->textDocument.uri, {}, std::move(param->textDocument.text));
167-
LanguageClient::GetInstance().ParseFile(param->textDocument.uri);
168167
LanguageClient::GetInstance().DiagnosticFile(param->textDocument.uri);
169168
return nullptr;
170169
}
@@ -206,7 +205,7 @@ std::shared_ptr<vscode::Serializable> LanguageService::OnFormatting(
206205
std::shared_ptr<vscode::Serializable> LanguageService::OnClose(
207206
std::shared_ptr<vscode::DidCloseTextDocumentParams> param)
208207
{
209-
LanguageClient::GetInstance().ParseFile(param->textDocument.uri);
208+
LanguageClient::GetInstance().ClearFile(param->textDocument.uri);
210209

211210
return nullptr;
212211
}

CodeFormatServer/src/Session/IOSession.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <nlohmann/json.hpp>
44
#include "CodeFormatServer/Protocol/ProtocolParser.h"
55
#include <chrono>
6+
#include <thread>
67
#include "Util/format.h"
78

89
namespace chrono = std::chrono;
@@ -17,31 +18,39 @@ IOSession::~IOSession()
1718
{
1819
}
1920

20-
void IOSession::Run()
21+
int IOSession::Run(asio::io_context& ioc)
2122
{
23+
std::thread t([&ioc]()
24+
{
25+
while(true)
26+
{
27+
ioc.run();
28+
std::this_thread::yield();
29+
}
30+
});
31+
t.detach();
32+
return 0;
2233
}
2334

24-
std::string IOSession::Handle(std::string_view msg)
35+
std::string IOSession::Handle(std::shared_ptr<ProtocolParser> parser)
2536
{
2637
try
2738
{
28-
ProtocolParser parser;
29-
30-
parser.Parse(msg);
3139

32-
auto params = parser.GetParams();
40+
auto params = parser->GetParams();
3341

3442
if (!params.is_null())
3543
{
3644
auto start = chrono::system_clock::now();
37-
auto result = _service.Dispatch(parser.GetMethod(), params);
45+
auto result = _service.Dispatch(parser->GetMethod(), params);
3846
if (result)
3947
{
40-
return parser.SerializeProtocol(result);
48+
return parser->SerializeProtocol(result);
4149
}
42-
std::cerr << format("request {}, it cost: {}ms\n", parser.GetMethod(), chrono::duration_cast<chrono::milliseconds>(
43-
chrono::system_clock::now() - start
44-
).count());
50+
std::cerr << format("request {}, it cost: {}ms\n", parser->GetMethod(),
51+
chrono::duration_cast<chrono::milliseconds>(
52+
chrono::system_clock::now() - start
53+
).count());
4554
}
4655
}
4756
catch (std::exception& e)

CodeFormatServer/src/Session/SocketIOSession.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ SocketIOSession::SocketIOSession(asio::ip::tcp::socket&& socket)
99
{
1010
}
1111

12-
void SocketIOSession::Run()
12+
int SocketIOSession::Run(asio::io_context& ioc)
1313
{
14+
IOSession::Run(ioc);
1415
while (true)
1516
{
1617
do
@@ -37,18 +38,26 @@ void SocketIOSession::Run()
3738
}
3839
while (true);
3940

40-
do {
41+
do
42+
{
4143
auto content = _protocolBuffer.ReadOneProtocol();
42-
std::string result = Handle(content);
43-
44+
auto parser = std::make_shared<ProtocolParser>();
45+
parser->Parse(content);
4446
_protocolBuffer.Reset();
45-
if (!result.empty()) {
46-
Send(result);
47-
}
48-
} while (_protocolBuffer.CanReadOneProtocol());
47+
asio::post(ioc, [this, parser]()
48+
{
49+
std::string result = Handle(parser);
50+
51+
if (!result.empty())
52+
{
53+
Send(result);
54+
}
55+
});
56+
}
57+
while (_protocolBuffer.CanReadOneProtocol());
4958
}
5059
endLoop:
51-
return;
60+
return 0;
5261
}
5362

5463
void SocketIOSession::Send(std::string_view content)

CodeFormatServer/src/Session/StandardIOSession.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
#include "CodeFormatServer/Session/StandardIOSession.h"
22

33
#include <iostream>
4-
5-
#ifndef _WIN32
64
#include <asio.hpp>
5+
#ifndef _WIN32
76
#include <unistd.h>
87
#endif
98
#include "CodeFormatServer/Protocol/ProtocolParser.h"
109
#include "CodeFormatServer/Protocol/ProtocolBuffer.h"
1110

12-
1311
class StandardIO
1412
{
1513
public:
@@ -81,13 +79,11 @@ void StandardIO::Write(std::string_view content)
8179
std::cout.write(content.data(), content.size());
8280
}
8381

84-
8582
#endif
8683

8784

88-
void StandardIOSession::Run()
85+
int StandardIOSession::Run(asio::io_context& ioc)
8986
{
90-
9187
while (true)
9288
{
9389
do
@@ -115,18 +111,24 @@ void StandardIOSession::Run()
115111

116112
do
117113
{
118-
std::string result = Handle(_protocolBuffer.ReadOneProtocol());
119-
114+
auto content = _protocolBuffer.ReadOneProtocol();
115+
auto parser = std::make_shared<ProtocolParser>();
116+
parser->Parse(content);
120117
_protocolBuffer.Reset();
121-
if (!result.empty())
122-
{
123-
Send(result);
124-
}
118+
asio::post(ioc, [this, parser]()
119+
{
120+
std::string result = Handle(parser);
121+
122+
if (!result.empty())
123+
{
124+
Send(result);
125+
}
126+
});
125127
}
126128
while (_protocolBuffer.CanReadOneProtocol());
127129
}
128130
endLoop:
129-
return;
131+
return 0;
130132
}
131133

132134
void StandardIOSession::Send(std::string_view content)

0 commit comments

Comments
 (0)