Support #7323
closedusing BroadCast-example for fast value update
0%
Description
Using Wt-4.1.1, Chrome, ubuntu 18.04
Hi!
I'm using the BroadCast-example to build an application that shows values in different browser-windows. My first test opens 10 browser-windows to show one single value which is updated by a server-post every 20ms. After a while the whole application crashes with a segfault. I'm helpless what the error could be. Am I updating too fast? Which speed of updating is possible?
Here's the run-server-loop:
void Server::run()
{
for(;;) {
try {
std::this_thread::sleep_for(std::chrono::milliseconds(20));
if(stop_) return;
{
std::unique_lock lock(mutex_);
counter_ = Data::instance().get(); // content_ is a member of Server-class (type double)
for(auto& c : connections_) {
Wt::WServer::instance()->post(c.sessionId, c.function);
}
}
}
catch(...){
logger->error("unknown error");
}
}
}
The Data::instance()-object is a singleton that has locks:
class Data
{
public:
Data() = default;
~Data() = default;
void set(double value)
{
std::unique_lock<std::mutex> lock(mutex_);
value_ = value;
}
double get() const
{
std::unique_lock<std::mutex> lock(mutex_);
return value_;
}
static Data& instance()
{
static Data _instance;
return _instance;
}
private:
double value_{0};
mutable std::mutex mutex_;
};
Files
Updated by Roel Standaert almost 5 years ago
While 20ms may be pretty fast (if you're not using WebSockets I would recommend enabling that to lower the overhead), but that should not cause segmentation faults. I can't immediately tell from your code where it's are going wrong.
If you want to find the source of the segfault, I'd recommend running it with gdb and seeing what the backtrace is when the segfault happens. Using valgrind (though this will slow things down a lot) or address sanitizer could also help.
Updated by Fabian V almost 5 years ago
Hi thanks for the response!
Actually I don't know how to enable websockets for wt? Is there any example you could recommend?
I've tested my code and it even crashes when I use a local double-variable and d somiething like "content_" (please see code below). So there's no big change comparing to the BroadCast-example.
The program crashes while trying to execute the function pointer "c.function" and it looks like there's going somithing wrong with WObserver. So I thought this might be a wt-internal problem. You should be able to comprehend the problem if you just run the BroadCast-example and set the sleep to <=20ms and inkrement a double member. After a while the program crashes.
Befor using somithing like this example in my company's software, I need to make shure that the Server/Execution doesn't crash in this example program.
void Server::run()
{
for(;;) {
try {
std::this_thread::sleep_for(std::chrono::milliseconds(20));
if(stop_) return;
{
std::unique_lock lock(mutex_);
if(counter_++ > 10000) counter_ = 0;
for(auto& c : connections_) {
Wt::WServer::instance()->post(c.sessionId, c.function);
}
}
}
catch(...){
logger->error("unknown error");
}
}
}
Updated by Roel Standaert almost 5 years ago
- File broadcast_example_issue_7323.patch broadcast_example_issue_7323.patch added
- Status changed from New to Feedback
You can enable WebSockets in your wt_config.xml
.
A simple one that only enables WebSockets would look like this:
<server>
<application-settings location="*">
<web-sockets>true</web-sockets>
</application-settings>
</server>
You can provide a custom config with the -c
option if you're using the wthttp
connector.
What exactly do you mean by "after a while"? How many sessions do you have going at the same time?
I provided the simple patch I'm testing with, if I understood your description of the issue correctly, and that seems to be working perfectly fine (even when not using WebSockets). I'm using the latest master on Ubuntu 18.04. I'm not using the operating system's Boost, though. I'm using Boost 1.68.0.
Updated by Fabian V almost 5 years ago
Ok thanks I'll check that option.
The following command says 1.62 of boost:
cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION"
I'm running the tests in a VM and I'm using chrome. I've opened 10 windows and let them show the website.
The crash sometimes comes after a few minutes and sometimes after 30 minutes. If you set the sleep down to 1 ms the program crashes faster.
Updated by Roel Standaert almost 5 years ago
I think I see it (after shortening the timeout and running with address sanitizer).
An observing_ptr
is being put into an function object (the bindSafe
), and because that function object is being passed to schedule()
that causes it at some point to be copied, causing a call to addObserver
when we don't have the application lock.
Updated by Roel Standaert almost 5 years ago
So, ironically, the safe thing here is to not use bindSafe(...)
.
Updated by Fabian V almost 5 years ago
Ok that sounds funny. So the right way would be just to call the function?
Like this (from BroadCast-example ClientWidget-ctor:
server.connect(this, ([this]() { updateData(); }));
Updated by Roel Standaert almost 5 years ago
Yes, a lambda capture of this
, or std::bind
would work here.
The whole observing\_ptr@/@observable
system is not thread safe (on purpose: it's a simpler, more lightweight solution). It is only intended for use when you have the ApplicationLock
.
This is indeed an error in that example.
Updated by Roel Standaert almost 5 years ago
- Status changed from Feedback to Resolved
I updated the example.
Updated by Roel Standaert almost 5 years ago
- Status changed from Resolved to Closed