This recent panel (Armstrong, Hewitt and Hoare) discussion on concurrency was the first time I got to know about him and it gave me a lot of food for thought.
Before we make a technology choice, we should be clear what those choices are. SQL is a query language and DynamoDB is a database. "NoSQL" technologies can be fronted with SQL interfaces. Relational databases can vary a lot too in their ACID compliance ("I" being the component with maximum variance).
The choice of technology should first be based on the problem and not whether it is serverless. Choosing DynamoDB when your application demands strict serializability would be totally wrong. I hope more people think about the semantic specifications of their applications (especially under concurrency).
Yes, and I think the quoted paragraph has so much more to do with coding around interfaces (behaviour) than with abstraction using non-exported package symbols.
Regarding single-letter variables, mathematical functions might be an exception. I think writing func gcd(a, b int) int {...} is better than other alternatives. There is simply no need to assign any more meaning to the arguments other than their type.
To make your comment useful [0], I would suggest explaining why and giving some context. For example, you could start with the size of your AWS infra, which other tools are you using other than CloudWatch etc.
The question is not suggesting a follow feature. It is just a hypothetical. The aim is to list great contributors on this platform, so that anyone looking at this thread can learn something new from their contributions.
Paging has nothing to do with this. When I say 1 MB thread stacks, it means the maximum size of that thread's stack in the virtual address space [0]. Each of these million threads could be using only a few KBs for its stack (out of that 1 MB of stack space). That would imply a few gigs of physical memory => no paging.
Nobody is suggesting that you create a million threads. But to think that it is not possible without TBs of physical memory is a fallacy (for 64-bit machines).
The thread switching costs itself could be prohibitive to performance. IIRC, goroutine switching cost is roughly 1/10th of linux thread switching costs.
Again, all this confusion is due to not being clear about virtual and physical memory. Every OS thread in linux does have a fixed virtual memory size (it is claimed when a thread is created, but this claim is on the virtual memory. This value is fixed at creation time). As you grow your program's conceptual stack in this virtual memory area, you would soon hit new pages of virtual memory, leading to page faults and linux allocating physical memory for you.
From a virtual memory standpoint, every thread would appear to have a fixed size which can be set when you create it. [0]
From a physical memory standpoint, every thread would appear to have a dynamic size (but bounded by the virtual memory size of course).
I think it is so important to not arbitrarily throw words like 'RAM' in such discussions, and use more unambiguous terminology such as - virtual address space and the resident set size (RSS).
On a 64-bit machine, with 1MB stack size (this is a claim on the virtual address space, not the physical memory), you can have millions of threads too (that you may hit a lower limit due to other OS level knobs is another matter).
Thanks for the perspective (especially for me, since Go is my primary language.)
Just to clarify, the primary target audience for the article is anyone who is getting started with asyncio (although I know of people who have been using asyncio, but don't really understand whats going on).
This recent panel (Armstrong, Hewitt and Hoare) discussion on concurrency was the first time I got to know about him and it gave me a lot of food for thought.