4 ms·
I disagree with you and here's why; Opinions of mine were made after trying both Redis and Node.js and finding them in poor state. You can read about Redis's p
by mdomans 10y ago
I disagree with you and here's why;
Opinions of mine were made after trying both Redis and Node.js and finding them in poor state. You can read about Redis's problems here: http://redis.io/topics/latency http://redis.io/topics/latency and here http://redis.io/topics/transactions http://redis.io/topics/transactions
Node.js is better in regard to handling high load. And the concept of having the heavy lifting happening mostly away from programmer is very sensible. I only find the implementation lacking and there seem to be a fair amount of people now migrating away from Node.js
In regard to your point about two programs running "concurrently" - that's actually multitasking, a feature of OS, not the programming language. And if your OS doesn't support that, you can't write a web browser that will make the email client work concurrently.
Concurrency only means that two different things seem to be happening at once.
Cooperative multitasking and cooperative concurrency are two different things. Cooperative multitasking means that if your browser is poorly written and blocks - your whole machine blocks.
On the other hand cooperative concurrency is a paradigm under which if your coroutine blocks, your program blocks.
The argument between whether to choose threads or coroutines is an argument whether it is better to have blocking or race conditions.
So, having traversed "why I'm wrong", let's consider if there are better models.
Arguably the best language in the class of highly concurrent ones is Erlang. Erlang for years dominated the space of stable concurrency.
And how it works? Message passing. You can still deadlock Erlang program - it's just much harder.
Another good example I like is Grand Central Dispatch and it's OS version libdispatch.
The whole point there is to have blocks or operations that, and this is guaranteed by the programmer, mutate the state of memory in an atomic way.
Both of those examples are really about having a queue of changes and applying them. And you could, quite sensibly, argue that a mutex is nothing more internally than an ordered queue, so why bother.
Well, my problem is really with the API language gives to the programmer. The point I'm trying to make is that concerning the programmer with how his work is executed is wrong.
If we can avoid locks inside Python interpreter, and we can, by having a different syntax to describe what needs to happen, I'd consider it a much better solution.
It's much easier to say: "drive me to the Station" than to drive there.
- btilly 10y agoI am not sure what your trying involved. However I have found use cases that both Redis and Node.js were great for. And I'm well aware of how to make both suck. Every programming tool has limitations. Use them within the right domains, and they are likely to work well. Use them for something they are poorly suited to, and your experience is likely to be horrible. That is why Redis talks honestly about what the potential problems and strengths are. Those aren't problems in the right use case, but they are things you need to know to help figure out if you have the right use case. Moving on, cooperative multitasking is a form of cooperative concurrency. It has all of the same strengths and weaknesses as cooperative concurrency in any other setting. Hence a single badly coded network call could freeze up Mac OS 9, or Win 3.1. That said if every application is coded correctly, then you can do a lot of things concurrently. I remember using email, Usenet and a browser at the same time on Mac OS 9, and it worked fine..most of the time. Once the system gets complex enough, the fact that any mistake can lock everything becomes unacceptable. This is why operating systems do not generally use cooperative multitasking. An individual application may reasonably choose to go either way. But as they get more complex, there is pressure to go preemptive. Moving on, you only have half the story for Erlang. Erlang uses message passing AND immutable memory. The fact that you can't modify memory in place is a huge limitation on the programmer. However it also eliminates large classes of race conditions. If Python made all data immutable, it could also get rid of most of the uses of the GIL. For a less extreme approach, look at Go. In Go data is mutable. But by convention, you pass objects around using channels, and only one goroutine owns an object at a time. Since only the owner accesses it, that eliminates most race conditions. However if you violate the convention, a Go program dump can dump core very quickly!
- mdomans 10y agoEventually we come to a point where I agree with you, almost. One exception is Redis/Node.js - I don't like them because they indeed work in certain cases, but that set is much less than what authors of Redis/Node.js advertise. I very fondly, for example, remember antirez being adamant that Redis is awesome as cache, yet it took me 10minutes to prove that single Redis performs worse than single Memcached. And no, I don't consider answer: run more Redis instances valid. You design software to have features that solve problems, not replace old with new. And yes, Erlang uses message passing and has locks and immutable memory. I prefer the Go approach of mutating through channels/queues. Both Go and GCD in C/ObjC are good examples of this approach.