惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
GbyAI
GbyAI
博客园 - Franky
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
The Register - Security
The Register - Security
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
InfoQ
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Full Disclosure
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
博客园 - 【当耐特】
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Project Zero
Project Zero
量子位
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
美团技术团队
Attack and Defense Labs
Attack and Defense Labs
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Blog of Author Tim Ferriss
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Troy Hunt's Blog
Google Online Security Blog
Google Online Security Blog
罗磊的独立博客
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
S
SegmentFault 最新的问题
L
LINUX DO - 最新话题
Simon Willison's Weblog
Simon Willison's Weblog
爱范儿
爱范儿
博客园 - 聂微东
A
About on SuperTechFans
PCI Perspectives
PCI Perspectives
D
Docker

Sophie Alpert

There are no lossless transformations of natural-language text Deconstructing “services” I don’t want AI agents controlling my laptop Materialized views are obviously useful TODOs aren’t for doing Hire me to empower and upskill your eng team How React Changed the Web Forever: A Documentary Fast and maintainable patterns for fetching from a database React Conf: “Building a Custom React Renderer” Why review code? Metrics by proxy Yak shaving and fixing Voice React Conf: “React Today and Tomorrow” Why we host conference talk dry runs React Podcast: Inside React Type errors with inference need stacks Observable programming React 16: an API-compatible rewrite Hi, I’m trans. Initializing on the main thread using dispatch_once A near-perfect oninput shim for IE 8 and 9 Using React to speed up the Khan Academy question editor What I did at Khan Academy, 2012 edition Preventing XSS attacks when embedding JSON in HTML Rolling back to an old revision in Mercurial (like git reset)
Everyone is wrong about that Slack flowchart
Sophie Alpert · 2024-10-30 · via Sophie Alpert

Building software is hard. Oftentimes things that seem like they should be simple end up being way more complicated when you get into the details. (OK, maybe this isn’t specific to software.)

As evidence of this, people love to point to this flowchart that Slack’s engineering team published in March 2017 summarizing the logic Slack uses to determine whether to send a given user a notification for a message (author Johnny Rodgers’s additional commentary here):

Slack's flowchart titled 'Should we send a notification'. It has a few dozen boxes and arrows in different colors, and the lines are intertwined and even circular in some places. Multiple parts of the chart are partially duplicative with other parts.

You’ll hear no argument from me that this flowchart is incredibly complicated! It’s hard to understand the nuances of the logic from glancing quickly at this diagram. There are literally cycles in the graph! However I think it overcomplicates the situation a lot.

The most obvious cause of extra boxes in the diagram is completely splitting the “channel notification preferences” from “global notification preferences” questions, despite the fact that the options are almost perfectly analogous. Another issue is unnecessarily repeated checks for threads and highlight words that each appear a half dozen different times.

If you “refactor” the diagram, you end up with something that looks more like this version I drew:

My rendition of the same flowchart. It has only 6 boxes. We check the notification preference in only a single place and the chart overall is nearly linear, with each other check shunting a Yes or No answer towards the final 'Send Notification' or 'Don't Notify' outcome, rather than having many parallel paths that the common case goes down.

To me this is way easier to understand.

I’ll caveat that this is not 100% bug-for-bug compatible with the original flowchart. For example, the original chart claims that if @channel mentions are suppressed we’should never notify for a @channel message, but that’s not accurate: if the message contains a user mention or highlight word, we should still notify in that case. My goal is to match the actual 2017 behavior of Slack, not to match the original diagram for the sake of it — and I believe my version is comparably or more accurate.

Since the logic is simpler to understand at a glance in my version, I expect it is also easier to verify the correctness of and find bugs in my diagram if someone were to want to.

My diagram combines several things that are split out in the original version. In addition to the mergers I mentioned above, my use of && and || typically corresponds to different boxes in the original. Similarly, my Nothing (incl. muted) arrow is actually two checks masquerading as one.

Am I unfairly cheating by smooshing these together? I’d argue no. Each box or each arrow might correspond to a few lines of code (or may need to load data from multiple sources), but here we combine things that are conceptually part of the same check into one place, which makes it easier to understand the intent. I also focus on trying to have a single clear path through the chart with offramps, versus the original that has a dozen different “valid” paths. The goal of the chart, at least to me, is to make it easy to understand the high-level story of the decision tree, while still staying accurate to small details. In code, each complex check might be defined as its own function that can be reviewed and tested independently.

I don’t mean to claim that Slack’s notifications logic is simple. Indeed, former Slack employees tell me that it’s one of the most complex pieces of their codebase. I’m sure there is even a fair amount of complexity that is not captured in either diagram. For example, in what cases should a message sender be shown the choice to override do-not-disturb and “Notify anyway”? If a push notification is sent to my phone but then I view it on desktop or the message is deleted, should the notification be rescinded? This is all tricky business.

The point I want to make here is that the way we think about and talk about our systems has a huge impact on how understandable they are. It’s easy to make a complex solution to a complex problem; what’s hard is making a simple solution to a complex problem. With careful attention we can find the right lens to look through so that a tricky problem falls into place and our understanding of it looks more like the second diagram than the first.

Thanks to Scott Sandler for helping me understand the original diagram and reviewing mine.