Better handling of out of memory situations in live data websocket (onBattery)
This commit is contained in:
parent
210fce67ce
commit
ec93004724
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
//#include <HuaweiFrameHandler.h>
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsHuaweiLiveClass {
|
class WebApiWsHuaweiLiveClass {
|
||||||
public:
|
public:
|
||||||
@ -21,4 +21,6 @@ private:
|
|||||||
|
|
||||||
uint32_t _lastWsCleanup = 0;
|
uint32_t _lastWsCleanup = 0;
|
||||||
uint32_t _lastUpdateCheck = 0;
|
uint32_t _lastUpdateCheck = 0;
|
||||||
|
|
||||||
|
std::mutex _mutex;
|
||||||
};
|
};
|
||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsBatteryLiveClass {
|
class WebApiWsBatteryLiveClass {
|
||||||
public:
|
public:
|
||||||
@ -21,4 +22,6 @@ private:
|
|||||||
uint32_t _lastWsCleanup = 0;
|
uint32_t _lastWsCleanup = 0;
|
||||||
uint32_t _lastUpdateCheck = 0;
|
uint32_t _lastUpdateCheck = 0;
|
||||||
static constexpr uint16_t _responseSize = 1024 + 512;
|
static constexpr uint16_t _responseSize = 1024 + 512;
|
||||||
|
|
||||||
|
std::mutex _mutex;
|
||||||
};
|
};
|
||||||
@ -4,6 +4,7 @@
|
|||||||
#include "ArduinoJson.h"
|
#include "ArduinoJson.h"
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <VeDirectMpptController.h>
|
#include <VeDirectMpptController.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class WebApiWsVedirectLiveClass {
|
class WebApiWsVedirectLiveClass {
|
||||||
public:
|
public:
|
||||||
@ -23,4 +24,6 @@ private:
|
|||||||
uint32_t _lastWsCleanup = 0;
|
uint32_t _lastWsCleanup = 0;
|
||||||
uint32_t _dataAgeMillis = 0;
|
uint32_t _dataAgeMillis = 0;
|
||||||
static constexpr uint16_t _responseSize = 1024 + 128;
|
static constexpr uint16_t _responseSize = 1024 + 128;
|
||||||
|
|
||||||
|
std::mutex _mutex;
|
||||||
};
|
};
|
||||||
@ -7,6 +7,7 @@
|
|||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Huawei_can.h"
|
#include "Huawei_can.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
#include "Utils.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
|
|
||||||
@ -50,16 +51,15 @@ void WebApiWsHuaweiLiveClass::loop()
|
|||||||
_lastUpdateCheck = millis();
|
_lastUpdateCheck = millis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String buffer;
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
// free JsonDocument as soon as possible
|
DynamicJsonDocument root(1024);
|
||||||
{
|
if (Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||||
DynamicJsonDocument root(1024);
|
|
||||||
JsonVariant var = root;
|
JsonVariant var = root;
|
||||||
generateJsonResponse(var);
|
generateJsonResponse(var);
|
||||||
serializeJson(root, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer) {
|
String buffer;
|
||||||
|
serializeJson(root, buffer);
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
if (Configuration.get().Security.AllowReadonly) {
|
||||||
_ws.setAuthentication("", "");
|
_ws.setAuthentication("", "");
|
||||||
} else {
|
} else {
|
||||||
@ -69,7 +69,9 @@ void WebApiWsHuaweiLiveClass::loop()
|
|||||||
_ws.textAll(buffer);
|
_ws.textAll(buffer);
|
||||||
}
|
}
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/livedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/huaweilivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/huaweilivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,15 +124,19 @@ void WebApiWsHuaweiLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 1024U);
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, 1024U);
|
||||||
auto& root = response->getRoot();
|
auto& root = response->getRoot();
|
||||||
|
|
||||||
generateJsonResponse(root);
|
generateJsonResponse(root);
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/livedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/huaweilivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
WebApi.sendTooManyRequests(request);
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/huaweilivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
WebApi.sendTooManyRequests(request);
|
WebApi.sendTooManyRequests(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,7 @@
|
|||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
WebApiWsBatteryLiveClass::WebApiWsBatteryLiveClass()
|
WebApiWsBatteryLiveClass::WebApiWsBatteryLiveClass()
|
||||||
: _ws("/batterylivedata")
|
: _ws("/batterylivedata")
|
||||||
@ -48,16 +49,15 @@ void WebApiWsBatteryLiveClass::loop()
|
|||||||
_lastUpdateCheck = millis();
|
_lastUpdateCheck = millis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String buffer;
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
// free JsonDocument as soon as possible
|
DynamicJsonDocument root(_responseSize);
|
||||||
{
|
if (Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||||
DynamicJsonDocument root(_responseSize);
|
|
||||||
JsonVariant var = root;
|
JsonVariant var = root;
|
||||||
generateJsonResponse(var);
|
generateJsonResponse(var);
|
||||||
serializeJson(root, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer) {
|
String buffer;
|
||||||
|
serializeJson(root, buffer);
|
||||||
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
if (Configuration.get().Security.AllowReadonly) {
|
||||||
_ws.setAuthentication("", "");
|
_ws.setAuthentication("", "");
|
||||||
} else {
|
} else {
|
||||||
@ -68,6 +68,8 @@ void WebApiWsBatteryLiveClass::loop()
|
|||||||
}
|
}
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/batterylivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/batterylivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/batterylivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +93,7 @@ void WebApiWsBatteryLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, _responseSize);
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, _responseSize);
|
||||||
auto& root = response->getRoot();
|
auto& root = response->getRoot();
|
||||||
generateJsonResponse(root);
|
generateJsonResponse(root);
|
||||||
@ -99,7 +102,9 @@ void WebApiWsBatteryLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/batterylivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/batterylivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
WebApi.sendTooManyRequests(request);
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/batterylivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
WebApi.sendTooManyRequests(request);
|
WebApi.sendTooManyRequests(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#include "AsyncJson.h"
|
#include "AsyncJson.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
#include "Utils.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include "PowerLimiter.h"
|
#include "PowerLimiter.h"
|
||||||
@ -55,16 +56,15 @@ void WebApiWsVedirectLiveClass::loop()
|
|||||||
if (millis() - _lastWsPublish > (10 * 1000) || lastDataAgeMillis > _dataAgeMillis) {
|
if (millis() - _lastWsPublish > (10 * 1000) || lastDataAgeMillis > _dataAgeMillis) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String buffer;
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
// free JsonDocument as soon as possible
|
DynamicJsonDocument root(_responseSize);
|
||||||
{
|
if (Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
|
||||||
DynamicJsonDocument root(_responseSize);
|
|
||||||
JsonVariant var = root;
|
JsonVariant var = root;
|
||||||
generateJsonResponse(var);
|
generateJsonResponse(var);
|
||||||
|
|
||||||
|
String buffer;
|
||||||
serializeJson(root, buffer);
|
serializeJson(root, buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer) {
|
|
||||||
if (Configuration.get().Security.AllowReadonly) {
|
if (Configuration.get().Security.AllowReadonly) {
|
||||||
_ws.setAuthentication("", "");
|
_ws.setAuthentication("", "");
|
||||||
} else {
|
} else {
|
||||||
@ -76,6 +76,8 @@ void WebApiWsVedirectLiveClass::loop()
|
|||||||
|
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/vedirectlivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/vedirectlivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/vedirectlivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastWsPublish = millis();
|
_lastWsPublish = millis();
|
||||||
@ -168,6 +170,7 @@ void WebApiWsVedirectLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, _responseSize);
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, _responseSize);
|
||||||
auto& root = response->getRoot();
|
auto& root = response->getRoot();
|
||||||
|
|
||||||
@ -177,8 +180,10 @@ void WebApiWsVedirectLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
} catch (std::bad_alloc& bad_alloc) {
|
} catch (std::bad_alloc& bad_alloc) {
|
||||||
MessageOutput.printf("Calling /api/livedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
MessageOutput.printf("Calling /api/vedirectlivedata/status has temporarily run out of resources. Reason: \"%s\".\r\n", bad_alloc.what());
|
||||||
|
WebApi.sendTooManyRequests(request);
|
||||||
|
} catch (const std::exception& exc) {
|
||||||
|
MessageOutput.printf("Unknown exception in /api/vedirectlivedata/status. Reason: \"%s\".\r\n", exc.what());
|
||||||
WebApi.sendTooManyRequests(request);
|
WebApi.sendTooManyRequests(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user