Ask HN: Weirdest hack that you ever saw in production?

330 points by jxub ↗ HN

288 comments

[ 6.6 ms ] story [ 300 ms ] thread
Finance needed to do end-of-year stuff a couple of days past end-of-year. The system couldn't handle this, bad things would happen and data would change once end-of-year passes.

Solution? A bash script that does:

   while true:
       set date to 4pm end-of-year
       sleep 1
Why the loop, vs setting the date once?
NTP would resync it, and obviously after X hours it would no longer be end of year even if you set the date in the past.

It needed to be end of year day for 2 or 3 days.

yeah I get that but `while(true)` seems excessive. Why not just do it once and disable NTP?
because time moves forwards, and if you set it to 4pm then in 1.5 hours it will be 5.30pm, and the end-of-year stuff will kick in?

Three lines of bash seemed simpler. It's a hack, yes, and there are better ways. But really who gives a damn.

I would guess the system was probably running ntpd or some other time sync service that they were unwilling or unable to turn off.
Right after WinXP came out, I was a sys/win admin at a manufacturing co. Their ERP system was an old VB app that sat on a share drive and everyone opened the same .exe from their respective workstations.

The app required a ton of scheduled database and ERP tasks (it used a legacy flat-file db), so the vendor wrapped them all up in a secondary executable that was effectively a non-headless (headful?) daemon (this was expensive, niche industry software btw). The first instance of the application that opened would also trigger the daemon to open too, on whichever PC it was executed on (it was supposed to be opened on the server 1st). It was provided by the vendor this way, as part of the COTS application.

As a result of this daemon hack, every couple days (after the application crashed on the server, as it did frequently) I would run around the building to dozens and dozens of workstations until I found the user’s workstation that had been the first to run the ERP after the server process crashed, and thus had the daemon running on their workstation. Then I would kill it, and sprint back to the server closet to reopen the daemon before any other users would run the ERP and grab the daemon (later would just RDP after we got off NT).

It was awesome.

Oh wow. Yeah, that sort of thing seems to have been so common in ERP software.

My first professional programming job was working on a bespoke ERP and industrial process control suite (written in PowerBuilder). The program had a huge number of sub programs (dynamically loaded modules, each an MDI window accessed using a “program name”, something like a SAP transaction code).

We had a number of background services that would have to run, however writing Windows services in PowerBuilder was anything but easy. And we were reluctant to use anything else - the whole benefit of using a 4GL was a well integrated ORM and report generating functionality.

So we’d implement our background services as regular modules (with their little MDI window) within the main thick client app. Clients would have a number of workstations dedicated to running a single one of these processes. Nothing headless, each outputting it’s status or logs to he connected display. If the power, network or database ever dropped, each of these machines would have to be restarted and have its allocated sub program reopened.

For example, despatch label printing program would monitor a database queue table for new rows, bring up a report associated with the specified despatch note, print the report to the label printer then delete the row.

It seems so hackish but it worked incredibly well. Our clients were all food or paper manufacturers, running 24/7. Operations were rarely disrupted. Have a single screen per function to monitor for status changes was something operators were accustomed to.

This was over a decade ago, but I’ve never worked with a more productive team since. The constraints of the system let us focus on solving business problems. I can’t imagine writing anything of this scale in a modern environment. I’d love to see 4GLs like this make a comeback. The first class GUI, ORM, report generation were a huge productivity boost. And the simple programming language (with a very simple object model) put the focus on problem solving and not API acrobatics.

Simpler times.

No kidding. Everything got clear queueing and back-pressure for free!
Back at CS school, that's the definition I always hoped to hear of "race condition".
I looked up ERP software in google images. Holy poor UX, Batman! There's a great market opportunity there for something that doesn't spew out everything at once onscreen.
From the outside it definitely looks this way. And some enterprise software (Oracle, Peoplesoft) definitely have some real UX gaps. However... in a professional, power-user environment, high information density is massive plus. Being able to see as much information as possible, with as few clicks as possible, and as few round-trips to the server as possible, is very desirable.

The less information you have per screen/interaction, the more you lock users into a specific way of doing things. Business software users tend to optimise for what works for them. The worst UX experiments I’ve conducted in enterprise software involved low information density screens, showing users just what they told me they needed to see. User expectations in this space are so nuanced - better to favour more information and a high learning curve vs easier to user but less flexible software.

