Skip to content

Commit bcb1098

Browse files
authored
Make StatefulService buffer size configurable (rjwats#118)
Introduce DEFAULT_BUFFER_SIZE for StatefulService related classes Add configurable buffer sizes for StatefulService related classes Remove redundant function from HttpEndpoint
1 parent 4fa491e commit bcb1098

File tree

5 files changed

+123
-81
lines changed

5 files changed

+123
-81
lines changed

lib/framework/FSPersistence.h

+14-15
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@
66
#include <JsonDeserializer.h>
77
#include <FS.h>
88

9-
#define MAX_FILE_SIZE 1024
10-
119
template <class T>
1210
class FSPersistence {
1311
public:
1412
FSPersistence(JsonSerializer<T> jsonSerializer,
1513
JsonDeserializer<T> jsonDeserializer,
1614
StatefulService<T>* statefulService,
1715
FS* fs,
18-
char const* filePath) :
16+
char const* filePath,
17+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
1918
_jsonSerializer(jsonSerializer),
2019
_jsonDeserializer(jsonDeserializer),
2120
_statefulService(statefulService),
2221
_fs(fs),
2322
_filePath(filePath),
23+
_bufferSize(bufferSize),
2424
_updateHandlerId(0) {
2525
enableUpdateHandler();
2626
}
@@ -29,15 +29,13 @@ class FSPersistence {
2929
File settingsFile = _fs->open(_filePath, "r");
3030

3131
if (settingsFile) {
32-
if (settingsFile.size() <= MAX_FILE_SIZE) {
33-
DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_FILE_SIZE);
34-
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
35-
if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()) {
36-
JsonObject jsonObject = jsonDocument.as<JsonObject>();
37-
_statefulService->updateWithoutPropagation(jsonObject, _jsonDeserializer);
38-
settingsFile.close();
39-
return;
40-
}
32+
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
33+
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
34+
if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()) {
35+
JsonObject jsonObject = jsonDocument.as<JsonObject>();
36+
_statefulService->updateWithoutPropagation(jsonObject, _jsonDeserializer);
37+
settingsFile.close();
38+
return;
4139
}
4240
settingsFile.close();
4341
}
@@ -49,7 +47,7 @@ class FSPersistence {
4947

5048
bool writeToFS() {
5149
// create and populate a new json object
52-
DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_FILE_SIZE);
50+
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
5351
JsonObject jsonObject = jsonDocument.to<JsonObject>();
5452
_statefulService->read(jsonObject, _jsonSerializer);
5553

@@ -84,15 +82,16 @@ class FSPersistence {
8482
JsonSerializer<T> _jsonSerializer;
8583
JsonDeserializer<T> _jsonDeserializer;
8684
StatefulService<T>* _statefulService;
87-
FS* _fs;
85+
FS* _fs;
8886
char const* _filePath;
87+
size_t _bufferSize;
8988
update_handler_id_t _updateHandlerId;
9089

9190
protected:
9291
// We assume the deserializer supplies sensible defaults if an empty object
9392
// is supplied, this virtual function allows that to be changed.
9493
virtual void applyDefaults() {
95-
DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_FILE_SIZE);
94+
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
9695
JsonObject jsonObject = jsonDocument.as<JsonObject>();
9796
_statefulService->updateWithoutPropagation(jsonObject, _jsonDeserializer);
9897
}

lib/framework/HttpEndpoint.h

+30-28
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <JsonSerializer.h>
1212
#include <JsonDeserializer.h>
1313

14-
#define MAX_CONTENT_LENGTH 1024
1514
#define HTTP_ENDPOINT_ORIGIN_ID "http"
1615

1716
template <class T>
@@ -22,8 +21,9 @@ class HttpGetEndpoint {
2221
AsyncWebServer* server,
2322
const String& servicePath,
2423
SecurityManager* securityManager,
25-
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN) :
26-
_jsonSerializer(jsonSerializer), _statefulService(statefulService) {
24+
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
25+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
26+
_jsonSerializer(jsonSerializer), _statefulService(statefulService), _bufferSize(bufferSize) {
2727
server->on(servicePath.c_str(),
2828
HTTP_GET,
2929
securityManager->wrapRequest(std::bind(&HttpGetEndpoint::fetchSettings, this, std::placeholders::_1),
@@ -33,17 +33,19 @@ class HttpGetEndpoint {
3333
HttpGetEndpoint(JsonSerializer<T> jsonSerializer,
3434
StatefulService<T>* statefulService,
3535
AsyncWebServer* server,
36-
const String& servicePath) :
37-
_jsonSerializer(jsonSerializer), _statefulService(statefulService) {
36+
const String& servicePath,
37+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
38+
_jsonSerializer(jsonSerializer), _statefulService(statefulService), _bufferSize(bufferSize) {
3839
server->on(servicePath.c_str(), HTTP_GET, std::bind(&HttpGetEndpoint::fetchSettings, this, std::placeholders::_1));
3940
}
4041

4142
protected:
4243
JsonSerializer<T> _jsonSerializer;
4344
StatefulService<T>* _statefulService;
45+
size_t _bufferSize;
4446

4547
void fetchSettings(AsyncWebServerRequest* request) {
46-
AsyncJsonResponse* response = new AsyncJsonResponse(false, MAX_CONTENT_LENGTH);
48+
AsyncJsonResponse* response = new AsyncJsonResponse(false, _bufferSize);
4749
JsonObject jsonObject = response->getRoot().to<JsonObject>();
4850
_statefulService->read(jsonObject, _jsonSerializer);
4951

@@ -61,32 +63,36 @@ class HttpPostEndpoint {
6163
AsyncWebServer* server,
6264
const String& servicePath,
6365
SecurityManager* securityManager,
64-
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN) :
66+
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
67+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
6568
_jsonSerializer(jsonSerializer),
6669
_jsonDeserializer(jsonDeserializer),
6770
_statefulService(statefulService),
6871
_updateHandler(
6972
servicePath,
7073
securityManager->wrapCallback(
7174
std::bind(&HttpPostEndpoint::updateSettings, this, std::placeholders::_1, std::placeholders::_2),
72-
authenticationPredicate)) {
75+
authenticationPredicate),
76+
bufferSize),
77+
_bufferSize(bufferSize) {
7378
_updateHandler.setMethod(HTTP_POST);
74-
_updateHandler.setMaxContentLength(MAX_CONTENT_LENGTH);
7579
server->addHandler(&_updateHandler);
7680
}
7781

7882
HttpPostEndpoint(JsonSerializer<T> jsonSerializer,
7983
JsonDeserializer<T> jsonDeserializer,
8084
StatefulService<T>* statefulService,
8185
AsyncWebServer* server,
82-
const String& servicePath) :
86+
const String& servicePath,
87+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
8388
_jsonSerializer(jsonSerializer),
8489
_jsonDeserializer(jsonDeserializer),
8590
_statefulService(statefulService),
8691
_updateHandler(servicePath,
87-
std::bind(&HttpPostEndpoint::updateSettings, this, std::placeholders::_1, std::placeholders::_2)) {
92+
std::bind(&HttpPostEndpoint::updateSettings, this, std::placeholders::_1, std::placeholders::_2),
93+
bufferSize),
94+
_bufferSize(bufferSize) {
8895
_updateHandler.setMethod(HTTP_POST);
89-
_updateHandler.setMaxContentLength(MAX_CONTENT_LENGTH);
9096
server->addHandler(&_updateHandler);
9197
}
9298

@@ -95,19 +101,11 @@ class HttpPostEndpoint {
95101
JsonDeserializer<T> _jsonDeserializer;
96102
StatefulService<T>* _statefulService;
97103
AsyncCallbackJsonWebHandler _updateHandler;
98-
99-
void fetchSettings(AsyncWebServerRequest* request) {
100-
AsyncJsonResponse* response = new AsyncJsonResponse(false, MAX_CONTENT_LENGTH);
101-
JsonObject jsonObject = response->getRoot().to<JsonObject>();
102-
_statefulService->read(jsonObject, _jsonSerializer);
103-
104-
response->setLength();
105-
request->send(response);
106-
}
104+
size_t _bufferSize;
107105

108106
void updateSettings(AsyncWebServerRequest* request, JsonVariant& json) {
109107
if (json.is<JsonObject>()) {
110-
AsyncJsonResponse* response = new AsyncJsonResponse(false, MAX_CONTENT_LENGTH);
108+
AsyncJsonResponse* response = new AsyncJsonResponse(false, _bufferSize);
111109

112110
// use callback to update the settings once the response is complete
113111
request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); });
@@ -138,29 +136,33 @@ class HttpEndpoint : public HttpGetEndpoint<T>, public HttpPostEndpoint<T> {
138136
AsyncWebServer* server,
139137
const String& servicePath,
140138
SecurityManager* securityManager,
141-
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN) :
139+
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
140+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
142141
HttpGetEndpoint<T>(jsonSerializer,
143142
statefulService,
144143
server,
145144
servicePath,
146145
securityManager,
147-
authenticationPredicate),
146+
authenticationPredicate,
147+
bufferSize),
148148
HttpPostEndpoint<T>(jsonSerializer,
149149
jsonDeserializer,
150150
statefulService,
151151
server,
152152
servicePath,
153153
securityManager,
154-
authenticationPredicate) {
154+
authenticationPredicate,
155+
bufferSize) {
155156
}
156157

157158
HttpEndpoint(JsonSerializer<T> jsonSerializer,
158159
JsonDeserializer<T> jsonDeserializer,
159160
StatefulService<T>* statefulService,
160161
AsyncWebServer* server,
161-
const String& servicePath) :
162-
HttpGetEndpoint<T>(jsonSerializer, statefulService, server, servicePath),
163-
HttpPostEndpoint<T>(jsonSerializer, jsonDeserializer, statefulService, server, servicePath) {
162+
const String& servicePath,
163+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
164+
HttpGetEndpoint<T>(jsonSerializer, statefulService, server, servicePath, bufferSize),
165+
HttpPostEndpoint<T>(jsonSerializer, jsonDeserializer, statefulService, server, servicePath, bufferSize) {
164166
}
165167
};
166168

lib/framework/MqttPubSub.h

+18-13
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
#include <JsonDeserializer.h>
77
#include <AsyncMqttClient.h>
88

9-
#define MAX_MESSAGE_SIZE 1024
109
#define MQTT_ORIGIN_ID "mqtt"
1110

1211
template <class T>
1312
class MqttConnector {
1413
protected:
1514
StatefulService<T>* _statefulService;
1615
AsyncMqttClient* _mqttClient;
16+
size_t _bufferSize;
1717

18-
MqttConnector(StatefulService<T>* statefulService, AsyncMqttClient* mqttClient) :
19-
_statefulService(statefulService), _mqttClient(mqttClient) {
18+
MqttConnector(StatefulService<T>* statefulService, AsyncMqttClient* mqttClient, size_t bufferSize) :
19+
_statefulService(statefulService), _mqttClient(mqttClient), _bufferSize(bufferSize) {
2020
_mqttClient->onConnect(std::bind(&MqttConnector::onConnect, this));
2121
}
2222

@@ -34,8 +34,9 @@ class MqttPub : virtual public MqttConnector<T> {
3434
MqttPub(JsonSerializer<T> jsonSerializer,
3535
StatefulService<T>* statefulService,
3636
AsyncMqttClient* mqttClient,
37-
const String& pubTopic = "") :
38-
MqttConnector<T>(statefulService, mqttClient), _jsonSerializer(jsonSerializer), _pubTopic(pubTopic) {
37+
const String& pubTopic = "",
38+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
39+
MqttConnector<T>(statefulService, mqttClient, bufferSize), _jsonSerializer(jsonSerializer), _pubTopic(pubTopic) {
3940
MqttConnector<T>::_statefulService->addUpdateHandler([&](const String& originId) { publish(); }, false);
4041
}
4142

@@ -56,7 +57,7 @@ class MqttPub : virtual public MqttConnector<T> {
5657
void publish() {
5758
if (_pubTopic.length() > 0 && MqttConnector<T>::_mqttClient->connected()) {
5859
// serialize to json doc
59-
DynamicJsonDocument json(MAX_MESSAGE_SIZE);
60+
DynamicJsonDocument json(MqttConnector<T>::_bufferSize);
6061
JsonObject jsonObject = json.to<JsonObject>();
6162
MqttConnector<T>::_statefulService->read(jsonObject, _jsonSerializer);
6263

@@ -76,8 +77,11 @@ class MqttSub : virtual public MqttConnector<T> {
7677
MqttSub(JsonDeserializer<T> jsonDeserializer,
7778
StatefulService<T>* statefulService,
7879
AsyncMqttClient* mqttClient,
79-
const String& subTopic = "") :
80-
MqttConnector<T>(statefulService, mqttClient), _jsonDeserializer(jsonDeserializer), _subTopic(subTopic) {
80+
const String& subTopic = "",
81+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
82+
MqttConnector<T>(statefulService, mqttClient, bufferSize),
83+
_jsonDeserializer(jsonDeserializer),
84+
_subTopic(subTopic) {
8185
MqttConnector<T>::_mqttClient->onMessage(std::bind(&MqttSub::onMqttMessage,
8286
this,
8387
std::placeholders::_1,
@@ -127,7 +131,7 @@ class MqttSub : virtual public MqttConnector<T> {
127131
}
128132

129133
// deserialize from string
130-
DynamicJsonDocument json(MAX_MESSAGE_SIZE);
134+
DynamicJsonDocument json(MqttConnector<T>::_bufferSize);
131135
DeserializationError error = deserializeJson(json, payload, len);
132136
if (!error && json.is<JsonObject>()) {
133137
JsonObject jsonObject = json.as<JsonObject>();
@@ -144,10 +148,11 @@ class MqttPubSub : public MqttPub<T>, public MqttSub<T> {
144148
StatefulService<T>* statefulService,
145149
AsyncMqttClient* mqttClient,
146150
const String& pubTopic = "",
147-
const String& subTopic = "") :
148-
MqttConnector<T>(statefulService, mqttClient),
149-
MqttPub<T>(jsonSerializer, statefulService, mqttClient, pubTopic),
150-
MqttSub<T>(jsonDeserializer, statefulService, mqttClient, subTopic) {
151+
const String& subTopic = "",
152+
size_t bufferSize = DEFAULT_BUFFER_SIZE) :
153+
MqttConnector<T>(statefulService, mqttClient, bufferSize),
154+
MqttPub<T>(jsonSerializer, statefulService, mqttClient, pubTopic, bufferSize),
155+
MqttSub<T>(jsonDeserializer, statefulService, mqttClient, subTopic, bufferSize) {
151156
}
152157

153158
public:

lib/framework/StatefulService.h

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
#include <freertos/semphr.h>
1313
#endif
1414

15+
#ifndef DEFAULT_BUFFER_SIZE
16+
#define DEFAULT_BUFFER_SIZE 1024
17+
#endif
18+
1519
typedef size_t update_handler_id_t;
1620
typedef std::function<void(const String& originId)> StateUpdateCallback;
1721

0 commit comments

Comments
 (0)