Advent of Code in Production, Day 1: Project Kickoff
Explore how you might approach building the solutions to Advent of Code challenges as a production service that you intend to operate long term, rather than as a collection of one-off scripts.
This is the first in what I intend to be a series, based on Advent of Code 2022. I'll explore how you might approach building the solutions to those challenges as a production service that you intend to operate long term, rather than as a collection of one-off scripts. I don't actually know what the tasks for upcoming days will be, so I hope this works 😅
Premise
In this scenario, we've been asked to help Santa with some production issues. In fact, if we think of ourselves as a service provider, then Santa Clause is our client. Conceivably, he might even be just one of many in a market for our services. The first challenge Santa has is to find the backpack with the most food, from a list of foods grouped by pack. Santa's elves are making expeditions to gather magical star fruits. It seems they need to bring a lot of food with them to do it. They want to know which pack has the most food, in case they need to borrow some from each other. And we know they're going to be going out on these gathering expeditions every day. The first list we get has about 250 packs. That's not a huge number, but it's not nothing either. In total it's well over 1,000 rows of data. Especially if we assume Santa's operation could grow, or we'll expand our customer base. And another thing we know is that our scope will increase over time.
Star Fruit Tools
Basically, what I'm saying is we need to think a little about scale. How are we going to operate this software? How are we going to grow it? For that matter, how big could the dataset become? It sounds like we're going to be asked for a collection of things that I'm going to call Star Fruit Tools. A set of disparate software tools tends to be a pretty bad user experience. Most of the reason people outsource tooling to vendors is because they don't want a set of disparate tools. They want a service provider. So I'll plan to build a service. We'll keep it scoped as narrowly to the requirements as possible. We can anticipate future desires, and we can try to keep our options open, but we won't build features that we haven't been asked for. At least, not beyond what it takes to run a service.
Data Modeling
We have some very scant requirements and some very limited data, but that's enough to do a bit of data and process modeling. On the data side, we have Food, Backpacks, and Expeditions. I think these can map in a very straightforward way to data models. That raises the question of where to put that data. It's hard to imagine a scenario where we *won't* want to store it. And we want to access it in a structured way, for analysis. That pretty much demands a database. I think there's two reasonable options we could take: a NoSQL document store, or a SQL database. Document stores are convenient when you don't know what your data looks like, but in my experience that's a trap. Not knowing what your data model is *now* is not the same as not *needing* to know what it is later. I think evolving a data model over time is more likely to be successful than waiting to define one until you're trying to use it. So, I'm going to choose a SQL database. The specific flavor doesn't matter much, but it's hard to go wrong with Postgres, so I'll pick that. Not that I expect it to make a difference for quite a while. Those data models become tables in a very straightforward way.
erDiagram Expedition ||..|{ Backpack : includes Backpack ||..|{ Food : contains Food { int calories }
Process Modeling
In terms of the process model, we look at what our users—the elves—are doing, and what they're asking us to do. They're working out in the field, with limited tools. They want a tool that will help them with planning and logistics, but it's not something like an inventory system. The process they have is to write out all the contents of their backpacks onto a shared list, and then do some analysis on it. So, we need a service that will process the list, and a service that will return the analysis. These could be the same service, or a different one. I don't see a reason to jump to microservices just yet, so we'll build a singular service that can do this.  They have a way to get a plaintext list, so that's our input. We'll parse it, store it, analyze it, and return the analysis. Now, the application logic to perform that analysis is not that complicated. But it's practically trivial as a SQL statement.
sequenceDiagram actor Elves participant SFTools Elves->>SFTools: Input list SFTools->>SFTools: parse SFTools->>Database: store Database->>SFTools: query SFTools->>Elves: respond
And so, our final system consists of one small monolithic service, and one database. Everything is immediately consistent and we have no concurrency issues, which are convenient properties to have. We may even be able to maintain that for quite some time. SFTools should continue to be easily extensible to our future requirements. It's definitely overkill for the moment, but we know we're going to get requests for more tools and features as we go on.
erDiagram SFTools||--||Database: "depends on" SFTools { returns Function "inputs" none Parser "list" sum Processor "parsed list" }
Not to get ahead of ourselves, but some future features I might imagine we'll be asked for are things like more statistical views of the backpacks (largest N, smallest and median calorie counts, for example) and historical trends that could inform planning for future expeditions. In fact, the very first follow up request was for the largest N calorie counts. Good thing we anticipated that.
Conventional Solutions
I'm also doing Advent of Code the conventional way, and taking it as an opportunity to get more familiar with Golang. If you're interested in code solutions that have essentially no relationship to the system design exercise I'm doing here, you're welcome to follow that, too. Fair warning, I'm going to be behind and there's no guarantee I'll finish. But that is my intent.
https://github.com/jenniferplusplus/aoc2022/tree/main/day01
Cover photo by Meruyert Gonullu