The entire billing system at my first job was written as a console exe by a (brilliant) guy in during one-day session, working almost completely from live debugging breakpoints (against the production database). The result was less than beautiful, but there were rarely any problems with it. Needless to say anytime a billing inquiry came up it was his problem (which he was okay with since he owned the place).
Haha, literally writing a multicurrency accounting system from scratch at the moment. Same deal: my company, my rules. Trying to be a bit forward-looking though[0], and already tonnes of features you can't buy. Live third party market platform scraping, machine translation, github integration, beginnings of live mainland Chinese bank API integration, etc.

[0] https://github.com/globalcitizen/ifex-protocol/

my dad put a rubberband on an ibm mainframe printer in 75 to make it work while ibm showed up to fix it. They came in and didn't get it to work. So my dad as he needed to print millions of water bills on time put the rubberband back in and ran his job.
My dad had a similar thing with his car. An old jalopy, I don't remember exactly what was wrong, something slipped out of place in relation to the engine, miles away from any support.

He happened to have clamps in the back, put a clamp on it and a few rubber bands for good measure. When he finally got to the garage they looked at it, laughed, then suggested that he keep it that way, given that the parts for the car were rare and the fix was reasonably expensive. I believe that he ended up driving on that for a couple of years until the car broke down from an unrelated part failure.

Glad to see confirmation of using a rubber band to fix an IBM mainframe. Been there done that, but the story is so loony I wondered if anyone would believe me. http://laughtonelectronics.com/oldsite/comm_mfg/commercial_i...
Love that you've updated your page with a reference to this discussion already :-)
I was delighted at being able to cite an independent source saying such a thing was possible!

In the 2016 HN thread "Strange bug workarounds" I posted a much gnarlier problem (and oddball solution): https://news.ycombinator.com/item?id=12485921

Read it yesterday as I was reading your previous posts :-)

(I often check the posting history when someone posts something interesting.)

Using the Google Sheets API to store session history and metadata for a nightly backfill job instead of, you know, a database. The program broke after the creator left and no one could figure out how to bring it back up. The engineer assigned to fix it pulled their hair out looking for the database creds, local SQLite3 records, anything that would initialize the backfill. Finally realized it wasn't just printing out metadata to a Google Sheet but actually relying on that as a persistence layer. Root cause of the breakage was automatically adding every Hadoop counter from the job as its own column in the Sheet, which eventually exceeded the dimension limits.
Using Google Sheets instead of a proper database brings me nightmares.
I did this once. A client wanted a website that mimicked the functionality of a complicated spreadsheet that he had created to calculate quotes for customers and didn't have enough money to pay to have all the logic rewritten in a webserver (not to mention continually updated).

I imported the spreadsheet into google sheets, gave him access, and had the webserver paste the values in the spreadsheet via the google sheets api and read them back out.

I created a whole project for this!

https://github.com/franciscop/drive-db

Since you can also hook a Google Form to a spreadsheet, you can do surprisingly advanced things over there.

Not to detract from this project, buy this is a good opportunity to mention Apps Script.

You can do all sorts of interesting things between a form, spreadsheet, and other services including your own. Nobody seems to use it, but internally we do all sorts of gloriously hacky workflows with it.

You can easily script forms/sheets/calendar/Gmail together to create pretty much anything you need.

I use it to send daily email reports of data fed into a spreadsheet.

Ah sure, no problem, feel free to do a PR mentioning App Scripts as well if you'd like.

From a quick overview it seems like if you need serious work with spreadsheets/GDocs then App Scripts is a good choice. However drive-db is more like a (very) quick way of putting a Spreadsheet into your Node.js backend as an array/db. I purposefully didn't even allow edit since that'd require API keys from users and defeat the quick part of it.

The funny thing about this was that the truly incompetent wouldn't have been able to do something like that.

Sounds more like some BS requirement from a clueless middle manager or a boss and a dose of malicious compliance.

I worked at a place that had a large, distributed terminal network running on something like OSF or DEC Unix.

It was 2001 and the thing was on life support while PCs were being rolled out. I was helping to rack my new database servers, which was next to this big lab table/shelf combo with like 16 terminals on it. When pulling a cable I banged my head on the table, then this big book fell on my hand.

