-
Notifications
You must be signed in to change notification settings - Fork 349
Open
Description
Add a description
In my case, I have sporadic read operations (subscriptions to new types of events, which may be sent by the client once on connection) and a huge number of events to send (up to 2k per second per socket)
TLS websocket is not thread-safe. It means that it should be used in a single coroutine, and part of the time is taken for dummy syscalls on TryRecv.
The handling may look like:
void Handle(userver::server::websocket::WebSocketConnection& connection,
userver::server::request::RequestContext& requestContext) const override {
while (!engine::current_task::ShouldCancel()) {
userver::server::websocket::Message message;
if (connection.TryRecv(message)) {
HandleMessage(message)
}
std::string message;
if (queue->Pop(message, deadline(10ms)) {
connection.SendText(message);
}
}
}
In the load test, it leads to 35-40% performance degradation in comparison with two coroutines.
I need to be able to read and write from two coroutines for better performance, e.g.:
void ReadLoop(userver::server::websocket::WebSocketConnection& connection)
{
userver::server::websocket::Message message;
while (!userver::engine::current_task::ShouldCancel())
{
if (!connection.WaitReadable(Deadline(10ms)))
{
continue;
}
{
std::lock_guard lock(_sslLock);
if (!connection.Recv(message))
{
continue;
}
}
HandleMessage(message);
}
}
void SendLoop( userver::server::websocket::WebSocketConnection& connection)
{
while (!engine::current_task::ShouldCancel()) {
std::string message;
if (queue->Pop(message) {
std::lock_guard lock(_sslLock);
connection.SendText(message);
}
}
}
At least there is no WaitReadable for WebSocketConnection and current implementation of TlsWrapper::WaitReadable is not-thread safe as well and requires lock:
bool TlsWrapper::WaitReadable(Deadline deadline) {
impl_->CheckAlive();
char buf = 0;
return impl_->PerformSslIo(
&SSL_peek_ex, &buf, 1, impl::TransferMode::kOnce, InterruptAction::kPass, deadline, "WaitReadable"
);
}
Metadata
Metadata
Assignees
Labels
No labels