Description
Recently, when doing a deep dive into behavior in slow network environments, I can across the code in Updater.cpp that handles a timeout while an update is being streamed. Effectively, it will wait for 100ms after a timeout and then try once more. If this second attempt fails, the update fails. I would like to propose a change to this mechanism that makes the download succeed in even the slowest networks.
This change uses a call to millis() to track the start time, reseting this start time every time data is received. After 60 seconds of not receiving more data, it will timeout.
The new function is below with the new variable called "timeout":
size_t UpdaterClass::writeStream(Stream &data) {
size_t written = 0;
size_t toRead = 0;
if(hasError() || !isRunning())
return 0;
if(!_verifyHeader(data.peek())) {
#ifdef DEBUG_UPDATER
printError(DEBUG_UPDATER);
#endif
_reset();
return 0;
}
unsigned long timeout = millis();
if (_progress_callback) {
_progress_callback(0, _size);
}
if(_ledPin != -1) {
pinMode(_ledPin, OUTPUT);
}
while(remaining()) {
if(_ledPin != -1) {
digitalWrite(_ledPin, _ledOn); // Switch LED on
}
size_t bytesToRead = _bufferSize - _bufferLen;
if(bytesToRead > remaining()) {
bytesToRead = remaining();
}
toRead = data.readBytes(_buffer + _bufferLen, bytesToRead);
if(toRead == 0) { //Timeout
if (millis() - timeout > 60000) {
_currentAddress = (_startAddress + _size);
_setError(UPDATE_ERROR_STREAM);
_reset();
return written;
}
delay(100);
} else {
timeout = millis();
}
if(_ledPin != -1) {
digitalWrite(_ledPin, !_ledOn); // Switch LED off
}
_bufferLen += toRead;
if((_bufferLen == remaining() || _bufferLen == _bufferSize) && !_writeBuffer())
return written;
written += toRead;
if(_progress_callback) {
_progress_callback(progress(), _size);
}
yield();
}
if(_progress_callback) {
_progress_callback(progress(), _size);
}
return written;
}
Also, I read another thread recently with comments thanking you all for the incredible work you do on this project. One response was it is not common to get thanks, so here is another. THANK YOU!!