About 10 minutes later, a bunch of graybeards come around the corner yelling “WTF are you doing!”

Turns out that the dictionary that hit my hand was perched across two keyboards, holding down the “enter” keys of two terminals. Turns out that for reasons unknown, those terminals had to be repeatedly hitting the enter key in order for the logins and print jobs of about 40,000 people to work.

Seriously, that is pretty impressive. Unix police found you.
I've worked at a place with a very similar hack before, but it was for a bunch of windows servers. The issue was a process was trying to scan various Office files, and even though no actual Word/Excel/etc app was running warning dialogs could suddenly appear blocking the scan process. The problem was "solved" by some frustrated ops guy that wrote a service that scanned for dialog boxes and closed them.
First time I've heard of this problem there was "Buzof" - maybe nearly 20 years ago? I just googled and it still exists: http://www.basta.com/Buzof
I've got one of those from "Only on WIndows" series. One of my colleagues uses WIndows and tends to remote in from home. Unfortunately when a cleaner cleans the office after hours she sometimes accidentally hits the CAPS key and he can't log in anymore remotely. His solution was to rip out the CAPS key and cover the hole with duct tape.
I do this, too. The first thing I do when I get a new keyboard is to remove the caps lock key. I never used it in my 20 years of PC usages and I don't get why it's still there.

Back in my CounterStrike gaming days I would also remove the Windows key because it would crash the game when accidentally pressed.

Map escape key to it. Especially if you use vim.
I map ALT to CTRL and CapsLock to ALT, so I don't have to use my pinky to hot CTRL
DON’T remove caps lock!!! Use it as an application switcher!

Some of my most used shortcuts:

Caps + C = Chrome

Caps + S = Spotify

Caps + A = Atom

Caps + T = Terminal

+1 for removing windows key if gaming

That's a really good idea. Most of my application switching needs are covered by the built-in Windows "Win+1 opens first icon on the taskbar, Win+2 opens the second...", but this could cover the lesser used ones like Outlook.
On Windows, Win+1 launches the first app in the taskbar, Win+2 launches the second, etc.
I work about 30/70 on Mac and Windows. I have the caps lock key mapped to ctrl on Windows and cmd on Mac since they’re roughly equivalent. Makes switching my muscle memory when I switch my OS far less necessary. No more hitting ctrl-c to copy on Mac and instead sending a SIGKILL to the terminal!
My wife would kill me. She uses it to enter uppercase first letters. Just won’t (or can’t) work the shift key.
It's used by the Japanese IME on Windows: Ctrl+CapsLock - hiragana input, Alt+CapsLock - katakana input, Shift+CapsLack - alphanumeric input.
I like your typo in the last capslock, it accurately describes my capslock key ;)

Though, that actually is interesting, and you made me read up ab bit on Japanese.

Ahh the good old CounterStrike quick exit! If you were lucky you could alt-tab back in, but you'd have a big mouse arrow where your reticle used to be :D

I ended up coding a utility (in VS6!) to disable the windows key when you launched the game.

dude that windows key always messed me up, esp because my computer was a load of crap, and it took hella days to minimize/maximize the window again, usually I had to reboot the machine.
I use AutoHotKey to remap it to launch TotalCommander.
Does AutoHotKey function on the login screen?
Nope -- I remap Caps Lock to control, and if I'm not careful I can wind up logged in with it stuck in caps mode, and no way to get lowercase characters without locking the screen, turning off all-caps mode, and logging in again. Luckily, this is hard to do :-)
I use AHK to remap CapsLock to double-click to reduce the strain on my mouse hand, but I can access the original CapsLock function via shift-CapsLock. Try it -- maybe that will help you.
That's a fantastic idea! Unfortunately, I use JetBrains IDEs, so I have lots of ctrl-shift keychords I couldn't live without.
Not a hack, but once we couldn't figure out why a printer dropped off the network.

Turns out the cleaners were thorough enough to clean deep down behind a desk and turned off a surge protector that a 5-port network switch was plugged into.

I've mapped my caps key to fullwidth text, initially for quick-response memeing but it turns out it's actually quite helpful for increasing expressiveness on various chat protocols.
That's actually pretty cool - how do you accomplish that? (And on which OS?)
WTF? How come I worked around three years on RDP clients and stuff and did not know about this?
I remapped my caps key to control on every machine I use. I find it much more ergonomic than the standard left-control location.
Similar but inverse to this, I was fixing a critical server and it usually came up in a minute or less. 5 minutes later I get concerned, I walk into the server room and it’s still trying to boot. I scratch my head and see a usb keyboard attached.... with a screwdriver sitting on my space bar.

