3 ms·
I don't think debuggers are superior than print statements or Jepsen. I work with multithreaded code and lock free data structures. I don't use a debugger. So
by samsquire 4y ago
I don't think debuggers are superior than print statements or Jepsen.
I work with multithreaded code and lock free data structures.
I don't use a debugger. So I rely on having a model in my head that could be wrong and what I plan to do is analyse logs after a test run. These are guaranteed interleavings that actually ran.
When you have 100 of threads and random interleavings your mental model is problem is necessarily different to thinking I'll reach to the debugger to tell me what the program is doing.
When you want serializability you need to design your system differently. I implemented multiversion concurrency control and use timestamps for correctness. I have yet to write a TLA model for it though.
https://github.com/samsquire/multiversion-concurrency-control/issues/4 https://github.com/samsquire/multiversion-concurrency-contro...
I also want to test my Raft implementation which isn't properly threaded. But I also need to test pathological cases such as old raft nodes coming back.
Most of the time you're reaching for the debugger is that you don't understand why your web framework got into such a state where something is null such as your Inversion of control Java container as the control flow is so complicated. It doesn't help with multithreaded programming.
- Agingcoder 4y agoThe 'design system differently' is a very good point, especially for distributed systems. Basically you have to build correctness and debuggability into the development process, and these are actually difficult problems on their own for these kind of systems.
- samsquire 4y agoI try to understand the reasoning of a concurrent system If two threads (or computers) can simultaneously be at any point in execution, you need to lay down some baselines for future execution. If the baseline is not met you need to Thread.yield or busy wait or busy wait and then park yourself for scheduling by the OS. So you need to wait until the system state is valid to modify - there is nobody else modifying state. I implemented the left right concurrency pattern but it causes duplication of data. One of my ideas is to combine it with arrays of structures and structures of arrays to at least benefit from the duplication of storage for parallelism. Once you got past that check, you do your work and then compare and swap and check that the world is still valid - there might have been someone else who was faster than you. I'm not an expert I am just interested in multithreading and scalability challenges. If there is multiple changes, such as a doubly linked list. I think you need multiple CAS and you need to update your guard to guard against that partial update too. How do you avoid a partial update being read? You could offload the check to a reader of the linked list to check if there is a partial update on that node. These problems are difficult to debug but you need accurate thread interleavings that you can sort into total order which is difficult as some things are going on at identical times. I've been reading Go scheduler sourcecode go/proc.go trying to understand how it multiplexes G goroutines onto threads M. Lots of locking going on! I am interested in bloom Lang too for distributed programming.