diff --git a/CHANGELOG.md b/CHANGELOG.md index 956341c..057a923 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog ## unreleased ### Features -### Fixes + - [167](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/167) - Added `InfluxDBClient::writeRecord(const char *record)`. + - [167](https://github.com/tobiasschuerg/InfluxDB-Client-for-Arduino/pull/167) - Added possibility to disable retrying by setting `maxRetryAttempts` to zero: `client.setWriteOptions(WriteOptions().maxRetryAttempts(0));` ## 3.9.0 [2021-09-17] ### Features diff --git a/src/InfluxDbClient.cpp b/src/InfluxDbClient.cpp index 0b36ef9..53feb6b 100644 --- a/src/InfluxDbClient.cpp +++ b/src/InfluxDbClient.cpp @@ -294,7 +294,7 @@ bool InfluxDBClient::writePoint(Point & point) { return false; } -bool InfluxDBClient::Batch::append(String &line) { +bool InfluxDBClient::Batch::append(const char *line) { if(pointer == _size) { //overwriting, clean buffer for(int i=0;i< _size; i++) { @@ -330,6 +330,10 @@ char * InfluxDBClient::Batch::createData() { } bool InfluxDBClient::writeRecord(String &record) { + return writeRecord(record.c_str()); +} + +bool InfluxDBClient::writeRecord(const char *record) { if(!_writeBuffer[_bufferPointer]) { _writeBuffer[_bufferPointer] = new Batch(_writeOptions._batchSize); } @@ -411,7 +415,7 @@ bool InfluxDBClient::flushBufferInternal(bool flashOnlyFull) { int statusCode = postData(data); delete [] data; // retry on unsuccessfull connection or retryable status codes - bool retry = statusCode < 0 || statusCode >= 429; + bool retry = (statusCode < 0 || statusCode >= 429) && _writeOptions._maxRetryAttempts > 0; success = statusCode >= 200 && statusCode < 300; // advance even on message failure x e <300;429) if(success || !retry) { diff --git a/src/InfluxDbClient.h b/src/InfluxDbClient.h index 341df71..b1acd0d 100644 --- a/src/InfluxDbClient.h +++ b/src/InfluxDbClient.h @@ -123,6 +123,7 @@ class InfluxDBClient { // Writes record in InfluxDB line protocol format to write buffer. // Returns true if successful, false in case of any error bool writeRecord(String &record); + bool writeRecord(const char *record); // Writes record represented by Point to buffer // Returns true if successful, false in case of any error bool writePoint(Point& point); @@ -172,7 +173,7 @@ class InfluxDBClient { uint8_t retryCount = 0; Batch(int size):_size(size) { buffer = new String[size]; } ~Batch() { delete [] buffer; } - bool append(String &line); + bool append(const char *line); char *createData(); bool isFull() const { return pointer == _size; diff --git a/test/Test.cpp b/test/Test.cpp index 5a33b94..c83dd74 100644 --- a/test/Test.cpp +++ b/test/Test.cpp @@ -68,6 +68,7 @@ void Test::run() { testTimestamp(); testRetryOnFailedConnection(); testRetryOnFailedConnectionWithFlush(); + testNonRetry(); testBufferOverwriteBatchsize1(); testBufferOverwriteBatchsize5(); testServerTempDownBatchsize5(); @@ -566,7 +567,7 @@ void Test::testRepeatedInit() { } while(0); uint32_t endRAM = ESP.getFreeHeap(); long diff = endRAM-startRAM; - TEST_ASSERTM(diff>-100,String(diff)); + TEST_ASSERTM(diff>-300,String(diff)); TEST_END(); } @@ -2121,6 +2122,60 @@ void Test::testFlushing() { deleteAll(Test::apiUrl); } +#define WS_DEBUG_RAM(text) { Serial.printf_P(PSTR(text ": free_heap %d, max_alloc_heap %d, heap_fragmentation %d\n"), ESP.getFreeHeap(), ESP.getMaxFreeBlockSize(), ESP.getHeapFragmentation()); } + + +void Test::testNonRetry() { + TEST_INIT("testNonRetry"); + const char *lines[] = { + "device_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng free_heap=16568i,max_alloc_heap=11336i,heap_fragmentation=29i,uptime=28821.23,wifi_disconnects=0i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=location state=3i,before_mem_free=36232i,before_mem_max_free_block=17544i,before_mem_framentation=49i,after_mem_free=35792i,after_mem_max_free_block=17544i,after_mem_framentation=48i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=clock state=2i,before_mem_free=16704i,before_mem_max_free_block=11336i,before_mem_framentation=30i,after_mem_free=16704i,after_mem_max_free_block=11336i,after_mem_framentation=30i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=update state=0i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=astronomy state=2i,before_mem_free=16376i,before_mem_max_free_block=11336i,before_mem_framentation=28i,after_mem_free=16376i,after_mem_max_free_block=11336i,after_mem_framentation=28i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=current_weather state=2i,before_mem_free=16728i,before_mem_max_free_block=11336i,before_mem_framentation=30i,after_mem_free=16376i,after_mem_max_free_block=11336i,after_mem_framentation=28i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=forecast state=2i,before_mem_free=16704i,before_mem_max_free_block=11336i,before_mem_framentation=30i,after_mem_free=16376i,after_mem_max_free_block=11336i,after_mem_framentation=28i", + "service_status,clientId=WS-E09806011111,Device=WS-ESP8266,Version=0.58-rc3,Location=Prague\\,CZ,WiFi=Bonitoo-ng,service=iot_center state=0i", + }; + WriteOptions wo; + WS_DEBUG_RAM("Before inst"); + InfluxDBClient *client = new InfluxDBClient(Test::apiUrl, Test::orgName, Test::bucketName, Test::token); + WS_DEBUG_RAM("after inst"); + + //TEST not keeping batch for retry + Serial.println("Stop server"); + TEST_ASSERT(waitServer(Test::managementUrl, false)); + client->setHTTPOptions(HTTPOptions().httpReadTimeout(500)); + TEST_ASSERT(!client->validateConnection()); + // Disable retry + wo.maxRetryAttempts(0); + client->setWriteOptions(wo); + client->setHTTPOptions(HTTPOptions().connectionReuse(true)); + TEST_ASSERT(!client->writeRecord(lines[0])); + TEST_ASSERT(!client->_writeBuffer[0]); + + TEST_ASSERT(waitServer(Test::managementUrl, true)); + TEST_ASSERT(client->validateConnection()); + + uint8_t size = sizeof(lines)/sizeof(lines[0]); + uint16_t batchSize = size +1; + wo.batchSize(batchSize).bufferSize(batchSize); + client->setWriteOptions(wo); + + WS_DEBUG_RAM("Before"); + for(int i=0;iwriteRecord(lines[i]), client->getLastErrorMessage()); + WS_DEBUG_RAM("After write Line"); + } + TEST_ASSERTM(client->flushBuffer(), client->getLastErrorMessage()); + WS_DEBUG_RAM("After flush"); + delete client; + WS_DEBUG_RAM("After delete"); + TEST_END(); + deleteAll(Test::apiUrl); +} + + void Test::setServerUrl(InfluxDBClient &client, String serverUrl) { client._connInfo.serverUrl = serverUrl; client._service->_apiURL = serverUrl + "/api/v2/"; diff --git a/test/Test.h b/test/Test.h index a051f5a..0c1e0dd 100644 --- a/test/Test.h +++ b/test/Test.h @@ -71,6 +71,7 @@ class Test : public TestBase { static void testIsValidID(); static void testBuckets(); static void testFlushing(); + static void testNonRetry(); }; #endif //_TEST_H_ \ No newline at end of file