Yup, I IRQ-DOSS’ed myself.

I have heard a similar story that existed in my company before it joined. It was a system that raised and dispatched jobs to engineers, and unless the space bar was held down on the master terminal, it stopped sending jobs out.
5F3759DF a.k.a. fast inverse square root [1] in graphics programming.

[1] - https://en.wikipedia.org/wiki/Fast_inverse_square_root

Descendents of this still exist in many codebases, especially libm's. I've found it in my own codebase as well. It's surprisingly maintainable.
I'd love to know who left those comments for Quake III Arena in your referenced Wikipedia article. I had a good laugh.
>I'd love to know who left those comments

The legend himself, John Carmack.

Fast inverse square root is really the perfect example of black magic in programming.

I always thought of this bit of code as a great example of applied numerical methods techniques, rather than “Black Magic” The magic constant is derivable from standard methods and one can even choose to optimize other measures of error.

http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf

Isn't it what black magic is all about?

Unorthodox technique, that you can explain if you try hard enough (in a sense, everything that reliably work could be explained and someone has to came up with in the first place), used by people who don't really understand it.

What do you think is a better example?

I would consider “black magic” to be something that works reliably due to some specific and idiosyncratic property of the environment that it operates within. Basically, something that is exceptionally tightly coupled. I think the novel FPGA solutions that genetic algorithms can create fall into this category; they often didn’t work on different boards, or even when the same board was plugged into a different power supply because the solution was overfit.

“A Story About Magic” is black magic in action. http://catb.org/jargon/html/magic-story.html

“The Story of Mel” is not black magic even though no one else understood his program. http://www.catb.org/jargon/html/story-of-mel.html

Yes, it is derivable, but it takes a certain amount of (reckless) genius to put all together

In the world where FizzBuzz is hard, applying the Newton Method is a rare thing.

Webhost circa 2002. Lots of carrots from Microsoft for us to go big on ASP.NET hosting. Fat boss made a deal which involved us rewriting our customer interface in ASP.NET from the existing ColdFusion morass. His eyes popping at our estimates of how long this would take, he came up with a solution: rename our *.cfm files to .aspx, and map IIS to pass .aspx files to the CF server. Job done.
Genius. Now if we could convince the kids of today this is solution to rewriting everything using the latest fad framework.
Nice and efficient. There’s an elegance to this solution that’s hard to grasp unless you’ve been in a similar situation before.
I love the novelty and frivolity
Not sure if this is still the case, but back when I was at Apple the program that triggered when you pressed a button on an Apple remote pointed at a Macintosh was just a giant AppleScript file that, at the top level, was a giant `if...else if...` statement to try and determine which application had the foreground so that the appropriate action (e.g. next track for iTunes, next slide for Keynote, next chapter marker for QuickTime, etc.) could be triggered.
Interesting! The only .scpt files I can find in /System are Automator actions or in Script Utility itself, and of those the only one that seems relevant is Library/Automator/Initiate Remote Broadcast.action/Contents/Resources/Scripts/main.scpt, which seems like something else. Hopefully that means they fixed it (if someone with an apple remote wants to run opensnoop and double-check that would be cool!)
I think I remember this from the days of Front Row. It’s long gone now.
(comment deleted)
So that‘s why that remote was always so unreliable.
running a 3rd party program called PTFB (press the fckn button) as a background process on a farm of 20 Prod web servers to automatically press "OK" on a dialog window that would pop up as a result of unhanded exception in one of our hacky conversion processes that the company didn't allow us to fix.
"Don't delete this comment or the production server will crash." Tried it, did as advertised. Apparently the website went through a proxy that reflected over the code, using that comment as a hook to inject some sort of functionality.
I've personally set this kind of thing up. Inherited an old PHP site for a webdev contract, and a couple weeks into development (before any of my code had made it to prod), the server starts hanging randomly, or spitting out seemingly random errors on every request.

I was told in no uncertain terms by the client that I had to fix the server hangs within 48hrs I'd lose the contract. This was in a million+ LOC custom Wordpress nightmare.

