TaskScheduler tasks with limited lifespans #597
Draft
+80
−83
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
@tbnobody This might have information that could be helpful to the upstream project and I would appreciate your opinion on this matter.
This is an attempt to use TaskScheduler tasks with a particular interval. In general, this works. In this case, the
BatteryClass
MQTT publish task works as expected: It is executed in the expected interval.I would really like to extend this approach to all classes that need to execute work regularly. In particular, this would allow for simplifications based on the knowledge that a particular function is executed at a particular interval. See the changes in the
JkBms::Controller
class, where a sender and receiver task are supposed to be used and where the receiver task is only enabled when needed, allowing for a better overall approach to tackle some of the problems that arise if the loop task was executed with high frequency.Unfortunately, the
JkBms::Controller
tasks don't even execute once. I don't yet understand why that is. The difference here is that the task instances are constructed "dynamically", i.e., once the main loop is executing. The idea is that only the specific battery provider that is needed is constructed at all, and some may need no task, another needs one, another needs two.What I do understand is that even though I made @tbnobody define
_TASK_THREAD_SAFE
for the TaskScheduler library, the whole library is really not at all thread-safe. This is something that I realized after I actually looked at the code. In particular, adding a task to the scheduler while a scheduler pass is active is simply unsupported. Adding does not lead to serious problems, I guess, but deleting a task whose instance then is freed definitely does: There is no guarantee whatsoever that TaskScheduler does not try to load/execute a task in the chain that was previously deleted. If the task was also freed, this leads to a memory access violation:I am confident that the whole TaskScheduler is not made to handle task objects with limited lifespan. And that is very disappointing.
Ideas:
std::shared_ptr
and once there is only once reference (in the DynamicTaskScheduler), the task ist deleted from the chain and is freed.Assessment:
Thank you very much if you made it through this wall of text 🙈 @helgeerbe What's your feeling about this? The changeset of this PR might give you an idea of the potential that I am talking about.