我正在调试这个库:https://github.com/IntelAI/he-transformer,因为它在目前的状态下对我来说有点太不可靠了。
客户端-服务器通信似乎有问题,在文件中具体说明
src/seal/he_seal_executable.cpp
。以下代码有时会在最后三行的某处阻塞:
for (const auto& pb_tensor : pb_tensors) {
pb::TCPMessage result_msg;
result_msg.set_type(pb::TCPMessage_Type_RESPONSE);
*result_msg.add_he_tensors() = pb_tensor;
// ...
m_session->write_message(TCPMessage(std::move(result_msg)));
}
// Wait until message is written
std::unique_lock<std::mutex> mlock(m_result_mutex);
std::condition_variable& writing_cond = m_session->is_writing_cond();
writing_cond.wait(mlock, [this] { return !m_session->is_writing(); });
}
is_writing_cond
只是检查消息队列是否为空。对应的客户端代码(src/seal/he_seal_client.cpp
)是这样的:
void HESealClient::handle_result(const pb::TCPMessage& message) {
// ...
close_connection();
}
在哪里
close_connection
调用这个函数(在src/tcp/tcp_client.cpp
):
/// \brief Closes the socket
void TCPClient::close() {
NGRAPH_HE_LOG(1) << "Closing socket";
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
boost::asio::post(m_io_context, [this]() { m_socket.close(); });
}
如果我注释掉
close_connection();
,服务器似乎可靠地终止了。
不幸的是,我不太熟悉 boost,甚至一般的 c++,所以我在这方面没有取得太大进展。我认为服务器正在后台异步清空消息队列:
void TCPSession::do_write() {
// ...
boost::asio::async_write(
m_socket, boost::asio::buffer(m_write_buffer),
[this, self](boost::system::error_code ec, std::size_t /* length */) {
NGRAPH_CHECK(!ec, "Server error writing message: ", ec.message());
m_message_queue.pop_front();
if (!m_message_queue.empty()) {
do_write();
} else {
m_is_writing.notify_all();
}
});
}
我想,当没有客户收听消息时,这就会停止。如果这个问题太模糊,我深表歉意,但我希望对这个主题有一定经验的人可以看到代码中的一些明显错误,这将帮助我使库可用。
我尝试在
close_connection();
中注释掉HESealClient::handle_result
行,这似乎解决了服务器“挂起”的问题,但不幸的是,这不是解决方案,因为它会导致客户端永远不会终止。