node-red-nodes
node-red-nodes copied to clipboard
node-red-node-tail potentially stops working after deferred re-init took place (node.tout = setTimeout...) and with filename by input in use
note: the bug was found by code review and confirmed by observed behavior, see text below questions and aswers:
Which node are you reporting an issue on?
node-red-node-tail
What are the steps to reproduce?
-
create inject node with filename member
-
attach a tail node without filname preconfigured
-
listen to output with debug node
-
inject non-existing file, tail node will run into deferred re-init after 10 seconds with a timeout (node.tout = setTimeout...)
-
this will potentially be repeated every 10 seconds untill "wrong" file is corrected
-
inject existing (or any again non-existing) filename, tail node will stop doing anything and will never again start any tail
What happens?
because the code line "if (!node.tout) { fileTail(); }" never reaches "fileTail();" because node.tout is never cleared again after it was assigned a value
What do you expect to happen?
- tail will happily pick up tailing a new different file whenever a new filename is injected no matter if a previous timeout was scheduled anytime before.
Please tell us about your environment:
- Node-RED version: RedMatic Version 7.2.1 / node red 1.2.9
- node.js version: ? but claimed to be irrelevant
- npm version: ? but claimed to be irrelevant
- Platform/OS: RaspberryMatic (rpi 3B)
- Browser: irrelevant
notes:
the bug came to my mind when i was reading 28-tail.js out of couriosity. a common ideom is when developers use the setTimeout return value to detect if a timeout is pending whithout clearing its value. but no matter what the implementation returns, its value is never changed of course when the scheduled function fires by itself. so the condition
(!!node.tout)
becomes never false again after it was set the first time, no matter if the timeout is still pending or not.
to make the variable reflecting the condition if a call is currently pending or not if must be manually cleared
- when the function fires (could be done in fileTail function body at the beginning)
- whenever (after!) the timeout is cleared
i use the node to tail a rolling log file. that logfile is renamed and moved away and replaced by a new file with the old name when rolling happens. i use a dynamic filname because the thing is configurable. i also have implemented error catching and detection if a rolling process is currently ongoing or strinking in the middle of tailing to restart tailing on the new file after rolling was completed.
"strangely" the tail node pretty often just quits working completely.
i suspect that the conditions of th log file rolling include the possibility that for some moments the file is not found at all for short moments. whenever that happens and the node used the setTimeout backed retry, any new filenames or any stopping and restarting the tail will lead into a "dead" tail node.
i can come up with a pull request to fix that after i have been testing my fix
Yes please to a PR.