Open BigBIueWhale opened 10 months ago
Thank you for your comprehensive feedback and for identifying the critical issues in the current implementation of the library. Your insights into the problems with blocking, the misuse of Mutex over extended periods, and the async nature of the API are invaluable.
I've taken your advice seriously and have committed to redesigning the API to be event-based, as you suggested. This approach should mitigate the race conditions and blocking issues inherent in the previous design. I've pushed the initial changes to a new branch called development
.
I would be honored if you could join the development process. Your expertise would greatly benefit the project, especially as we navigate through these significant changes. I'm particularly interested in your thoughts on the modified code.
Additionally, I'm currently facing a challenge with the test_scan_complex_folder
function, which is taking much longer than expected. Any insights or suggestions you might have on addressing this issue would be deeply appreciated.
You can find the development
branch here: [https://github.com/AviadCohen24/RustDirectorySniffer/tree/development]. Please feel free to share your thoughts, criticisms, and suggestions. Your collaboration would not only help enhance the quality of the library but also accelerate the development process.
Looking forward to potentially working together.
As it currently stands, it's impossible to use the API of this library as a user without encountering race conditions or even without blocking. This is due to both implementation flaws and design flaws at the API level.
Does get_directory_map block? Should say in the README.
This doesn't make sense:
given that
guard
isn't released until the end of the scope (which in this case is the end of the function). Here's a solution to that problem: Fix Rust Lock ScopeThere's also a similar issue at
scan_directory_async
. Because of these lines:the directory_map will be locked until the end of the thread execution.
This means that in the current implementation:
scan_directory_async
spawns a thread that locksdirectory_map
throughout this thread's entire execution.get_directory_map
acquires thedirectory_map
lock, therefore blocking until thescan_directory_async
thread is done.Another issue is that it's bad practice to rely on Mutex for long blocking preriods- it's not efficient. Better to use Mutex in conjunction with Condvar (equivalent of std::condition_variable).
Here's a basic overview of how you use a
Condvar
in Rust:Create a
Condvar
and aMutex
: First, you need to create a condition variable and a mutex. The mutex is used to provide safe access to the shared state.Lock the Mutex: To access the shared state, a thread must first lock the mutex.
Wait on the Condition Variable: If the condition you're waiting for is not met, you call
wait
orwait_timeout
on the condition variable. This call will block the current thread until another thread signals on the condition variable. While waiting, the mutex is atomically released.Signal the Condition Variable: Another thread can signal the condition variable to wake one or all waiting threads. This is typically done after modifying the shared state in such a way that the condition might now be true.
Re-acquire the Mutex: When a thread is woken up, it automatically re-acquires the mutex lock before
wait
returns.Condition variables represent the ability to block a thread such that it consumes no CPU time while waiting for an event to occur.
Altogether, I see 3 issues in the current implementation that have to do with the async nature of this library:
get_directory_map
is blocking, so this is not an async APIscan_directory_async
and then quickly callsget_directory_map
, the thread::spawn might not be done yet, and therefore the previous scan (an old scan, or an empty directory map) will be returned.My solution would be to redesign your API to be event-based (which is a challenge when dealing with cross-language and cross-runtime).