Every Programmer’s Worst Nightmare - My Website Part 2
Creation of demo.dust.coffee (the really technical part) also note to self: stop with the clickbait titles.

One of the features I always imagined my portfolio site would have, is the ability to view and start a full interactive demo for each of my projects. There were various (and expensive ways) to do this. Some of my fellow alumni decided to host each of their rails project/api’s on something like heroku, and then had a seperate frontend host. I didn’t much care for this strategy for many reasons. One, it would be tedious to manage. Two, it might get expensive. I know some cloud services do a pay as you go/per project you want to host, but I’m cheap and prefer to spend my money on cups of coffee ☕️.
Do I sacrifice a few cups of coffee to pay for hosting all my demos?

You probably already guessed my answer to that, no. Instead, I bought some coffee and got to thinking. I figured that there was no reason to host all my projects separately and have them run all the time. Instead I asked myself “what if I could have a server that started other servers?” A server within a server? :O
How could I do such a thing?
It was actually pretty simple to setup. I used Rack(what rails is built on) as a basic web server that would listen for a button press on coffeedust.io and then dispatch a start command in bash to run that demo. I foresaw a few issues with that approach however. One issue would be, how would I make that demo server run without blocking the main parent thread? Also, how would I have the server shutoff after a certain amount of time inactive?
Giving Parallelization a Good Bash(script)
As I have quite a bit of experience with Unix commands along with multithreading in Ruby, I was pretty confident in my ability to make this idea come alive and solve those issues. I first solved the issue of the main thread being blocked while the demo was starting and running. So I decided to make a parallel process with Unix’s Fork command and… Viola! No more blocked thread. However, the demo keep giving me an error when I ran it’s start command. Saying how it was missing a gem that was definitely in it’s Gemfile.
Then every programmers worst fear. No answers on stack-overflow!
After quite a bit of googling, I realized that no-one else has either attempted what I was doing, or never had this issue before. I was getting pretty discouraged, but I never gave up and I started doing some deep think debugging. First, I tried to figure out what exactly the problem was. I ran bundle install and got a success message. But I looked at the gems it installed, and they weren’t the correct ones, it was actually using the gem file for my Rack server, not the demo!
Very confused about this, I figured that maybe I wasn’t in the correct directory when running the server. After confirming I was indeed in the right directory, I was very much confusion. I then ‘traced’ the code’s steps and looked through the gem files, bundler settings for both servers and I found nothing that could be causing the Gemfile location issue.
After taking what I knew already and ruling out what I knew wasn’t causing it, I realized that the issue was not with my code, it was almost like it was an invisible configuration.
Then it hit me! There is an invisible configuration hash at the system level. The ENV hash! I then looked at it at runtime, and sure enough, there was a configuration for the Bundler Gemfile location. As the demo sever is a forked process of the Rack server, the ENV hash would have been copied. Thus the Gemfile that the demo Rails server was using, was indeed the one belonging to its parent process, the Rack server.
After resetting that ENV hash attribute in the context of the new forked process, the rails server for my demo ran, and it was all sunshine from here on.
But I don’t want the demo to run all the time if it’s not being used…
If this was Javascript, I could simply do a setTimeout to send a shutdown command to the process after a certain amount of time. However, this is Ruby, and asynchronous tasks ain’t that simple. Some might even say, such a thing is impossible, however, Ruby does have a concurrent multithreading system built in! So, I used that system to create an asynchronous shutdown timer, so after 15 mins, it will stop the demo server process, all without blocking the main thread.
Next, all I had left to do was configure this server to be able to run my different projects and code some bash scripts for correctly installing those demos and their dependencies on the server’s machine. After wrapping everything in a nice Docker container, it was ready to be installed on my one server machine.
It was quite a challenge but I loved every minute of it! It made me realize that backend and technical development is my passion, much more enjoyable than frontend development with CSS & HTML.
Mission accomplished! Just one server needed to run and host them all! All my project demos. Thanks for reading 😄
github repo for the project: https://github.com/Coffee-Dust/demo-coffeedust-io


