-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
155 changed files
with
2,877 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
219 changes: 219 additions & 0 deletions
219
testcontent/Blog/a-defensive-approach-to-engineering-quality.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
--- | ||
date: 2021-01-24T17:15:00-08:00 | ||
title: A Defensive Approach to Engineering Quality | ||
type: posts | ||
tags: | ||
- Web Development | ||
- Coding | ||
- Software Management | ||
- Engineering Management | ||
- DevTo | ||
techfeatured: true | ||
description: One of the most important ways I can contribute to the quality of our sites is by saying no. | ||
--- | ||
As an engineering manager, I have a certain amount of control over what | ||
ends up on our sites and in our systems. Not complete control, my voice | ||
is only one in the room, as it should be. One of the most important ways | ||
I can contribute to the quality of our sites is by saying no. Blocking | ||
or pushing back on requests that are contrary to our goals can be as | ||
important as what we decide **to** do. | ||
|
||
The goal is not to prevent change. Change is great, but randomness ruins | ||
plans. If you build a hundred features and ten of them don't fit into | ||
the product vision or the technical architecture, those ten will have a | ||
disproportionate impact on the team over the life of the product. | ||
|
||
The pressure to do one-off features or changes is continual, but it is | ||
also quite normal. The stakeholder asking for this change isn't a bad | ||
person, they just have a different perspective. While they may be able | ||
to understand how much effort is involved in their request, they are | ||
unlikely to understand the long-term costs in terms of maintainability. | ||
Often it is difficult for the engineering team to articulate this cost. | ||
For a single change it isn\'t significant, but all these changes add up | ||
over time. | ||
|
||
## Death by a thousand cuts | ||
|
||
One concrete example that has been a constant in my projects, is teams | ||
asking for us to add third party scripts. There are a few reasons why | ||
this happens, but in my experience, the most common is a request to add | ||
a set of tracking code to a \# of pages. Someone in the company is | ||
running an advertising campaign, and your site is the destination. | ||
Everything is nearly done and its days away from going live on Facebook | ||
and Twitter. No one looped engineering in before now, of course. An | ||
email comes in, often having bounced around, in search of the person who | ||
runs the site: | ||
|
||
> Hey Duncan, I hear you are the guy to ask about getting something onto | ||
> the site. We are about to kick off a huge ad campaign across fifteen | ||
> countries to drive folks to the new Azure solutions content. It's | ||
> using ads on Facebook and Twitter, so we need to add tracking pixels | ||
> for both of those to the attached list of ten pages. I have included | ||
> the zip files of javascript for both sites, if you could get it up on | ||
> the site by tomorrow that would be great! | ||
> | ||
> Thanks, Sam | ||
Couple of things to unpack here. Sam hasn\'t done anything wrong, | ||
there\'s no evil intent. They didn\'t know to loop engineering in, and | ||
they don\'t know if adding two scripts to a set of pages is hard or at | ||
all controversial. They have a job to do and this is just one step. | ||
|
||
## The simple solution | ||
|
||
Why not just do it? the business wants it, and our site exists to serve | ||
the business, so shouldn\'t we just make a ticket and get it done? | ||
|
||
Let's follow that path for a bit to see where it gets us (hint, simple | ||
changes generally aren\'t that simple). | ||
|
||
To close the work item and hit Sam\'s deadline, we open the page, follow | ||
the instructions from each third-party and put all the script references | ||
in. Test it, seems to work, no errors, we see network calls to a bunch | ||
of places, done. Ship it, close the ticket. | ||
|
||
Hard to push back against what is probably an hour\'s work, right? | ||
|
||
Most big sites aren\'t a bunch of individual pages though, so you\'d | ||
probably be editing a common template. To add these scripts **only** to | ||
the requested pages, you\'ll need a little IF statement (`if url =-\_\_ | ||
or url =\_\_ ... `). Now we are running a bit of logic on **all** our | ||
pages. It\'s tiny though, still hard to really raise a red flag. Your | ||
developer "Spidey-sense" is starting to tingle, but the work is done, | ||
Sam is happy. | ||
|
||
A few weeks later, another email comes in: | ||
|
||
> Hey Duncan, thanks so much for helping out with that last request, the | ||
> campaign is going great. We are trying out something new now, we've | ||
> picked a mix of pages (some from the last campaign and some new ones) | ||
> and we are adding LinkedIn to the mix. Super excited to see how that | ||
> compares to the other campaign that is running. Anyway, the new ads | ||
> start tomorrow and there is a lot of \$\$ being spent here, so if you | ||
> could get these new scripts up that would be great. Scripts and a list | ||
> of pages attached like last time. Thanks so much! Owe you a coffee :) | ||
> | ||
> Sam | ||
A new work item is created, maybe ends up with a new developer. If they | ||
saw the code from the last request, they might just extend it with some | ||
more if statements, to be consistent. Or maybe they'll go a different | ||
way, it's hard to predict, especially with a busy team. | ||
|
||
One possible path is that these requests keep trickling in over the | ||
years, various bits of code are added, and we end up with a block of | ||
terrible code running on all our pages. Regardless of how many times | ||
this happens though, even doing it once can have unintended | ||
consequences. | ||
|
||
Months after we add some third-party scripts, we end up looking at this | ||
page and we see an issue. | ||
|
||
Choose your adventure time, the page is\... | ||
|
||
1. Performing poorly, the third-party script must work in any | ||
situation, so it loads its own version copy of jQuery and two other | ||
scripts you already have on the page. | ||
|
||
2. Failing. Turns out the third-party script was updated and now has a | ||
conflict with something else on the page. | ||
|
||
3. Dropping cookies. Most ad tracking scripts are going to drop cookies | ||
and the exact behavior could change over time. You carefully thought | ||
through privacy and GDPR for **your** scripts. Did you re-evaluate | ||
for every update to some 'random ad platform' script? | ||
|
||
Every case described above gets worse over time. Two years from now, you | ||
do an audit of all the cookies you drop. Will you catch every one-off | ||
page that does its own special thing? If the Ad campaign ends after two | ||
months, do you remember to remove this code, or does it live on forever? | ||
|
||
## A better way to handle these requests | ||
|
||
Third party script requests are just one example and I am sure you have | ||
your own set of examples. I\'ve seen similar requests for one-off | ||
redirects, custom variations on styles or headers, etc. The common | ||
element is that it is a special-case request, seemingly one-off, and | ||
disconnected from any larger vision or roadmap. We know it's a bad idea | ||
to hack this in, despite pressure or temptation to just do it. It is | ||
hard to quantify the negatives though, which puts the developer in a | ||
difficult spot. | ||
|
||
I could tell you to 'just say no' to anything like this, and sometimes I | ||
do that myself, but that\'s not always reasonable or even appropriate. | ||
First, we should try to understand if this is a genuine business need. | ||
Are these ad campaigns important? Do we **need** to track their results? | ||
|
||
Next, we take a step back from the specifics of the request and turn it | ||
into the actual business need. Sam asked us to add these scripts, but | ||
what they **really want** is to report on the effectiveness of their ad | ||
campaign. The script might be the right approach, but it's always good | ||
to turn any request that has jumped ahead to implementation back into a | ||
description of the real goal. Can we accomplish within the existing | ||
capabilities of our platform? We have analytics on the site, could we | ||
add distinct tracking ids as query strings to the ads and report on them | ||
that way? | ||
|
||
In the end, if this is needed and there isn't any existing way to handle | ||
it, then we are back to the original request. At this point, we still | ||
have options that reduce the negative aspects of adding these scripts. | ||
Talk to Sam, or the set of Sams who work on ad campaigns. Are we | ||
planning to do a lot of these? Generally going all-in on the same three | ||
platforms? | ||
|
||
If so, dig into the docs for each platform, so you can determine the | ||
best way to implement their scripts. Are the scripts the same for every | ||
campaign? Add an option in your site admin to turn "Advertising Scripts" | ||
on/off for a set of pages. If that type of self-serve config is too much | ||
work, test adding the scripts to every page. I know that sounds bad, but | ||
it might be a better solution than some sort of complicated | ||
configuration to control where they appear. | ||
|
||
Now that we\'ve decided to do this right, it's a platform capability not | ||
a one-off hack. You can test it in depth, include it in your performance | ||
and privacy plans, and take it into account when you are making changes. | ||
|
||
Handling these requests properly is a lot more work than a hack, in the | ||
short term, but it is the only sustainable option. We need to deliver on | ||
business requests, but remember that a stable, maintainable, and quality | ||
site is **also** a business priority. Sacrificing the long-term health | ||
of your system for a never- ending set of day-to-day requests is not a | ||
workable solution. | ||
|
||
I understand this can be a hard sell. | ||
|
||
You will be asked to "just take a short-cut this one time". Sometimes | ||
you won\'t have the support needed to win the battle and you will have | ||
to do it. Try to minimize the impact of this type of work by | ||
|
||
- Setting a time to revisit the implementation (to remove or improve | ||
it). | ||
|
||
- Categorize and document \"one-off\" requests. If you can point at an | ||
ongoing pattern, it's easier to justify doing a proper solution. | ||
|
||
- One-off solution results in an issue? It seems wrong to say, \"I | ||
told you so\", but it's more support for your push back on these | ||
requests. Write it up and provide some clear data though, don\'t | ||
expect anyone else to remember or to make the connection to the | ||
original request. | ||
|
||
## Policies as an appeal to an external authority | ||
|
||
Finally, the best advice I can give you is to create written | ||
guidelines/policies. Even if **you** wrote it, being able to say \"we | ||
don\'t add third-party scripts to our pages outside of a defined | ||
feature" is a wonderful way to steer the conversation in the right | ||
direction. | ||
|
||
My personal approach to this specific issue is to say, "We don't do | ||
that", suggest how they can use our existing capabilities to accomplish | ||
at least some of their goals, and if it turns out to be a high enough | ||
priority then we move to planning out the proper 'real' way to provide a | ||
sustainable solution. | ||
|
||
If urgency, as in Sam\'s original request with a day's notice, forces a | ||
short-term solution, we pro-actively plan to resist/remove at a specific | ||
date. I don\'t always get what I want of course, and some things slip | ||
through without my knowledge, but the fewer of these that happen the | ||
better off my team and system will be. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
date: 2019-05-11T17:58:00-08:00 | ||
title: Drinking Craft Beer at the Brew Wild Pizza Bar in Madrid | ||
type: posts | ||
tags: | ||
- Travel | ||
- Beer | ||
- Madrid | ||
- Spain | ||
images: | ||
- /images/beer/imperial_stout_sml.jpg | ||
description: On a recent trip to Spain, I was lucky to find a local craft brewpub | ||
--- | ||
My most recent bit of [beer tourism]({{< relref "beer-tourism.md" >}}) happened on a wonderful trip to Spain. While traveling to European countries, I often end up drinking lagers. This is not my regular choice at home, but my travel beer choice system is based on an overall desire to drink a local beer if available and the fact that I **really** prefer beer on tap (or _cerveza de barril_ in spanish). | ||
|
||
Given those preferences, I try to find local craft beer on tap, fall back to local beer on tap, and then after that I'm basically just going with what ever they have. Last time I was in Madrid, that meant I was drinking Mahou, Cruz Campo, Alhambra, and Estrella Damm. I definitely ended up drinking a fair amount of these beers this trip too, but I was also pleasantly surprised by a lot of craft beer options. There was even a [Cervezas La Cibeles](http://www.cervezaslacibeles.com/) (a Madrid craft brewery) in the hotel room fridge when we arrived (along with a Heineken of course)! | ||
|
||
![bottle of Cervezas La Cibeles, a craft beer from Madrid](/images/beer/cibeles_sml.jpg) | ||
|
||
Loved the logo of [the Santa Ana brewery](https://cerveceriasantaana.com) (it's a squirrel holding a beer), but when I ordered the single beer they had available (brewed by them), I was surprised to see it come out in a bottle. It was good, but this was **their pub** so it was a bit disappointing that their beer wasn't on tap. Note that the website seems to suggest that draft beer is available, so your results may vary. | ||
|
||
The absolute best place I found on my trip though, was [a local pizza place whose name, Brew Wild made me think they'd have some beer](http://www.brewwildpizzabar.com). That was an understatement. With 18 beers on tap, many of them very local, my only regret was that I could only try a couple. | ||
|
||
![View of the taps and the bartender at Brew Wild](/images/beer/brew_wild_one_sml.jpg) | ||
|
||
Luckily for me, and my step-dad who was traveling with us, we made it there **twice** during this one trip. We flew into and out of Madrid, so we were back there about two weeks later. Brew Wild was on the agenda for both Madrid visits! The list of available beers likely changes all the time, but I can tell you that I enjoyed the **Vanilla Black Velvet** (Russian Imperial Stout) and the **15 hour Citra Session IPA** both from [La Quince](http://laquincebrewery.com/). | ||
|
||
![Tulip glass of a nice dark stout](/images/beer/imperial_stout_sml.jpg) | ||
|
||
The pizza place is either run by the same people as La Quince, or they have a very close partnership, it basically seemed like the La Quince brewpub. They had lots of other brewery's beers on tap though, and in fact on our second visit, it happened to be a brewer's night. We tried some beer from, and chatted with a representative of [Northern Monk](https://northernmonk.com/) (a brewery from Leeds, England). | ||
|
||
I'm sure there are many other craft beer spots in Madrid, but finding them wasn't the main purpose of my family vacation. We were very happy to find a spot with so many great craft beers right where we were staying. | ||
|
||
Oh, and the pizza was great too! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
--- | ||
date: 2019-08-17T17:00:00-08:00 | ||
title: Boxing Cat Craft Beer Brewery in Shanghai China | ||
type: posts | ||
tags: | ||
- Travel | ||
- Beer | ||
- China | ||
images: | ||
- /images/beer/shanghai/BoxingCat_Outside_Logo.jpg | ||
description: Not the first brewery I found in Shanghai, but the one I keep going back to | ||
--- | ||
## Overview | ||
|
||
Shortly after my first visit, I was searching around online to see if there were any craft beer places in Shanghai other than the Shanghai Brewery that I had already found. I found a few articles about new beer places, and they all made comments about 'now there is more than just the old favorite, Boxing Cat' and I knew I had to find this Boxing Cat place. Just the name alone had me interested. On my next trip, I was able to find them in an area called Sinan Mansions. | ||
|
||
![Boxing Cat logo showing their mascot who looks like a skinny Thai boxer](/images/beer/shanghai/BoxingCat_Outside_Logo.jpg) | ||
|
||
I went right in and had one of the many bit of cultural confusion that you may run into while traveling. I was handed a paper list of what was available on tap at the moment, just a photocopied list. | ||
|
||
> A list like that is a good sign. If the taps rotate, they need something that can be updated often like a printed list, or a chalk board sign or something like that. If the list of beers is only in a glossy menu, then you'll end up getting a lot of 'no, sorry, don't have that one' when you try to order. | ||
Anyway, I was reading the list, enjoying the details provided (descriptions of the beer, IBUs, and alcohol %) and asked for a schooner/half-pint of something. The waitress then proceeded to try to take my beer list, and I asked if I could hang on to it because I was likely going to order a second beer. They had a big pile of them by the door, but she still continued trying to pull it out of my hand. It was odd, but I hung onto it tightly until she gave up. If I could speak the language, I probably would have been able to better explain that I might have more than one beer :) | ||
|
||
On future visits, I found another location on the same road, but in a different part of town, and just recently they opened a completely new place called 'First Round'. | ||
|
||
![Street view of the First Round location of Boxing Cat, showing their sign and logo](/images/beer/shanghai/firstround_outside.jpg) | ||
|
||
![Wall behind the taps at the First Round location of Boxing Cat, showing their beer names](/images/beer/shanghai/firstround_inside.jpg) | ||
|
||
First Round is worth checking out, and it has all the same beers as the others, so if you can only pick one, that's the location I'd suggest you visit. This location is designed to be all 'self-serve', and I had no idea what that meant, so I had to ask. Turns out you can order food using your WeChat account and a menu of QR codes, and you can get beer from a self-serve station all without any help. Or at least you can if you can pay using WeChat. I was limited to credit card or cash, so I couldn't officially use the self-serve beer station, but I really wanted to see it in action, so I asked if the bartender could use the machine **for me** and let me film it! | ||
|
||
<video controls poster="/images/beer/shanghai/firstround.jpg" height="480px" width="280px"> | ||
<source src="/images/beer/shanghai/firstround.mp4" type="video/mp4"> | ||
Your browser does not support the video tag. | ||
</video> | ||
|
||
## The beer | ||
|
||
All this talk of a brewery, I guess I had better talk about the actual beer. I have been very happy with the different choices available at Boxing Cat, from the TKO IPA (which is normally always available, and is what you'll likely find at any other retail location) to the many varieties of stouts and porters (that come and go, I think I've only found their 'regular' Donkey Punch Porter on one occasion). I'm a big fan of the King Louie Imperial Stout, but [check out this page for a full list of what they are making](https://www.boxingcatbrewery.com/now-on-tap/). | ||
|
||
## Food | ||
|
||
All of the locations have [a full food menu](https://www.boxingcatbrewery.com/food/), and while I can't really speak to everything they have, the burger I had at one location was quite good. Think 'american bar food' and you won't be disappointed. | ||
|
||
## How to find Boxing Cat in Shanghai | ||
|
||
As of when I wrote this, there were three Boxing Cat locations in Shanghai: | ||
|
||
* [First Round (in Hong Qiao),739 Dingxi Lu, by Yan'an Xi Lu](https://www.thatsmags.com/shanghai/directory/1796042/first-round) | ||
* [Sinan Mansions Location, Unit 26A 519 Fu Xing Road Central](https://www.thatsmags.com/shanghai/directory/1391/boxing-cat-brewery-sinan-mansions) | ||
* [Yong Fu Location, 82 Fu Xing Road West](https://www.thatsmags.com/shanghai/directory/1392/boxing-cat-brewery-fuxing-lu) |
Oops, something went wrong.