I wound up writing a script that ran on a little EC2.micro instance that would ping the homepage every 60s looking for the HTML comment `<!-- if you delete this comment, the server will reboot forever -->`, and if the request timed out or the text wasn't found it would hit their hosting API and reboot the server the site was running on.

I deployed the "fix", finished the contract without incident, and subsequently fired the client.

The Atlantic has a magic PAGE_COMPLETED comment that we used when I was there to tell the CDN whether to cache a page or not. I imagine that’s common.
Using a Remote Access Object to proxy calls between 32-bit and 64-bit code. Instead of rewriting any of the original ASP code, the lead architect made a DLL that would provide .NET 2.0 functionality to the ASP code. This was in 2014. The DLL was 32-bit and predictably ran out of memory every 30 hours. We created a scheduled task to restart the service every 24 hours, what a band-aid.
Tons of asp (and asp.net) sites are restarted on a regular basis to prevent crashes. The source of most of these problems are never known.
Actually, IIS automatically restarts the worker thread once a day by default; meaning most developers are unaware of memory/resource leaks that don't end up causing a crash within 24 hours. Got called in to look at quite a few "random" issues that turned out to be resource leaks that only showed when the site was under enough stress for it to hit the brick wall within the 24 hour recycle period.
The default IIS app pool elapsed time based recycle interval is 1740min, or 29hrs. 29 being the smallest prime over 24. Seriously.
Yup, and for good reason. It means your site won’t be down at the same time two days in a row.
(comment deleted)
In my startup days, we were working on a proof of concept with a really big bank. Because of their security rules, we couldn't have direct access to their systems - so if we wanted to do something remotely, we would have to start a webex, they would join and share their screen, and give us remote control.

This worked great, except if we wanted to work over the weekend, since if we left the screen alone for more than a few minutes, the screen lock would kick in and we'd lose the session.

Our solution? We purchased a small fan with an oscillation mode, and tied a mouse to it. We then had the fan drag the mouse ever so slightly back and forth whenever we wanted to step away from the remote session. Kept it going for weeks.

Similar situation, except with a personal massager, a wireless mouse, and a large bowl.
I use a posh script like this when i dont want the computer to lock.

$ws = New-Object -COM wscript.shell;

while($true){ $ws.SendKeys("j"); Sleep 60;}

Ive used it for demos that way the computer doesnt lock before the demo starts, its pretty short and easy to remember. Also on windows if you spam SendKeys("{Left}") everything you type is backwards and when you hit the windows key it freezes the computer in an interesting way, pretty fun.

I used to use autohotkey to send an F13 key press every couple minutes to avoid lockout on a work computer where I wasn't allowed to increase the timeout
Wait is Function keys above F12 still addressable?
It’s Windows, so backwards compatibility mandates F13-F24 exist.
Certainly, my keyboard still has those buttons and I still use them
Which keyboard is this? I'm a keyboard-only user and would love to have an extra row of keys for shortcuts.
Can't speak for the parent, but Apple USB keyboards have F13-F19.
The script is overkill, just put some plastic under your mouse.
(comment deleted)
bash/X11 equivalent:

  function mouse_around {
    while true; do
      sleep "$1"
      xdotool mousemove_relative 1 1
      xdotool mousemove_relative -- -1 -1
    done
  }
  
  mouse_around 60
I did something similar in my last job: We used a custom terminal services client to log in to our data center, and the servers would kick you off after something like five minutes of inactivity. I ended up modifying the ts client to send a shift keypress every four minutes.
I've seen people strapping a watch on the back of the mouse to achieve the same effect, the constant ticking makes it like the mouse is slightly moved, preventing a screen lock.
On a windows machine you can start a powerpoint presentation, then minimise it. This stops the screen lock from starting.
I’ve used a blank no-audio video in Windows Media Player to achieve the same.
There's also this [1] I found when I had to opt out of a crazy work-enforced screen lock timer. (like 3m)

[1] https://archive.codeplex.com/?p=mousejiggler

