First Crack Release Notes, February 2020
I had a busy start to the year. Between traveling and work, I did not have enough time to finish the titanic task I had given myself: rewriting First Crack. When it came time to post the January release notes, then, I did not have anything ready; today I do.
First, some history — because it explains how I got here, and why I took on this task. As best I can tell, based on file creation times and git logs, I started writing First Crack around October of 2011. I worked on it here and there over the next three years, then made the source code public in July of 2014. I kept the public code base updated for about 18 months, until the end of 2015. By then I had grown enough to realize I could build a much better engine. It took me two years to make that rewrite production-ready, and then seven months to feel comfortable re-releasing it. Along with that re-release, I began posting monthly updates to track the changes I made, and the ones I wanted to make in the future. These posts lasted from June to December, 2019.
I started feeling the itch to rewrite First Crack again when the new year rolled around. I had discovered Pythonic concurrency in August, but took a serious interest in it six months later. By the time I finished Sequential Execution, Multiprocessing, and Multithreading IO-Bound Tasks in Python, I once again felt I had grown enough to make a rewrite worthwhile. I started that process near the end of January, with a few general goals:
- Write good code. I had written many of First Crack’s functions in a flow state. They worked, but it took a lot to remember why they did, and few conformed to best practices. Most programmers will say only the first trait matters, but well-reasoned, well-structured, and well-written programs streamline collaboration, make maintenance easy, and help projects outlast their authors. I also consider this a point of pride: good programmers write good code; bad ones excuse it. As part of the rewrite, I wanted to focus on doing the right things well, and standardizing method names, structure, and return values.
- Write modern code. A month after First Crack’s re-release, I began supporting Python 2. If a BASH script could not find Python 3, it changed the engine to run on the now-deprecated yet immortal version 2. The ease with which I managed this should have made obvious the fact that I had not taken advantage of years of improvements and optimizations, but that realization did not occur until I did a deep dive on concurrency. Along with the improvements outlined in the bullet above, I also wanted to modernize my code as part of this rewrite. As I think back to the beginning of this process, this cautionary tale and this story of redemption likely played a part in setting this goal as well.
- Design for concurrency. My deep dive into concurrency made its value clear. Although I had managed to bolt on some multiprocessing methods back in August of 2019, First Crack did not take full advantage of multiprocessing or multithreading. I wanted to use this rewrite as an opportunity to take full advantage of both.
I began the rewrite with these goals in mind, for both the back-end engine and the front-end design. I got the lion’s share of the work done over a long weekend at the beginning of February, and then spent the rest of the month cleaning up and documenting the code base, and polishing the new site layout. Check out the rewritten engine at FirstCrack’s GitHub page, and the new design here.
Aside from pursuing the goals above, for the most part First Crack’s rewrite just tries to do everything its predecessor did but better — with one exception: the preview feature now sets up a local web server to better replicate an actual use case scenario. Running
blog.py with the
-p flag — or using
make preview — creates a private web server available to the local machine only, so just you can test your website at
-P flag — or
make public — creates a public one available to anyone on the network via port 8000. Use the latter to test your website on other devices, for example, or show off a new design to your coworkers. Keep in mind, though, that the latter option may give bad actors a way into your machine; I implemented only the most basic security controls, so use this feature on shared networks with caution. The accompanying log file First Crack generates,
server.log, may help track down evidence of malicious activity if it feels like something went awry.
Those who have used Firebase before may know that the command-line tool can do this with
firebase serve, but Firebase’s web server does not afford me the same level of control a custom implementation does. It’s also slow, so I wrote my own.
I still have work to do. First Crack’s initial rewrite runs about 50% slower than its predecessor, so I need to spend some time fine-tuning it. While I had all but exhausted all avenues for better performance in the old version, I have not done much of that work in the new one; I look forward to making progress here soon. After that, I plan to overhaul the Markdown parser, as outlined below.
Feature Roadmap #
Along with general maintenance and my constant pursuit of optimization, I still want to get these things done in the future. I have carried most of these tasks over each month since I started this series, but plan to begin work on at least the first two soon.
Release Markdown Parser #
I want to release my Markdown parser as its own project. I fixed a few bugs during the rewrite, but I still have some others to work out. At the least, I want to go public with greater coverage of the spec, and with the ability to handle multi-line strings and entire files at once. My true goal is to design a performant Markdown parser and then write an efficient implementation of it. Several people have already done some interesting work in this space. At present, it implements the subset of the spec I use on a regular basis, and handles files one line at a time.
Publish Implementation of Markdown Spec #
Along with the release of my Markdown parser, I will need to outline the peculiarities of my implementation. Parity with John Gruber’s spec would make sense, or something like GitHub Flavored Markdown which has much more detailed documentation, so I may go this route; if not, I will need to produce my own documentation. This would cover weird edge cases for the most part, but it would also give those who use my engine have some sort of explanation for why their article looks weird. In brief, my argument against going with a standard comes down to the fact that I have little use for most of those features and edge use cases. Once this becomes its own project, though, that others may use, this argument gets even shakier. I will have to spend some time thinking about this before I move forward.
Improve Documentation #
A few of the ways I think I can improve the README in particular:
- Re-create usage GIFs. I had a few neat GIFs that showed off First Crack’s simple install process and easy use case, but I will have to re-create those after the rewrite.
- Performance graphs of First Crack’s back-end performance versus other, similar engines. At less than two seconds to build a website of over one thousand pages, I want to highlight this.
- Performance graphs of the web pages First Crack builds versus the pages common content management systems build.
- Screenshots. This site is a live demo of the engine, but I like the idea of having a few pictures in there, too.
As always, I look forward to the work ahead.