What Food Service Taught Me About Software Architecture : Part 2
Tags: architecture, webdev, beginners
Published: 2019-09-20 15:22:03



## Stateful vs Stateless 

![Woman ordering food in a restaurant](https://thepracticaldev.s3.amazonaws.com/i/cpb0wdwdpdo9hmavrvkb.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@sourfraser">Fraser Cottrell</a> on Unsplash</figcaption>

State<i>ful</i> applications are applications which need to persist information (or "state") within the application between uses.

State<i>less</i> applications are those which persist nothing between uses.

The easiest way of identifying a stateful role in food service is identifying if the employee fulfilling that role could be switched for literally any other employee of the same role at any point with no impact on the restaurant.

For instance, a busser could be generally switched out at the end of a shift, and the new busser would be able to continue working without needing to learn information on the state of the restaurant.

A traditional waiter, however, carries with them information on the tables. "*Table 9 is allergic to nuts*", "*Table 13 is paying the check*", "*We are out of avocado mayo*". If getting replaced, this information would have to be transferred to the replacement before the job could be continued properly. However, this could be minimized by keeping state stored on an external source (POS systems, notepads, etc.). Bartenders are also extremely stateful, having to keep track of conversations, customer preferences, etc.

Korean BBQ restaurants have fairly stateless waiters. They don't generally keep too much information on the state of a table, they just react to whatever the state of the actual table is (which is considered an *external* state). This makes it really easy to throw more staff members on the floor (scaling out) without any interruption to the customers.

Generally stateless makes applications easier to handle. Just like in the above example, it makes it easy to automatically scale out the application (throw more instances of the application behind the load balancer) to handle high volume time periods.

The most common use of stateful applications nowadays are when you want to store user sessions server side (as opposed to storing a user's credentials in the browser or front end application, which can get complicated), or when you want to do in-application caching for performance gains. Both of these can actually be offloaded to external databases that get shared between stateless applications, but that adds other layers of complexity. 

## Asynchronous Design

![A stack of steaming tortillas.](https://thepracticaldev.s3.amazonaws.com/i/0pigk9n50gk2ahnrnqox.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@iisus_d_costea">Octavian Catana</a> on Unsplash</figcaption>

Asynchronous design is designing applications and software such that it can multitask.

An easy example of a pretty much every day any 15 second window of time at a Chili's: 
- Ring in food for a table in a POS
- Throw tortillas on the tortilla heater
- Set up the coffee drip to brew with one hand while filling cups with waters with the other
- Grab the tortillas off the heater
- Throw everything onto a tray and walk out

Not only was I able to multitask heating up the tortillas while taking care of coffee and water, but sending the food order at the beginning was a way of getting the cooks to start their asynchronous process of cooking the food (which I will later need to re-sync up on).

Fortunately, we humans are extremely good at being asynchronous. We delegate tasks to others, can do two different things with two hands at once, can keep track of progress on several different tasks, and can adapt to two tasks becoming dependent on each other (deadlocks). 

Applications tend to be a lot harder to make asynchronous without introducing dangers. Race conditions (result of two tasks differing depending on which one finishes first) and dead locks (two tasks needing to wait for each other, resulting in neither ever progressing) are pretty much the nightmare fuel for most developers.

When designed correctly, asynchronous applications can massively speed up a process, and sometimes can help distribute work loads so that applications don't get overworked (imagine if the server had to handle cooking the food, instead of having an application, the cook, working in parallel).

## Cloud Services

![Bottle of wine being poured into a decanter](https://thepracticaldev.s3.amazonaws.com/i/qchtod40k7j33ie88g5x.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@meganmarkham">Megan Markham</a> on Unsplash</figcaption>

Cloud services is pretty much outsourcing the physical servers for your applications to be managed by a third party.

I've been to several vineyards that have their own kitchens, and (obviously) their own drinks, but they use a 3rd party company for providing the waiters. The vineyard can train the employees on what is expected of them (do/don't bus plates, handle specific sections, etc.), but they themselves don't pay the employees directly, and don't ever need to worry about managing the employees.

Another good example is a catering company. You don't need to manage the employees or tell them how to cook things, you just tell the company what food is expected and how many waiters you may need, and the company takes care of the rest.

From a dev perspective, what this all boils down to is would we prefer to have a computer sitting in the corner of the office hosting our application, or make a company like Microsoft or Amazon manage the physical computer itself? The benefits of the latter option generally is that Microsoft and Amazon have massive teams dedicated to taking care of these servers on a large scale, making sure they have constant availability and are secure. These services also often offer functionalities like Serverless applications, that would be impossible otherwise.

The downside is that Microsoft and Amazon like money. The computer sitting in the corner of the office does not need money (although the electric companies, internet providers, and IT/DevOps/Systems team you have managing that computer do tend to need money).

## Serverless Applications
![Waiter speaking to a table outside of a restaurant](https://thepracticaldev.s3.amazonaws.com/i/bfe42wb2w47mic7t1dpr.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@henriquefelix">Henrique Felix</a> on Unsplash</figcaption>

I doubt an implementation of this actually exists in the food service world, because people don't work this way.

Serverless Applications are pretty much the logical extreme of Micro Services and Cloud Services.

Imagine if you had a restaurant where you paid a third party company to always be able to provide you with exactly as many waiters as you need. Those waiters would only work for exactly as long as they need to, and would clock in/out exactly when they start/stop work.

So if you go the entire day without a single customer, you owe that third party company $0. If there are 100 customers in the morning, and 0 at night, you only pay the company for the 4 or 5 waiters that they provide for the morning, and would not need to pay them anything for the night.

Depending on the role, these very-temporary employees may have significant enough spin up time (getting into uniform, clocking in, etc.) that it would become more desirable to just keep them around even during times that are not busy.

The goal with serverless would then be to do this for every single employee, and give each employee very, very specific tasks. You could even break waiters down into "table greeters", "order takers", "check droppers", and reduce the amount you need to pay for each employee to match the very granular tasks they are performing. You would never have any more employees at any given point than exactly how many you need to have to take on the current workload.

Naturally, people don't work that way, but applications can. Most cloud servers offer the ability for your application to not have a dedicated physical server, but rather spin up in arbitrary locations whenever it's needed. When designed correctly, this can make cloud hosting almost free, as you won't be eating away at the cloud service's resources constantly, only for very brief moments each day.


These serverless applications tend to need to be designed with serverless in mind, however. Just like in the above example, you would want to make sure that the spin up overhead on the application was really low. Generally you also have to design the application to be focused on solving one very granular task, to minimize run time/costs.


## Closing Thoughts
![Chocolate Cake](https://thepracticaldev.s3.amazonaws.com/i/lrwdma9vnrwm56j4sssx.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@heftiba">Toa Heftiba</a> on Unsplash</figcaption>

I've often wondered if the parallels found here exist because both food service and software architecture are trying to solve the same problem: streamlined interactions between a network of varied, often complicated, services. If that is the case, there has to be other industries with similar parallels.

I also wonder what a restaurant would look like if someone were to completely redesign the entire user experience and the roles used to cater to that experience. Would we end up with monoliths? Would we end up with "Cloud Services" that host very specialized employees that work where they are needed only when they are needed there? How much impact does the "humanizing" factor actually impact the importance of needing a specific role (I.E: Can we get rid of waiters if we find they aren't valuable to the system)?

<figcaption>Cover photo by <a href="https://unsplash.com/@mossphotography">Moss</a> on Unsplash</figcaption>