As someone who enforces screen lock timers for compliance, if I ever found someone was using any of these hacks, my solution would probably involve writing a script to automatically lock their screen every five minutes regardless of activity until they agreed to knock it off. :P
I actually find people's risk intuition spectacularly bad. People seem to suspect their IT department will catch them and report them for things that their IT department doesn't care about, for example. Or expect that the IT department and/or supervisors may be watching their webcam, which is creepy, and really not something ordinary workplaces do.
This seems to be a very common problem as evinced by the many solutions below. A friend of mine asked me solve the problem for him because he was remotely accessing a database and the company-issued laptop, VPN client, remote server and database server all had aggressive timeouts. Getting a cup of coffee meant logging in to everything again using long and complex company-issued passwords.

We used one of the common Raspberry PI Human Interface Device (HID) Python packages to send a harmless keyboard or mouse event once every 5 minutes.

Ha - amused to read this! Just built that a week ago for my partner. I used an Arduino connected to the USB as HID. The approx. 10 line script is moving the mouse back and forth every couple of seconds. Works like a charm: keeps the screen unlocked and her activity indicator busy...
I think an optical mouse placed on the reflective side of a CD achieves the same "jumping around" - effect.
(comment deleted)
Email validation by inserting a record into database and rolling back from savepoint if succeeded - Salesforce does not publish their official code/regex and architects pushed it to match it perfectly with the platform. Project was done in 2017 btw.
(comment deleted)
Had a server that was overheating badly and the numerous fans just weren’t working. Need to keep it running to transfer all the data to a newer machine. Went to Walmart and bought flexible dryer ducting and duct tape. Vented the AC directly into the case. Got everything transferred without having to pull the backup (which is slow). Never did figure out the fan thing but something must have gone wrong on the motherboard because all the fans were good.
I had a similar set up for a computer I overclocked to play games as a kid.
The music for our call waiting at my first job, was an old Windows machine blasting music in our server room with a phone on speaker... You ever wonder why music on clal waiting sounds so fuzzy?
Reminds me how the Russian Buzzer UVB-76 works. Hams listening to the station determined it was literally just a microphone in front of some tone generator, because occasionally you'd hear conversations between soldiers in the background.
Which I guess means you had to be super silent when doing physical hardware maintenance?
"I just heard a bunch of swearing when I was on hold!"
The lingua franca of theatrical lighting control is a physical-layer protocol designed for custom cabling called DMX. Light boards emit an array of 512 values in the range [0,255] and dimmers, or lighting instruments themselves, interpret these values as parameters like intensity. For various reasons it's useful to carry this signal over an IP network, and proprietary standards to do so have proliferated.

