Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Search - "synchronisation"
-
A "support" guy my boss got in. I had told my boss numerous times, "Get rid of this guy, he's only wasting our time and money. And he's going to end up doing something where we will end up having to put out the fires."
Sure as a pair of nuts on a squirrel, this crazy bastard goes and DELETES a client's database. Yes folks, in fucking production. A live database. The heart of the business' transactions are... *poof*... GONE!!!
No backups for the day! No synchronisation beforehand! No nothing... just GONE!!! Fucking flat-lining!
Well, when I realised what he has done, I had to remove myself from the room before shit got outta hand!
I told the boss man that is the last straw and he needs to go...
The long and short of it...
- The client had luckily only lost about half a days data.
- I'm no longer at the company.
- This dumb fuck still is.18 -
Got the iPod and music synchronisation isn't working well with Linux (I've synced quite some iProducts and it always goes great so this is a new one for me).
Bought a windows pc a few days ago and haven't installed Linux onto it yet so booted it up, installed Firefox and then downloaded iTunes.
Nearly done with installing when an error message pops up and the entire fucker blue-screens. Now it doesn't boot anymore 😡
Go die in a fucking corner, windows.10 -
Okay, story time.
Back during 2016, I decided to do a little experiment to test the viability of multithreading in a JavaScript server stack, and I'm not talking about the Node.js way of queuing I/O on background threads, or about WebWorkers that box and convert your arguments to JSON and back during a simple call across two JS contexts.
I'm talking about JavaScript code running concurrently on all cores. I'm talking about replacing the god-awful single-threaded event loop of ECMAScript – the biggest bottleneck in software history – with an honest-to-god, lock-free thread-pool scheduler that executes JS code in parallel, on all cores.
I'm talking about concurrent access to shared mutable state – a big, rightfully-hated mess when done badly – in JavaScript.
This rant is about the many mistakes I made at the time, specifically the biggest – but not the first – of which: publishing some preliminary results very early on.
Every time I showed my work to a JavaScript developer, I'd get negative feedback. Like, unjustified hatred and immediate denial, or outright rejection of the entire concept. Some were even adamantly trying to discourage me from this project.
So I posted a sarcastic question to the Software Engineering Stack Exchange, which was originally worded differently to reflect my frustration, but was later edited by mods to be more serious.
You can see the responses for yourself here: https://goo.gl/poHKpK
Most of the serious answers were along the lines of "multithreading is hard". The top voted response started with this statement: "1) Multithreading is extremely hard, and unfortunately the way you've presented this idea so far implies you're severely underestimating how hard it is."
While I'll admit that my presentation was initially lacking, I later made an entire page to explain the synchronisation mechanism in place, and you can read more about it here, if you're interested:
http://nexusjs.com/architecture/
But what really shocked me was that I had never understood the mindset that all the naysayers adopted until I read that response.
Because the bottom-line of that entire response is an argument: an argument against change.
The average JavaScript developer doesn't want a multithreaded server platform for JavaScript because it means a change of the status quo.
And this is exactly why I started this project. I wanted a highly performant JavaScript platform for servers that's more suitable for real-time applications like transcoding, video streaming, and machine learning.
Nexus does not and will not hold your hand. It will not repeat Node's mistakes and give you nice ways to shoot yourself in the foot later, like `process.on('uncaughtException', ...)` for a catch-all global error handling solution.
No, an uncaught exception will be dealt with like any other self-respecting language: by not ignoring the problem and pretending it doesn't exist. If you write bad code, your program will crash, and you can't rectify a bug in your code by ignoring its presence entirely and using duct tape to scrape something together.
Back on the topic of multithreading, though. Multithreading is known to be hard, that's true. But how do you deal with a difficult solution? You simplify it and break it down, not just disregard it completely; because multithreading has its great advantages, too.
Like, how about we talk performance?
How about distributed algorithms that don't waste 40% of their computing power on agent communication and pointless overhead (like the serialisation/deserialisation of messages across the execution boundary for every single call)?
How about vertical scaling without forking the entire address space (and thus multiplying your application's memory consumption by the number of cores you wish to use)?
How about utilising logical CPUs to the fullest extent, and allowing them to execute JavaScript? Something that isn't even possible with the current model implemented by Node?
Some will say that the performance gains aren't worth the risk. That the possibility of race conditions and deadlocks aren't worth it.
That's the point of cooperative multithreading. It is a way to smartly work around these issues.
If you use promises, they will execute in parallel, to the best of the scheduler's abilities, and if you chain them then they will run consecutively as planned according to their dependency graph.
If your code doesn't access global variables or shared closure variables, or your promises only deal with their provided inputs without side-effects, then no contention will *ever* occur.
If you only read and never modify globals, no contention will ever occur.
Are you seeing the same trend I'm seeing?
Good JavaScript programming practices miraculously coincide with the best practices of thread-safety.
When someone says we shouldn't use multithreading because it's hard, do you know what I like to say to that?
"To multithread, you need a pair."18 -
So recently I did a lot of research into the internals of Computers and CPUs.
And i'd like to share a result of mine.
First of all, take some time to look at the code down below. You see two assembler codes and two command lines.
The Assembler code is designed to test how the instructions "enter" and "leave" compare to manually doing what they are shortened to.
Enter and leave create a new Stackframe: this means, that they create a new temporary stack. The stack is where local variables are put to by the compiler. On the right side, you can see how I create my own stack by using
push rbp
mov rbp, rsp
sub rsp, 0
(I won't get into details behind why that works).
Okay. Why is this even relevant?
Well: there is the assumption that enter and leave are very slow. This is due to raw numbers:
In some paper I saw ( I couldn't find the link, i'm sorry), enter was said to use up 12 CPU cycles, while the manual stacking would require 3 (push + mov + sub => 1 + 1 + 1).
When I compile an empty function, I get pretty much what you'd expect just from the raw numbers of CPU cycles.
HOWEVER, then I add the dummy code in the middle:
mov eax, 123
add eax, 123543
mov ebx, 234
div ebx
and magically - both sides have the same result.
Why????
For one thing, there is CPU prefetching. This is the CPU loading in ram before its done executing the current instruction (this is how anti-debugger code works, btw. Might make another rant on that). Then there is the fact that the CPU usually starts work on the next instruction while the current instruction is processing IFF the register currently involved isnt involved in the next instruction (that would cause a lot of synchronisation problems). Now notice, that the CPU can't do any of that when manually entering and leaving. It can only start doing the mov eax, 1234 while performing the sub rsp, 0.
----------------
NOW: notice that the code on the right didn't take any precautions like making sure that the stack is big enough. If you sub too much stack at once, the stack will be exhausted, thats what we call a stack overflow. enter implements checks for that, and emits an interrupt if there is a SO (take this with a grain of salt, I couldn't find a resource backing this up). There are another type of checks I don't fully get (stack level checks) so I'd rather not make a fool of myself by writing about them.
Because of all those reasons I think that compilers should start using enter and leave again.
========
This post showed very well that bare numbers can often mislead.21 -
OneDrive: where we duplicate your files instead of synchronizing them correctly because fuck that.5
-
While coding in C, I once forgot to add a semicolon at the end of a while loop polling a register value.
The logic required me to make it zero as soon as it read non-zero and continue the rest of the process. Hence the 'while' that missed the semicolon ended up being a single instruction assignment to the same volatile register that I kept polling. This caused synchronisation issue with the FPGA, and my code got stuck in an uncertain infinite loop.
Took me 2 days and a silly, yet valid question from my teammate to figure out the cause of this stupid bug.8 -
Thanks to @bittersweet I found and tried _Notes by Firefox_. An awesome app, wich I definitely will keep and use.
I love the markdown support.
I love the synchronisation.
I hope they will add access-controls, so I can give other users access to my notes.
Sry, for the advertisement.4 -
I guess you could say that my speciality is cloud at scale. I’d say it chose me more than I chose it.
Looking back on it though, I think what I like about my speciality is the unique challenges it brings.
Every speciality has its own set of challenges, like tight resource limits in embedded, or client-server synchronisation in native/mobile.
The challenge of cloud at scale is throughput. Designing systems that can support 100K users making a bazillion requests a second, or a data pipeline firing events that you need to process in near real time without dropping a single one.
The real challenge of course is doing all this within a sensible budget. We have virtually infinite compute but we dont have infinite dollars to spend on it.
Its a fun problem to solve.3 -
My work network AD password has to be changed every 90 days or so and it is really getting to me now. I'm beginning to run out of passwords to use and may soon have to resort to writing them down on a piece of paper and lock it somewhere.
I get why we need to change it often. What I don't like is the stupid validation rules AD uses to check passwords. It doesn't allow variations and you have to use something completely new.
I have only been in the job for about 8 months and I have had a nightmare experience updating my password recently as the synchronisation failed and I was locked out of my accounts for a day or 2 rendering my useless and having to call support for help.
How the he'll am I supposed to remember my passwords when I have to change them that often!!!18