My skepticism of CSP is not that it's slow, slow alone could be fine. Tokio is slow for some things.
My issue is that it pretends things are simple when they're not, and it doesn't encourage the programmer to really think about "what if I start action x and then I'm interrupted by message y?"
And this isn't incompatible with CSP, you'd just have to embed an event loop in each process and never block it. So then you may as well use one loop and dedicated worker threads.
Like I think a common pitfall for novices (I certainly have done this) is thinking of the happy path and then just writing that into a thread.
Worst case, say it's a self-driving car. When I see a green light and there's nothing in my way, I'm gonna hit the accelerator and move 50 feet through the intersection. Lovely.
I write that into a thread and then a senior asks me what if a pedestrian enters while my thread is holding the accelerator. I forgot that I have to re-check for obstacles every frame. Oops. (Contrived, I know)
I think I'm an okay programmer. I think I'm even okay at concurrency.
I just have to ask myself on every line, can this fail? And can it take more than a couple microseconds?
Hashing data for instance is predictable. If I'm swapping and the os faults in memory, that's out of my scope. Hashing can't fail and always finishes in some number of cycles.
Parsing can fail.
File reads can fail and take time. The disk is a shared resource with its own controller, in every sense a read is actually a network call.
So if CSP means someone will hide long-running operations by accident, I don't think it's helpful
Good point, cancelling concurrent actions that started another concurrent actions is extremely complicated. I don't think humans can solve it efficiently in real life. There is usually a mess left behind if plans are reverted or changed significantly.
I have some fun habits to "idiot-proof" things. If I'm paying for something with my credit card, I keep my wallet out until my card is back in it. If I'm cooking something on the stove, the kitchen light and the exhaust fan must be on.
So at any moment, if my wallet is out, I know I must think about my card before I put my wallet back in my purse. And if the kitchen light is on or I hear the fan, I must check the stove regularly.
I have a couple friends who constantly lose phones or wallets, and I simply don't.
It's not intuitive to program but what's worked for me in software is, simply do _everything_ on every tick, and make sure the loop always ticks. Anything you can't do in tick, has to be made into an async task somehow and monitored every frame. Even up to a thousand tasks, "Is this still running? Should I stop it? Should I start it?" is a very cheap question to ask. I believe this is how some embedded folks code, like for a furnace controller.
A lot of multi-threading and TOCTOU vulns also seem to come down to "What if just one thread of yours froze for 60 seconds between any two atomic operations?" If I do something like create a file and then set permissions on it, it feels like it's fast. But actually, an attacker only needs one time slice where the permissions are wrong to get in. Luckily I don't work in security, so I just do my best.
My issue is that it pretends things are simple when they're not, and it doesn't encourage the programmer to really think about "what if I start action x and then I'm interrupted by message y?"
And this isn't incompatible with CSP, you'd just have to embed an event loop in each process and never block it. So then you may as well use one loop and dedicated worker threads.
Like I think a common pitfall for novices (I certainly have done this) is thinking of the happy path and then just writing that into a thread.
Worst case, say it's a self-driving car. When I see a green light and there's nothing in my way, I'm gonna hit the accelerator and move 50 feet through the intersection. Lovely.
I write that into a thread and then a senior asks me what if a pedestrian enters while my thread is holding the accelerator. I forgot that I have to re-check for obstacles every frame. Oops. (Contrived, I know)
I think I'm an okay programmer. I think I'm even okay at concurrency.
I just have to ask myself on every line, can this fail? And can it take more than a couple microseconds?
Hashing data for instance is predictable. If I'm swapping and the os faults in memory, that's out of my scope. Hashing can't fail and always finishes in some number of cycles.
Parsing can fail.
File reads can fail and take time. The disk is a shared resource with its own controller, in every sense a read is actually a network call.
So if CSP means someone will hide long-running operations by accident, I don't think it's helpful