xsharp.eu • RuntimeState and asynchronous tasks
Page 1 of 1

RuntimeState and asynchronous tasks

Posted: Fri Jan 19, 2024 12:08 pm
by leon-ts
Hi,
Currently, the RuntimeState class uses the ThreadLocal class to store values. This is fine for classic multi-threaded programming based on Thread classes, but causes problems in the more modern style based on asynchronous tasks (Task class, async, await). The problem is that asynchronous tasks are abstract from threads and use a pool of background threads under the hood. One task can start in one thread and end in another (resuming the task in a free thread from the pool). This leads to the fact that RuntimeState can return different values for the same task, which leads to errors in the application logic. To support asynchronous tasks, a good choice of value store for RuntimeState would be the AsyncLocal class. At the same time, the logic of its operation is also suitable for classical threads. Thus, there is a proposal to the X# development team to replace the storage class in RuntimeState with AsyncLocal instead of ThreadLocal. But not for all values. For example, it is better to leave the list of workareas as is on ThreadLocal (each thread has its own isolated list of workareas). Because existing user algorithms can be guided by this feature.

This is just my suggestion, so I wonder what other colleagues think about it.

One example where the problem described above may occur:
1. Thread #1 (the main application thread) set the working directory using the SetDefault function.
2. Thread #1 (the main application thread) starts the asynchronous task 'TaskA', which is executed in the background thread #2. This task gets the correct SetDefault value from RuntimeState.
3. The asynchronous task 'TaskA' has completed its work.
4. Thread #1 (the main application thread) changed the working directory using the SetDefault function.
5. Thread #1 (the main application thread) starts a new asynchronous task 'TaskB' (or even the same task TaskA, it doesn't matter), for which a free thread was automatically selected from the thread pool, and it turned out to be the same background thread #2. TaskB receives an incorrect SetDefault value from RuntimeState, which was set in step 1. And the expected value was set in step 4.

Re: RuntimeState and asynchronous tasks

Posted: Sat Jan 20, 2024 8:14 pm
by robert
Leonid,
I have no experience with AsyncLocal.
I am sure you have looked at our runtime state.
I need to give this some thought.
The Workareas list is linked to the fact that the RuntimeState is allocated per thread. It calls GetInstance() to get the current instance.
If we make the state asynclocal then we need some other mechanism to keep track of RDDs per thread.

Robert

Re: RuntimeState and asynchronous tasks

Posted: Sun Jan 21, 2024 8:36 am
by leon-ts
Robert,
robert wrote: Sat Jan 20, 2024 8:14 pm The Workareas list is linked to the fact that the RuntimeState is allocated per thread. It calls GetInstance() to get the current instance.
If we make the state asynclocal then we need some other mechanism to keep track of RDDs per thread.
No changes are expected to the Workareas property. I mentioned it here:
leon-ts wrote: Fri Jan 19, 2024 12:08 pm But not for all values. For example, it is better to leave the list of workareas as is on ThreadLocal (each thread has its own isolated list of workareas). Because existing user algorithms can be guided by this feature.
Because even SQL connections (DBConnection) must be bound to a specific thread.

It is intended to implement two storage variables in RuntimeState. One will be based on the AsyncLocal class, which will have all the properties except Workareas. The second storage variable will be based on the ThreadLocal class, which will serve the Workareas property.