Light boards these days are just computers with some domain-specific IO. Tired of our ancient ETC Expression console, my colleagues and I wanted to start using ETC's new Nomad control software on our laptops. Our venue's dimmers only understood ETCNet2, while Nomad could only speak the newer ETCNet3 (and a few other open standards we couldn't use). Attempting a software upgrade on the dimmers themselves seemed incredibly risky. To bring Nomad's output to DMX would have required an additional $500 hardware purchase on top of the already-not-cheap software license.

On the message boards, I discovered a strange fact. The ETC-branded DMX<->Net2 interfaces we owned were actually white-label manufactured by a company called Pathport. Pathport boxes spoke a much wider array of protocols using the same hardware. These things handled firmware updates by flashing themselves with whatever was served to them over BOOTP. Pathport firmware images were free to download straight from the manufacturer.

Net3->Net2 was too much to ask for, but they could do ArtNet (an open standard) to DMX. Nomad could also emit ArtNet. So I flashed and configured one node to operate as ArtNet -> DMX, and plugged it into another node configured for DMX -> Net2.

So now, locked in a closet, there is a very strange loop of switch -> hacked ETC box -> normal ETC box -> switch which seems bizarrely redundant, but actually makes the world go 'round. And I could run lights and sound from any network drop in the building.

Wow, this brings back memories of running the theater in my school. Definitely a different situation, but I like to think we did a good job given what we had.

We didn't really have a budget, just some hand-me-down equipment that came from above sometimes. I and others on my team put together so many hacks to make things work. One memorable time, our light board had broken, but we still needed to run shows.

We didn't have enough time to wait for shipping on a real USB->DMX adapter, nor budget for a new board, so I created a hacked together DMX adapter with a serial to USB adapter and a NAND gate (I put schematics together here, if anyone's interested: https://github.com/magmastonealex/DMXAdapters).

It worked remarkably well for being a bit of a hack, but paired with software like QLC+, had more features than our old light board! It was still in use for controlling special effect lighting when I left, though thankfully not for main lighting and day-to-day use.

The Expression may be outdated, but LDs still cling to it.

This also reminded me of how when HES stopped supporting the DP2000 in Hog, DP2000 owners just swapped it over to ArtNet mode.

Just recently I had to put together a web-based UI for editing vector graphics (clothing tags) and export them to pdf for printing. In order to avoid writing and maintaining two separate codebases, I re-used the client side code as my rendering code.

So I ended up with a server serving the editor frontend, as well as api endpoints that would use puppeteer and headless chrome to make a request (to itself) to load the frontend, import a given label file, render it, take a screenshot and save it to a file, then reply to the api request with the contents. So kind of a recursive api.

I had so much fun with this but I still can't believe I had to write my own svg editor and bake my own pdf generation and merging code to get the job done. It should not require two languages (node and python) and a headless browser to get the job done.

I’ve literally just helped someone do similar in their own product. If you run into issues with puppeteer’s blank or missing pages of a screenshot (for high-res images), just forgo that for canvases base64 export. It’ll save you a world of hurt!
wut. why did you do this? why didn't you just handle all of it in the frontend? jspdf makes PDFs in browser.
I would have loved to, but one of the sticking points was that the label file had to be serialized, saved, and later interpolated with data from a bunch of different records, which is why I used svg over canvas, wrote my own editor, etc. jsPDF seems great for imperatively generating a pdf, but not for editing/loading template files. Plus, since the pdf generation had to happen server side, I would have needed a headless browser anyway.

It's super weird, and I've been over it from every direction but I don't know how I could have done it differently.

>Plus, since the pdf generation had to happen server side

this is exactly my question: why did the pdf generation need to be server side?

1. Client creates a custom label and we store it in s3 2. They select x inventory items + click print 3. We retrieve and send the label file + inventory data to a service that interpolates the data into each template, renders to pdf, merges them, and forwards it to our printing service.

We certainly could do the work on the client, but they're making this request in a context where neither the label nor the libraries need to be loaded; in fact, in our server-side implementation, it could be done with a single api call. Doing it all client side would strongly couple the client to the technology.

Also, we re-used this api in two applications, one of which never loaded the editor (along with its dependencies).

TLDR; a weird hack was better than violating separation of conerns.

>forwards it to our printing service.

is the printing service a real physical service?

anyway i'm doing basically exactly this same thing except all client side (i send the serialized "label file" and data to the client) but printing is being done using the user's printer

Yep, the printing service is a third-party api (PrintNode) that routes the request to one of any number of desktop clients.

The reason we did it this way is 1. we have a web app so we can't print directly to their printer without a print dialog, and 2. we want to print to potentially a different device than the user is on.

Ha. My team implemented something very similar. We were writing a browser-based animation editor, and we needed to render a 'film strip' of frames. But we were targeting tablets, and loading a new canvas filled with heavyweight vector assets for each frame took forever. Since the animations were auto-saved to the server, it proved quicker just to spin up the app in a headless browser on the server, render all the frames, and have the client download them!
Production system that would chain-ssh through various bastion hosts to get around asinine firewall systems, eventually telnetting in as root to a non-standard port to run a script and dump data out of the files on disk of a MySQL instance backing a virtualization system. Billed based on how many of the output files that instance appeared in ("hourly billing!"), and who was the "owner" of that instance.
Here's a late version of Encarta.

https://goo.gl/6uX4Qu

Do you see that plain-looking dropdown menu with the rounded orange highlights? That is Internet Explorer. Just this one menu. It's an in-process instance of Trident, IEs old HTML rendering engine. So that little window is the equivalent of somthing like chromium embedded. I don't know why that menu is an instance of IE's HTML renderer. Someone wanted to style it with CSS, I think. So they embedded IE. That flyout to the right is probably another Trident window. In order to meet accessibility requirements, I had to grab the running instance of the root IE COM interface, and route keyboard events into it. With raw C++ COM. There were other hooks going in the opposite direction so the menu / browser window could tell the app about clicks.

That is just insane. Separate rendering engines for each tab?
I can't remember how the flyouts worked. They might have shared a window, or they might not have been HTML windows (but I think they were). What I know for sure is that the one main dropdown was IE.
Glass/gradients was a baaaad trend in visual styles. Very plastic, cheap looking.