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 - "wk228"
-
Something that I'm utterly ashamed of.
Had to add text message and call communication functionality in one of the products.
Boss shrunk the deadline to two days ETA.
Didn't know jackshit about twilio.
Meeting with client:
Client - So the communication thing is done right?
Me - Yyeahhh
Client - Let's try it then. *Calls himself*
Me - *Calls the API directly from my phone*
Client got out happy. Nobody knows what actually happened there. I didn't even talk to my colleagues about this. Boss gave me bonus to pull of the impossible. I added the feature after a week of the incident.8 -
i work on a music streaming app.
bug: playlist description shows there are X songs inside. But when you go inside it says there are Y songs in the list. the list actually containing Y songs.
hack: when a user goes in, cache Y and display it outside in the description next time.
result: user sees X songs in playlist description, goes in playlist and sees Y songs. goes back to check why it said X before but now it doesnt say X anymore coz we cached Y and display that in the description from now on so the user assumes they are imagining things17 -
Waaaay too many but let's go with this one for now.
At my previous job there was a web application which was generating about 1gb of log data a second. Server was full and the 'fullstack engineers' we called had zero clue about backend stuff and couldn't fix it.
Me and another engineer worked our asses off to figure this out but eventually the logging stopped and it went back to normal.
Great, right?
For that moment. I was the on-call server engineer and at like 3am I got called awake because this shit was happening again.
Sleep drunk with my phone I ssh'd into the server, not sure about what to do at first but then suddenly: let's chattr the goddamn log file...
$ chattr +i /var/log/logfile
Bam, worked, done, back to sleep.
(this comment + param marks the file in a way that it can only be read until the mark is removed, so you can't write to it or move it or remove it or whatever)13 -
The solution for this one isn't nearly as amusing as the journey.
I was working for one of the largest retailers in NA as an architect. Said retailer had over a thousand big box stores, IT maintenance budget of $200M/year. The kind of place that just reeks of waste and mismanagement at every level.
They had installed a system to distribute training and instructional videos to every store, as well as recorded daily broadcasts to all store employees as a way of reducing management time spend with employees in the morning. This system had cost a cool 400M USD, not including labor and upgrades for round 1. Round 2 was another 100M to add a storage buffer to each store because they'd failed to account for the fact that their internet connections at the store and the outbound pipe from the DC wasn't capable of running the public facing e-commerce and streaming all the video data to every store in realtime. Typical massive enterprise clusterfuck.
Then security gets involved. Each device at stores had a different address on a private megawan. The stores didn't generally phone home, home phoned them as an access control measure; stores calling the DC was verboten. This presented an obvious problem for the video system because it needed to pull updates.
The brilliant Infosys resources had a bright idea to solve this problem:
- Treat each device IP as an access key for that device (avg 15 per store per store).
- Verify the request ip, then issue a redirect with ANOTHER ip unique to that device that the firewall would ingress only to the video subnet
- Do it all with the F5
A few months later, the networking team comes back and announces that after months of work and 10s of people years they can't implement the solution because iRules have a size limit and they would need more than 60,000 lines or 15,000 rules to implement it. Sad trombones all around.
Then, a wild DBA appears, steps up to the plate and says he can solve the problem with the power of ORACLE! Few months later he comes back with some absolutely batshit solution that stored the individual octets of an IPV4, multiple nested queries to the same table to emulate subnet masking through some temp table spanning voodoo. Time to complete: 2-4 minutes per request. He too eventually gives up the fight, sort of, in that backhanded way DBAs tend to do everything. I wish I would have paid more attention to that abortion because the rationale and its mechanics were just staggeringly rube goldberg and should have been documented for posterity.
So I catch wind of this sitting in a CAB meeting. I hear them talking about how there's "no way to solve this problem, it's too complex, we're going to need a lot more databases to handle this." I tune in and gather all it really needs to do, since the ingress firewall is handling the origin IP checks, is convert the request IP to video ingress IP, 302 and call it a day.
While they're all grandstanding and pontificating, I fire up visual studio and:
- write a method that encodes the incoming request IP into a single uint32
- write an http module that keeps an in-memory dictionary of uint32,string for the request, response, converts the request ip and 302s the call with blackhole support
- convert all the mappings in the spreadsheet attached to the meetings into a csv, dump to disk
- write a wpf application to allow for easily managing the IP database in the short term
- deploy the solution one of our stage boxes
- add a TODO to eventually move this to a database
All this took about 5 minutes. I interrupt their conversation to ask them to retarget their test to the port I exposed on the stage box. Then watch them stare in stunned silence as the crow grows cold.
According to a friend who still works there, that code is still running in production on a single node to this day. And still running on the same static file database.
#TheValueOfEngineers2 -
That would probably be implementing multithreading in shell scripts.
https://gitlab.com/netikras/bthread
The idea (though not the project itself) was born back when I still was a sysadmin. Maintaining 30k servers 24/7 was quite something for a team of merely ~14 people. That includes 1st line support as well.
So I built a script to automate most of my BAU chores. You could feed a list of servers - tens or hundreds or more - and execute the same action on each of them (actions could be custom or predefined in the list of templates). Neither Puppet nor Chef or Ansible or anything of sorts was consistently deployed in that zoo, not to mention the corp processes made use of those tools even a slower approach than the manual one, so I needed my own solution.
The problem was the timing. I needed all those commands to execute on all the servers. However, as you might expect, some servers could be frozen, others could be in DMZ, some could be long decommed (and not removed from the listings), etc. And these buggars would cause my solution to freeze for longer than I'd like. Not to mention that running something like `sar -q 1 10` on 200 servers is quite time-consuming itself :)
And how do I get that output neatly and consistently (not something you'd easily get with moving the task to a background with '&'. And even with that you would not know when are all the iterations complete!)?
So many challenges...
I started building the threading solution that would
- execute all the tasks in parallel
- do not write anything to disks
- assign a title to each of the tasks
- wait for all the tasks to complete in either
> the same sequence as started
> as soon as the task finishes
- keep track of each task's
> return code
> output
> command
> sequence ID
> title
- execute post-finish actions (e.g. print to the console) for each of the tasks -- all the tracked properties are to be accessible by the post-finish actions.
The biggest challenges were:
a) how do I collect all that output without trashing my filesystems?
b) how do I synchronize all those tasks
c) how do I make the inception possible (threads creating threads that create their own threads and so on).
Took me some time, but I finally got there and created the libbthread library. It utilizes file descriptors, subshells and some piping magic to concentrate the output while keeping track of all the tasks' properties. I now use it extensively in my new tools - the ones where I can't use already existing tools and can't use higher-level languages.4 -
I wanted to play Pirates under DOS back then, but it didn't have the left-handed mouse button switch like Windows.
So I opened the mouse, scratched the PCB button lines away, soldered wires cross-over, and had a left-handed mouse also under DOS.3 -
I wanted to be able to physically start a home computer remotely.
- raspberry pi
- power relay to simulate the button
- a messenger chatbot linked to my account only
Now my local server is startable from anywhere7 -
I had a response body that I needed to obtain data from. It would either come as {success: {name, id}} or {success: [{name, id},{name,id}]}
I couldn't loop over something that wasn't a list and I couldn't just ask the type of the element in success so in my infinite wisdom I split the cases by examining the length of the element in success. If it had one it was an array and could be looped over, if it didn't, it was a single object to be processed 😂 if it works it works (it's still in production, tyvm)4 -
One of my first projects involved a python server. This was before I even knew about CD/CI, so we were updating by ssh-ing in, pulling, and killing the process.
My solution? Make an endpoint that pulls the repo and intentionally crashes the server to restart it. We used it for two years.1 -
If point-and-click game made in PowerPoint, that my grandma actively played because of boredom, is "creative hacky solution", then there you have it.
First game is "The Adventures of Sayid", second "Hide and Seek" with creepy pasta sound and graphic assets from Shrek: Activity Center.
Well, that's my childhood without Internet, what I can say!3 -
cat > /dev/null
I use it to take notes during meetings, they are temporary in the terminal so I am forced to polish them afterwards2 -
in 2017 i published my first website. it was basically a remake of google's translation telephone, because google shut it down. unfortunately, the translation api costs money, so rather than pay, i set up a gscript api endpoint that translates it for me.
apparently when you use gscript, translation is free. this was back when i was 14, which is crazy to think about. -
I have multiple contenders ;)
Contender one:
A program used to sort emails.
We was in the process of moving from lotus notes to exchange and needed a way route emails to the right server internally.
Solution, a qmail to receive all emails, a script running by cron every minute to read the emails, check the recipient name to a list and resending to the right server. The script was written in php :P since that was the only way we at the time had to read an email into an object, it was run just like any other shell script :D
Contender two:
A multi threaded mail sender that fetch email addresses and content from a database and posted them through qmail using background execution and pipes to get the result back and then update the database, written in bash script.
Contender three:
A c program used in a similar way as in one but this time using dial up and uucp to fetch email and then drop these either into lotus notes or into a bbs for our customers to give them an email address. This was around 1993, so not to many isp’s offered email and not to many had internet anyway, dial up bbs was much more common.5 -
The university I used to study CSE, they had some OLD computers with Windows XP in them. Also, all those computers had TWO user accounts. One with the admin access and another one with normal access. Until this, it was fine.
But the browsers installed there were so old, even normal website struggles to load properly. and so many outdated apps, kept bugging us for update, but every time we click on UPDATE, they ask for the admin password, which we didn't have. So, most of the students were frustrated about this, but nobody took any action! :/
So, I hacked one of the computers' admin password. the password was "BRIGHT". I'm like, these people are never gonna set different passwords in different computers and remember them for eternity. Definitely all passwords have to be the same, and they were! Which saved my time.
So, I shared the password with everyone in my class and now they can install any apps they want. Which made me so happy!
But You know, words travel fast! Just one day after the hacking incident, the Seniors ( & the juniors ) came to me with their laptops to find their forgotten password, which made me earn some money & eat some delicious foods, also got to meet some beautiful girls of our campus ^_^
& I used to go to other classes to hack those Admin passwords for fun ^_^ But I never told them the password until they pay me or feed me something delicious! ^_^
I miss those good old days! ^_^6 -
Hacking company product with reverse engineering ang bytecode instrumentation.
The project I had to write integration test for was really not meant/written for testing. I ended up bytecode instrumenting an internal library to intercept the needed states and results. -
I used a 8 years old phone as a Wi-Fi adapter for my new computer, while I got the cable.
Not the hackiest thing ever but the hackiest I can think of now.2 -
There are a few email addresses on my domain that I keep on receiving spam on, because I shared them on forums or whatever and crawlers picked it up.
I run Postfix for a mail server in a catch-all configuration. For whatever reason in this setup blacklisting email addresses doesn't work, and given Postfix' complexity I gave up after a few days. Instead I wrote a little bash script called "unspam" to log into the mail server, grep all the emails in the mail directory for those particular email addresses, and move whatever comes up to the .Junk directory.
On SSD it seems reasonably fast, and ZFS caching sure helps a lot too (although limited to 1GB memory max). It could've been a lot slower than it currently is. But I'm not exactly proud of myself for doing that. But hey it works!1 -
Apart of the fact that WordPress itself is one big hack, my most creative hacky solution was making it (dev) environment friendly.
First, I created a DB pull and push tool in NodeJS (on TypeScript). Then, because WP is so clever and stores internal URLs in full length in the DB, I had to create a DB migrator (find & replace) and attached it to the DB pull task.
After this, of course WP still has its config in one file, so I used composer to install phpdotenv and filled the config with environment variables.
Bundled with some good ol' Gitlab CI/CD magic, the website is now 10% sanely developable.
It feels like having to shovel piles of shit, but with a golden shovel. Everything stinks as hell but at least there is a tiny bling to it, temporarily.
But in all seriousness: WordPress is a god damn fucking pile of tumors!3 -
Needed texts to call-duty with the gist of the incident. Implemented, works.
PM wants to also ring the phone, cause text may not wake them up.
Me, telling him, that his tools don’t allow me to call him. However, I said, I could send the text as a fax msg, which would end up “ringing” mr call-duties phone, and then fax-Morse-beep the msg to him.
PM was ok w/ that.2 -
Didn't find a proper API to send chat messages to an MSTeams channel.
Didn't want to rely on third party tools.
Creates webhook endpoint, promptly creates my own API using JSON cards and requests to said endpoint.
Didn't know how why it worked but it did.2 -
While competing on typing speed with a friend I'd wait for him to finish and edit the wpm value on the html before sending him a screenshot of _my speed_. He rage quit after we got till 120 lol2
-
I've ranted about this before, but here we go again:
Go Plugins.
I was racking my brains trying to figure out how one could possibly implement plugins easily in Go.
I had a look at using RPC, which requires far to much boilerplate to be realistic. I looked at using Lua, but there doesn't seem to be a straight forward way of using it. I was even about to go with using WASM (yes, WASM). But then I came across Yaegi ("Yet another elegant Go interpreter", you heard right: "interpreter"), Yaegi is also very easy to use.
There are a few issues (including some I haven't solved yet), including flexibility (multiple types of plugins), module support, etc. Fortunately, Traefik just released their plugin system which is based on Yaegi (same company), and I got to learn a few tricks from them.
Here's how module loading works: The developer vendors their dependencies and pushes them to a repo. The user downloads the repo as a zip and saves it to the plugins folder. I hash the zip, unzip it to a cache, and set the the GOPATH for the interpreter to be that extracted folder. I then load the module (which is defined by a config file in the folder), and save it for later. This is the relatively easy part.
The hard part is allowing for different types of plugins. It looks easy, but Go has a strict typing system, makes things complicated. I'm in the process of solving this problem, and so far it should go like this: Check that the plugin fits an arbitrary interface, and if it does, we're good the go. I will just have to apply the returned plugin to that interface. I don't like this method for a few reasons, but hopefully with generics it will become a bit more clean.1 -
I called the hack "blow up bunny", was in my first company.
We had 4 industrial printers which usually got fed by PHP / IPP to generate invoices / picking lists / ...
The dilemma started with inventory - we didn't have time to prepar due to a severe influenza going round (my team of 5 was down to 2 persons, where on was stuck with trying to maintain order. Overall I guess more than 40 % ill, of roughly 70 persons...)
Inventory was the kind of ultimate death process. Since the company sold mobile accessoires and other - small - stuff.
Small is the important word here....
Over 10 000 items were usually in stock.
Everything needed to be counted if open or (if closed) at least registered.
The dev task was to generate PDFs with SKUs and prefilled information to prevent disaster.
The problem wasn't printing.
The problem was time and size.
To generate lists for > 10 000 articles, matching SKUs, segmented by number of teams isn't fun.
To print it even less. Especially since printers can and will fail - if you send nonstop, there is a high chance that the printer get's stuck since the printers command buffer get's cranky and so on.
It was my longest working day: 18 hours.
In the end "Blow up bunny" did something incredibly stupid: It was a not so trivial bash pipeline which "blew up" the large PDF in a max of 5 pages, sent it to one of the 4 printers in round robin fashion.
After a max of 4 iterations, bunny was called.
"bunny" was the fun part.
Via IPP you can of course watch the printer queue.
So...
Check if queue was empty, start next round with determined empty printer queues.
Not so easy already. But due to the amount of pages this could fail too.
This was the moment where my brain suddenly got stuck aft 4 o clock in the morning in a very dark and spookey empty company - what if the printer get's stuck? I could send an reset queue or stuff like that, but all in all - dead is dead. Paper Jam is paper jam.
So... I just added all cups servers to the curl list of bunny.
Yes. I printed on all > 50 printers on 4 beefy CUPS servers in the whole company.
It worked.
People were pretty pissed since collecting them was a pita... But it worked.
And in less than 2 hours, which I would have never believed (cannot remember the previous time or number of pages...)1 -
Most hacky things I've ever done:
A windows scheduled task that kicks off a massive as fuck ETL job, riddled with errors. Damn thing had a mind of its own and only ran whenever it felt like it. Client was happy, deadlines were met, boss moved me to another task. -
Sadly, I’m not a good enough developer to have clever and hacky solutions to anything. In college I did once use Visual Basic to spoof a Novell login screen and steal other students’ passwords and write them to a diskette, which I’d recover after they walked away from the machine. The worst I did to them was log into their messaging and send them messages from themselves. Oh, and I also set up an “underground” web site that the campus sysadmins didn’t discover for a while. I used it to set up a forum where students could sell their used textbooks for better prices than the buy back program at the campus bookstore.
-
Alot of hacks around here!
An extract of some of those:
-Couldn't time the shutter right when photographing lightning. Used my oscilloscope to measure its electrical influence and anytime a peak is detected, it actuates the shutter.
-Using a lock as a heatsink for a overheating display driver ic.
-Hacking two USB ports together to get more power.
-Display module was too tall with header pins. Moved its back components to the main board and soldered the module flat onto it by flowing solder down its connecting holes.
-Not me but still interesting: Back on ye olde times when paid tv contained a disruptive H or VSYNC signal only their paid tv box could filter, my electronics prof. analyzed it and built the required comb filter on his own. Even sold some on the black market. -
When I was making 3d floor planner I needed to cut holes in walls to make doorways. I couldn’t use 3d model of hole cause there isn’t 3d model of empty space and the hole itself required to be with adjustable size so I hacked backend model of door to add some data with empty 3d model and stored all of the positions instead to load that and cut those holes on walls manually.
So it become door without door model. Doorway.
It worked like a charm. -
Parsing my college's terrible classless html float left div mosaic timetables so I could hide lectures I wasn't taking.
-
Scratch away the PCB trace that was initially connected and solder a wire straight to the IC pin to connect it it to the place you want1
-
I needed to align instruction execution to a 64bit boundary, for custom CPU architecture that I'm building. Basically the ISA had 3 types of instruction lengths; 16bit, 32bit, and 48bit. The core did 64bit fetch from the Instruction Cache, the issue was that if an instruction was in between two blocks of data I needed to fetch two blocks. That would impact performance a bit. So I had to modify GCC sources of the ISA that I'm using. So instead of doing it the right way, I just did it the lazy way and modified the GCC backend to print
.p2alignw 3, 0x00ff, 4
.p2alignw 3, 0x00ff, 2
On each 48bit and 32bit instruction to generate NOPs. And it did work lol. -
My idea is really good actually my startup is doing great now.
But my first time pitch was a terrible one in front of a small investor. He trolls me but now in bootstrap mode we have more than 50+ customers world wide2 -
not really that hacky but it was something back then
when I was still learning front end development. I enabled live server on my vs code, connected to a network went to a different PC and connected to same network, went to browser on second PC, entered the other PCs IP adress and added the port number provided by vs code, I was able to access the website I was working on so as I worked and saved the site automatically refreshes on the other computer and i saw the results immediately
this was because I had an 11 inch screen PC. a hp mini. was practically impossible to work with that so whenever my roommates PC was free I'd do that without having to code directly on his PC
later on I enabled auto save on vs code and it seemed I was on a roll. lol -
Dug up decrepit FSF code from 2001 from a random Apple FTP that was indexed online, throw into toolchain from 2004 that doesn't provide extensions, and it fucking worked.
This was last week.
I don't know how the fuck DOS programs are still made for the original machines, the only decent toolchain is DJGPP but it needs 32-bit DOS extenders and a Pentium 3 with 128MB RAM minimum to run anything compiled with it, which sure as shit doesn't target appropriate DOS hardware (which is, on average, prolly a 386 with 4MB of RAM or so, considering most hardware still running meets DOOM minimum spec?)2 -
almost everything work related. especially filtering a csv export file with a python executable to open a word serial letter to open a email for some entries with vba. or writing a js object file with vba from an excel 'database'. my proudness is ambivalent.
-
I was setting up a CI build machine. Builds were supposed to be ran in disposable containers, but I needed a way to trigger a task on the host from inside the container. I didn't want to give containers shell access to host - kinda misses the point.
Solution: a server running on the host and listening for predefined commands on a named pipe. The pipe was bound into containers which would simply echo commands into it. Very simple and effective.
The hacky part? The server was an 8-line bash script.1 -
Every time I am tired of writing default values for optional values (values that can be nil but HAVE to have some default value unless they break the app / program I just tell it to be any valid value instead of nil,and if it’s nil the app / program crashes the fuck up.
I test it by feeding it ONLY valid data.
Irresponsible, I know, but none of my projects have passed testing phases and all of them never really finished development.1 -
Not really an impressive one, but I think it's blasphemous enough to be mentioned:
Creating an embedded application, it was not supported to print a float using optimized libraries (understandable since they're not really supposed to be used anyways), but I was too lazy to convert clocks to a time unit by hand while running benchmarks. So I just printed the float as two integers, splitting it to one for the whole and one for the thousands. -
Default dict that returns default dict on configparser to replace "if/try/nested .get()" to just "or"
In the end I had just
data = source or source1 or source2 or source3