AboutMagical processor fairy; part-time misanthropic bane of idiots. 🧚♀️🏹 Ergo sum miseriae
SkillsRuby ❤, js/es6, css, react, sql. VB and PHP can die in a fire; .NET can go, too.
LocationDying on the altar of lunacy.
Joined devRant on 2/25/2017
Do all the things like ++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatarSign Up
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple APILearn More
Up for a rollercoaster?
I had a super motivated day where i could focus and wanted to get my work done. My stupid work lappy instead kept throwing tantrums and totally prevented me from working. (Everything caused disk thrashing, took multiple minutes instead of seconds, etc.) Total shit day, but I felt great.
Next morning, I woke up all achy and cold. Ignored it and went to work. I was able to fix everything, and got my benchmarks running smoothly in all of fifteen minutes. Got good results, too! Left work and got married at the courthouse. :)
Went to a restaurant afterward, and two jolly fat guys (Off-duty Santa?!) bought us lunch.
Got home and… started feeling really awful. A little while later, I had a 102*f fever. Collapsed on the floor with an electric blanket and was absolutely miserable. Just kind of stared for hours, aching everywhere. Eventually went to bed, and my wife (!) made me all warm and comfy. And then I proceeded to be completely unable to sleep. Or move. Or think. Laid there for four hours unable to move, and shaking violently at any touch of cold air.
Now it’s 1am and I’m here at the freezing kitchen table writing this.
I am miserable.
But still happy, too!
I’m surrounded by idiots.
I’m continually reminded of that fact, but today I found something that really drives that point home.
Gather ‘round, everybody, it’s story time!
While working on a slow query ticket, I perused the code, finding several causes, and decided to run git blame on the files to see what dummy authored the mental diarrhea currently befouling my screen. As it turns out, the entire feature was written by mister legendary Apple golden boy “Finder’s Keeper” dev himself.
To give you the full scope of this mess, let me start at the frontend and work my way backward.
This function allows the user to better see the rows in the API Calls table, for which there is a also search feature — the very thing I’m tasked with fixing.
It’s worth noting that above the search feature are two inputs for a date range, with some helpful links like “last week” and “last month” … and “All”. It’s also worth noting that this table is for displaying search results of all the API requests and their responses for a given merchant… this table is enormous.
This search field for this table queries the backend on every character the user types. There’s no debouncing, no submit event, etc., so it triggers on every keystroke. The actual request runs through a layer of abstraction to parse out and log the user-entered date range, figure out where the request came from, and to map out some column names or add additional ones. It also does some hard to follow (and amazingly not injectable) orm condition building. It’s a mess of functional ugly.
The important columns in the table this query ultimately searches are not indexed, despite it only looking for “create_order” records — the largest of twenty-some types in the table. It also uses partial text matching (again: on. every. single. keystroke.) across two varchar(255)s that only ever hold <16 chars — and of which users only ever care about one at a time. After all of this, it filters the results based on some uncommented regexes, and worst of all: instead of fetching only one page’s worth of results like you’d expect, it fetches all of them at once and then discards what isn’t included by the paginator. So not only is this a guaranteed full table scan with partial text matching for every query (over millions to hundreds of millions of records), it’s that same full table scan for every single keystroke while the user types, and all but 25 records (user-selectable) get discarded — and then requeried when the user looks at the next page of results.
What the bloody fucking hell? I’d swear this idiot is an intern, but his code does (amazingly) actually work.
No wonder this search field nearly crashed one of the servers when someone actually tried using it.
While writing up this quarter's performance review, I re-read last quarter's goals, and found one my boss edited and added a minimum to: "Release more features that customers want and enjoy using, prioritized by product; minimum 4 product feature/bug tickets this quarter."
... they then proceeded to give me, not four+ product tickets, but: three security tickets (two of which are big projects), a frontend ticket that should have been assigned to the designer, and a slow query performance ticket -- on top of my existing security tickets from Q3.
How the fuck was I supposed to meet this requirement if I wasn't given any product tickets? What, finish the monster tickets in a week instead of a month or more each and beg for new product tickets from the product manager who refuses to even talk to me?
Fuck these people, seriously.8
Hey @Root! I know you won't have time to finish Ticket A before holiday vacation, so work on Ticket B instead.
I finished Ticket A in time. except for converting/fixing some horrible spaghetti monstrosity. More or less: "we overwrote this gem's middleware and now it calls back into our codebase under specific circumstances, and then calls the gem again, which calls the middleware again." Wtf? It's an atrocity against rationality.
The second day after vacation:
Hey @Root, drop Ticket B and work on Ticket C instead. Can you knock this out quick, like before friday? ... Uh, sure. It looks easy.
And in somewhere between 13 (now 5) minutes and two hours from now, I'm going to have a 1:1 with my boss to discuss the week. Having finished almost all of Ticket A won't matter because it's not a "recent priority" -- despite it being a priority before, and a lot of work. I've made no progress on Ticket B due to interruptions (and a total and complete lack of caring because I'm burned out and quite literally can no longer care), and no progress on ticket C because... it's all horribly broken and therefore not quick. I assigned it to Mr. Frontend, which I'll probably get chewed out for.
So, my 1:1 with bossmang today is going to be awful. And the worst part of all: I'm out of rum! Which means sobriety in the face of adversity! :<
but like, wtf. Just give me a ticket and let me work on it until it's done. Stop changing the damn priorities every other freaking day!17
It’s one-on-one time yet again this week!
I have a 1:1 with my boss every Thursday from 11:30am to 12:00 noon. They often run 45 minutes instead of the planned 30.
Why do I have these? I complained that I have too many meetings, and that it’s hard to get my work done around them (especially while burned out). So as a remedy he scheduled a weekly meeting, every Thursday, so he can make sure I’m getting enough work done. Totally makes sense, right?
And every Thursday he’s 15-25 minutes late. And because they always run long, I lose a full hour or more of time I could have used to get my work done. See the problem?
Today he was 36 minutes late.
Seriously, how disrespectful can he be?25
Hey. I have some steam keys I don't want, and I don't really have any friends to give them away to, so. Here you go!
I'll post them in the comments below.
Only redeem them if you actually want the game, and if you've used one please comment or upvote to let others know! Be kind, don't be greedy, honor system, etc. etc.27
Short but absolutely needed.
My time tracker shows I’ve had mental breakdowns for 29% of my tracked hours this month. I think it’s time to mail them some mistletoe taped to some manure.
(Yes, I’m searching for somewhere else. When I’m able.)16
This stupid crap is pissing me off.
I write a quick blob of code that performs an http request with custom headers and writes the response to a file. easy squeezy. Everything works.
I abstract it into a class and add request building and stages (enjoayble!), and have one method make the response, read its body, and write to a file. I literally copy/pasted most of my existing code into the method and indented it. The only changes were updating var names to instance vars.
But now? It's complaining something is trying to read the request body twice, and it's throwing a fit. What? How? You were just working!
WHY THE FUCK DOES MY BOSS HAVE ME MOCKING FUCKING RECAPTCHA API RESPONSES? IT'S SO FUCKING STUPID
I CAN'T MOCK THE RECAPTCHA JS METHODS SO I HAVE TO MAKE VALID-LOOKING JSON RESPONSES AND I DON'T HAVE A FUCKING CLUE HOW ANY OF IT FUCKING WORKS
THIS IS THE STUPIDEST THING ANYONE HAS EVER ASKED OF ME (okay, it isn't, but it's pretty damned close.) AND IT'S DURING MY BLOODY PERFORMANCE REVIEW.40
I copy a line from one spec (to create a user) and paste it in another spec. It works just dandy in the first, and throws MySQL missing column errors in the other.
This codebase is full of shit like this. Things work in one place but not another, and it’s never obvious why. Tens of thousands of gotchas and quirks. The only way I can get an answer to things like these is to either beg my boss for an explanation, which I’m sure he’s long since tired of, or spend a full day (or more) wading through several rabbit holes filled with raw sewage.
I wasted two hours today trying to get a simple fucking factory to work. And you know what? I just gave up and used the existing admin user. Yeah it’s a bad idea, but it’s fucking good enough.
They can yell if they want.
I have no cares left.15
Yesterday's (scheduled and adhoc) meetings:
Today's (scheduled) meetings:
Tomorrow's meetings include a 1:1 with my boss who will invariably ask why I'm not done on this "should take a week" project that I've had for a week, despite that he just unblocked me on yesterday morning, and I've had nothing but meetings since...
They fill my day with shit spaced out just enough to waste practically my entire freaking day so I can't get anything done, conveniently forget this, and then have the audacity to yell at me for not finishing my tickets. Of course I didn't finish! You all were too busy blabbing at me every day for the past fucking week! (Oh, and do they listen if I have something to say? Of course they fucking don't.)
Also, as a secondary rant, the product douchebag files tickets (usually complex as hell tickets worded to appear trivial) with enough missing information to make missing large sections of them easy. If I ask him for clarification, he tells me to read the ticket, and if I insist, he gets all exasperated and quickly zooms through the site faster than I can follow, shows maybe half of what's in the ticket, and asks why I don't know how to do any of this yet. After I finish his shit ticket (and true to his douchebag nature) he blames me for missing several of those pieces he never outlined or showed, and insists that I obviously don't test anything. And because that's clearly not douchey enough, the fucking sack of shit also goes behind my back and trashtalks me to my coworkers, tells them he can't trust me to do a simple fucking thing, and that he's given up on me.
What the FUCK is wrong with these people?28
I’m conducting a train.
For testing, I tell the train to go to station C when someone requests station G. But when I request station G afterwards, it sends me to station H instead.
I never asked for this.6
Every time I interact with this DBA he treats me like I’m some fucking moron who barely knows what a query is. It doesn’t help that I can’t get him to understand a damned fucking thing, no matter what the topic is. We speak the same language, supposedly, but can barely communicate. I can’t even begin describe how his half of the conversations go because I am unable to follow much of it.
Maybe if I start aligning my fucking chakras and channeling my inner goddamn cosmic peace energy, or whatever it is he’s on about, he might start making more sense? I swear he’s been so high so often that he’s never quite come down.
There’s obviously a language barrier, somehow, but the guy is also such a douche every freaking time. Ugh.16
YELLED AT FOR 45 FUCKING MINUTES OVER OTHER PEOPLE’S FUCKUPS
IF YOU PIECES OF SHIT WANT ME TO DO SOMETHING, FUCKING SAY IT. WRITE IT THE FUCK DOWN IN THE FUCKING TICKET.
AND IF YOU WANT A FUCKING DEMO, SCHEDULE THE FUCKING THING, AND STOP FUCKING CANCELING THEM. DON’T BLAME ME WHEN IT’S YOUR FUCKING FINGER ON THE FUCKING CANCEL BUTTON EVERY. FUCKING. WEEK.
AND SERIOUSLY, DON’T FUCKING EXPECT ME TO DROP MY LAST FUCKING TICKET THE AFTERNOON BEFORE VACATION FOR SOME LOW-PRIOIRTY CRAP BECAUSE SUDDENLY IT’S ALL THE RAGE INSIDE YOUR TINY DUMBASS HEAD. BUT OH BOO FUCKING HOO, @ROOT DIDN’T DO WHAT I ASKED WHEN I WAS BEING A FUCKING MORON! GO FUCK YOURSELF YOU FUCKING STUCK-UP IDIOT
AND FUCK BOZO THE CLOWN BOSS FOR BLAMING ME FOR THE FUCKING IDIOT’S BRUISED FUCKING EGO
FUCK THE LOT OF YOU40
Had a meeting with my boss earlier. Got yelled at for:
a) Working on a high-priority, externally-committed ticket (digit separators) that i was 85% done with on the Friday afternoon before my vacation instead of jumping to a lower-priority screwdriver ticket that just came in. Even though my boss agreed with me that what I did was exactly what I should have done, it's still bad because I was apparently rude to product by not doing as they asked?
b) Taking too long on that digit separator ticket that amounts to following a gigantic mess of convoluted spaghetti and making a few small changes, and making sure it doesn't break the world because it's all so fucking convoluted and fragile as hell. Let's not even mention my 4-10 hours of mandatory useless meetings every week.
c) Missing something that wasn't even listed in that same ticket -- somehow my fault? -- so I very obviously didn't test my work. Even though specs all passed and QA also tested and signed off on it as working and complete. Clearly half-assed and untested. Product keeps promising/planning UATs and then skipping them, and then has the audacity to complain about it.
d) Not recovering fast enough from burnout and daily mental breakdowns. I can still barely get out of bed and you want me to be super productive? Got it. Guess what? I'm being amazingly productive for my mental health. But my boss, Mr. Happy-go-lucky, thinks depression is dropping your icecream cone on your clean kitchen table, and this three-ton pile of spaghetti is "maybe a little messy, I guess."
So I need to somehow "regain the confidence" of both him and product because I'm taking awhile on difficult tickets (surprise), while having these ridiculous breakdowns (surprise), and because I don't fix things that aren't even listed in the fucking tickets (fucking surprise) -- and worse, that the lack of information is somehow entirely. my. fault. (surprise fucking surprise)
GOD I HATE THESE PEOPLE.18
Product: Hey, this screwdriver feature I never requested isn’t there. Why? Can you fix it? It’s kinda urgent.
Product: @Root please jump on the ticket above … fairly urgent.
Root: It’s Friday, I’m out next week, and I’m working on finishing <urgent comma ticket> right now.
Boss: Work on the screwdriver instead. But make sure you finish the comma ticket too!
Boss: By the way, I volunteered you for eight security reviews next month!
Security: You’re on call for AWS audits next month, too!10
Seven hours of meetings this week, and every. single. one. of them could have been an email.
How can they expect me to get anything done when all I’m doing is listening to them drone on and on and …
And of course this shouldn’t affect the deadlines. No siree! But can I work during them? Not a chance! … Totally do anyway …5
I fix one display, and another breaks.
Now I’m getting “$$1002.99” and can’t figure out why. Where is this popup coming from? Where does the encrypted URL point to? What does this ajax call do? Where does the amount go? When does it change? Why is it a string now? Where does the total get defined? How far down the rabbit hole do I need to go?
Short short version:
I found something to try fixing. I made some changes, forced a crash to inspect, and… Joy! My log stopped updating. How long have I been debugging on stale data?
Skipping a long debugging session…
I discover a suspect instance var in a suspect method, and… i have no freaking clue where it’s being defined. It’s used in the class, but never defined in it. Oh, and the name is pretty generic, so searching for it is even more fun.
WHO WRITES THIS CRAP?!
AND WHY DO PEOPLE CALL THEM “LEGENDS”? Like, really. That’s the word they use. “Legends.” I still can’t believe it.8
I’m adding some fucking commas.
It should be trivial, right?
They’re fucking commas. Displayed on a fucking webpage. So fucking hard.
What the fuck is this even? Specifically, what fucking looney morons can write something so fucking complicated it requires following the code path through ten fucking files to see where something gets fucking defined!?
There are seriously so fucking many layers of abstraction that I can’t even tell where the bloody fucking amount transforms from a currency into a string. I’m digging so deep in the codebase now that any change here will break countless other areas. There’s no excuse for this shit.
I have two options:
A) I convert the resulting magically conjured string into a currency again (and of course lose the actual currency, e.g. usd, peso, etc.), or
B) Refactor the code to actually pass around the currency like it’s fucking intended to be, and convert to a string only when displaying. Like it’s fucking intended to be.
Impossible decision here.
If I pick (A) I get yelled at because it’s bloody wrong. “it’s already for display” they’ll say. Except it isn’t. And on top of that, the “legendary” devs who wrote this monstrosity just assumed the currency will always be in USD. If I’m the last person to touch this, I take the blame. Doesn’t matter that “legendary Mr. Apple dev” wrote it this way. (How do I know? It’s not the first time this shit has happened.) So invariably it’ll be up to me to fix anyway.
But if I pick (B) and fix it now, I’ll get yelled at for refactoring their wonderful code, for making this into too big of a problem (again), and for taking on something that’s “just too much for me.” Assholes. My après Taco Bell bathroom experiences look and smell better than this codebase. But seriously, only those two “legendary” devs get to do any real refactoring or make any architecture decisions — despite many of them being horribly flawed. No one else is even close to qualified… and “qualified” apparently means circle jerking it in Silicon Valley with the other better-than-everyone snobs, bragging about themselves and about one another. MojoJojo. “It was terrible, but it fucking worked! It fucking worked!” And “I can’t believe <blah> wanted to fix that thing. No way, this is a piece of history!” Go fuck yourselves.
So sorry I don’t fit in your stupid club.
Oh, and as an pointed, close-at-hand example of their wonderful code? This API call I’m adding commas to (it’s only used by the frontend) uses a json instance variable to store the total, errors, displayed versions of fees/charges (yes they differ because of course they do), etc. … except that variable isn’t even defined anywhere in the class. It’s defined three. fucking. abstraction. layers. in. THREE! AND. That wonderful piece of smelly garbage they’re so proud of can situationally modify all of the other related instance variables like the various charges and fees, so I can’t just keep the original currency around, or even expect the types to remain the same. It’s global variable hell all over again.
Such fucking wonderful code.
I fucking hate this codebase and I hate this fucking company. And I fucking. hate. them.9
I’m trying to add digit separators to a few amount fields. There’s actually three tickets to do this in various places, and I’m working on the last of them.
I had a nightmare debugging session earlier where literally everything would 404 unless I navigated through the site in a very roundabout way. I never did figure out the cause, but I found a viable workaround. Basically: the house doesn’t exist if you use the front door, but it’s fine if you go through the garden gate, around the back, and crawl in through the side window. After hours of debugging I eventually discovered that if I unlocked the front door with a different key, everything was fine… but nobody else has this problem?
Onto the problem at hand!
I’m trying to add digit separators to some values. I found a way to navigate to the page in question (more difficult than it sounds), and … I don’t know what view is rendering the page. Or what controller. Or how it generates its text.
The URL is encrypted, so I get no clues there. (Which was lead dev’s solution to having scrapeable IDs instead of just, you know, fixing them). The encryption also happens in middleware, so it’s a nightmare to work through. And it’s by the lead dev, so the code is fucking atrocious.
The view… could be one of many, and I don’t even know where they are. Or what layout. Or what partials go into building it.
All of the text on the page are “resources” — think named translations that support plus nested macros. I don’t know their names, and the bits of text I can search for are used fucking everywhere. “Confirmation number” (the most unique of them) turns up 79 matches. “Fee” showed up in 8310 places before my editor gave up looking. Really.
The table displaying the data, which is what I actually care about, isn’t built in JS or markup, but is likely a resource that goes through heavy processing. It gets generated in a controller somewhere (I don’t know the resource name so I can’t find it), and passed through several layers of “dynamic form” abstraction, eventually turned into markup, and rendered as a partial template. At least, that’s how it worked in the previous ticket. I found a resource that looks right, and there’s only the one. I found the nested macros it uses for the amount and total, and added the separators there… only to find that it doesn’t work.
Fucking dead end.
And i have absolutely nothing else to go on.
Page title? “Show”
Text? All from macros with unknown names. Can’t really search for it without considerable effort.
Table? Doesn’t work.
Text in the table? doesn’t turn up anything new.
Legal agreement? There are multiple, used in many places, generates them dynamically via (of course) resources, and even looking through the method usages, doesn’t narrow it down very much.
What the fuck?
Why does this need to be so fucking complicated?
And what genius decided “$100000.00” doesn’t need separators? Right, the lot of them because separators aren’t used ANYWHERE but in code I authored. Like, really? This is fintech. You’d think they would be ubiquitous.
And the sheer amount of abstraction?
Stupid stupid stupid stupid stupid.11
🎶 Fixing production issues 🎶
🎶 Fixing production issues 🎶
🎶 In other people’s code! 🎶
Seriously, how am I still in a good mood when I have to deal with this?14
Literally just a sidebar.
And yes, this was in Hell.
Its code was spread across at least 40 files, and it used a bunch of freaking global variables to unfurl accordion sections, hide other sections/items, highlight the active item, etc. These were set (and unset!) in controller actions, so if you didn’t unset one, it remained open and highlighted until another action unset it.
Some of the global variable checks (and permissions checks) were done in the individual views, some outside of the `render` statements that include them. Some of them inherited variables from the parent, some from the controller, some from globals. Getting a view to work was trial and error. Oh, and some had their own inline css, some used css classes.
Subsections were separate views, so were some individual items, both sometimes rendered using shared templates, and all of the views and templates had the exact. same. filename. (They were located in different directories, and thus located automagically via implicit relative paths.) So, it was a virtually endless parade of`render partial => “sidebar”`. Which file does that point to? Good luck figuring it out!
Also, comments in several places said adding a new section required a database migration. I never did figure out why.
Anyway, I discovered this because I had an innocuous-sounding ticket to rearrange the sidebar, group some sections/items under different permissions, move some items to another menu, and nest some others differently.
It took me two bloody weeks, and this was when I was extremely productive every day.
Afterward, I was so disgusted by it that I took a day and removed every trace of the sidebar I could find, and rewrote it. I defined the sidebar in a hash, and wrote a simple recursive builder to generate the markup. It supported optional icons, n-level nesting, automatic highlighting of the current item and all parent nodes, compound and inherited permissions, wrapping of long names, hover and unfurl animations, etc. Took me a couple hundred lines of Ruby at the most, plus about the same of css.
Felt so good to remove that blight.5
Back in Hell, we had a “company summit” where everyone flew in for an all hands meeting.
It was three days long in a tiny office with very lacking air conditioning in the middle of a Las Vegas summer. Basically the entire thing was the CEO / goblin salesman king chewing at us and expounding about / proselytizing his latest and greatest sales ideas and how they’ll change the world. And randomly asking “which of you are HUNGRY?! Which of you want to be FILTHY FUCKING RICH?!” etc.
One good thing came out of it, which was that any and all new endeavors needed a “co-signer” and a sign off from development before we (developers, or more accurate: just me) would work on it. It reduced the growth rate of my backlog by like 80%, which was nice.
While dreading the “summit,” I hated him more than I had in quite awhile.
During the summit, I hated him more and even flipped him off.
After the summit, I swore to leave the revolting wreckage that was the company.
(And months later, I did just that —after becoming the sole dev and the only person holding the damned company afloat. When I gave him my two weeks’ notice, I absolutely relished his terror. And my time spent writing my 43 page no-sugarcoat handoff document that was guaranteed to scare off any hapless dev he might find. 😇)
But I digress, three 10-hour days with him and the rest of the sales team, the sleazy lawyer, the CTO who mentally checked out years ago, the yes-man contractor, and me. The only good thing that came out of that meeting was one good idea that he dismissed, and the sign off idea that saved my backlog a bit.
One of the sales people quit shortly thereafter. So it was a huge expense that wasted everyone’s time and added absolutely nothing of value to the company. GG!
Oh, it was also in the “totally better” office — meaning… cheaper, unfinished (literally plywood floors), and was one room in another company’s office, who often locked the door leading to their offices because they trusted him so much. But it was in downtown Las Vegas, with no parking at all, where gang members were hanging out almost every day, and it was next to low-income housing and weird no-service restaurants with shockingly high prices.
Weird and scary.
Totally carried pepper spray every time Mr. Goblin asshole forced me to go into the office. Didn’t get raped, though, or my laptop or car stolen. So that was nice.5
Best: the tool that works for the job.
Worst: the tool that doesn’t.
Example: Ruby is great for scripts and web dev, but simply doesn’t work for graphics engines.
Example: SQL is great for fetching data (etc.), but it is absolutely terrible for business logic.
Example: XSLT is great for lowering your faith and your will to live, but it is absolutely awful for literally every other purpose.22