<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gustav Wengel</title>
    <description>The latest articles on DEV Community by Gustav Wengel (@geewee).</description>
    <link>https://dev.to/geewee</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F54045%2F21cf5121-7272-46a9-95c9-82d66b4cc0c0.jpeg</url>
      <title>DEV Community: Gustav Wengel</title>
      <link>https://dev.to/geewee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geewee"/>
    <language>en</language>
    <item>
      <title>Azure Event Hubs Are Not Queues</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Tue, 12 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/azure-event-hubs-are-not-queues-7i9</link>
      <guid>https://dev.to/geewee/azure-event-hubs-are-not-queues-7i9</guid>
      <description>&lt;p&gt;Unfortunately, I’ve seen quite a few people use &lt;a href="https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-about"&gt;Azure Event Hubs&lt;/a&gt;, when what they really wanted was a queue.&lt;/p&gt;

&lt;p&gt;Event Hubs are great for large-scale data ingestion, but if you just need to pass messages between your services - use something else. Here’s a few reasons why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Messages Block The Queue
&lt;/h2&gt;

&lt;p&gt;Event Hubs uses a partitioning model where messages sent to it are distributed among partitions.&lt;br&gt;&lt;br&gt;
Each partition has one reader that can read from concurrently, and the messages are always processed in order.&lt;/p&gt;

&lt;p&gt;This means that if you have a message that’s taking a while to process, the rest of the messages on that partition are delayed.&lt;br&gt;&lt;br&gt;
It means that if you have a message that’s causing your application to crash, you can’t process anything else on that partition until you somehow deal with that message. Either by waiting and retrying, dropping the message or perhaps saving it somewhere else.&lt;/p&gt;

&lt;p&gt;Contrast this with something like the Azure Storage Queue where you can lock a message and attempt to process it.&lt;br&gt;&lt;br&gt;
If you can’t process it or it takes a while you’re not holding anyone up. Other consumers don’t need to wait for you to process your message before they can continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checkpointing Makes Error Handling Hard(er)
&lt;/h2&gt;

&lt;p&gt;Event Hubs are batch-oriented. You receive a batch of messages and then when you’ve processed enough you create what’s called a &lt;a href="https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-features#checkpointing"&gt;checkpoint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A checkpoint is a way of writing down: This is how many messages I’ve processed. Checkpointing is something you do occasionally - it isn’t meant to be something you do every message.&lt;br&gt;&lt;br&gt;
If your application crashes between checkpoints it’ll start off at the last checkpoint and you’ll reprocess each message until you’re up-to-date again.&lt;br&gt;&lt;br&gt;
That means your systems have to be pretty durable to messages that are delivered multiple times.&lt;/p&gt;

&lt;p&gt;While this is a problem with most queues (applications can always crash between receiving a message and processing it), often you’ll only process one message at a time, so there’s less harm done if something fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Hubs Require An Extra Storage Account
&lt;/h2&gt;

&lt;p&gt;The partitioned readers use an Azure Storage account to coordinate checkpointing and &lt;a href="https://docs.microsoft.com/en-us/azure/event-hubs/event-processor-balance-partition-load"&gt;partition ownership&lt;/a&gt; between them.&lt;/p&gt;

&lt;p&gt;This means that you can’t read from an Event Hub without also having a storage account. It’s not a big deal, but it does add an extra connection string to manage, and an extra Azure resource to deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local Development
&lt;/h2&gt;

&lt;p&gt;There is no way of running an Event Hub locally.&lt;br&gt;&lt;br&gt;
Contrast this with e.g. an Azure Storage Queue which you can run locally with &lt;a href="https://github.com/Azure/Azurite"&gt;Azurite&lt;/a&gt;, or many other queues which you can run in Docker.&lt;/p&gt;

&lt;p&gt;Being able to run your dependencies locally is really nice. It means you don’t have to deal with spinning up Event Hubs for each developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reasons to use Event Hub
&lt;/h2&gt;

&lt;p&gt;I don’t hate Event Hubs. They’re a good tool if you need what it offers, such as the &lt;a href="https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-overview"&gt;Event Capture Feature&lt;/a&gt;, or you have large amounts of data.&lt;/p&gt;

&lt;p&gt;But if you just need to send messages between services? Use something else.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How To Ask Good Questions When Working Remote</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Fri, 27 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/how-to-ask-good-questions-when-working-remote-g05</link>
      <guid>https://dev.to/geewee/how-to-ask-good-questions-when-working-remote-g05</guid>
      <description>&lt;p&gt;At my current job with &lt;a href="https://www.linkedin.com/company/scada-minds/"&gt;SCADA MINDS&lt;/a&gt; I work with several different teams at the same time. That means I get to answer many questions. I’ve noticed that some teams are much, much better at asking questions and communicating than others.&lt;/p&gt;

&lt;p&gt;Let’s take a look at two real interactions I’ve had that effectively illustrate the difference between good and bad communication in a remote setting. First, the example of bad communication. This was a question asked to me in private:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e3lxDAfj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/private-message-bad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e3lxDAfj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/private-message-bad.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up - the better one. This was a question asked by an intern in a public development channel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7PdFJSLD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/public-message-good.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7PdFJSLD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/public-message-good.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These two interactions are as different as night and day!&lt;/p&gt;

&lt;p&gt;Let’s try to consider a couple of factors that will lead to asking good questions - and in turn getting good answers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Write One Self-Contained Message
&lt;/h1&gt;

&lt;p&gt;One of the most important rules when asking the question is to write &lt;em&gt;one&lt;/em&gt;, self-contained, message.&lt;/p&gt;

&lt;p&gt;While &lt;a href="https://www.nohello.com/2013/01/please-dont-say-just-hello-in-chat.html?m=1"&gt;saying hello&lt;/a&gt; before asking your question might seem polite in real-life, it’s awful etiquette when asking questions online.&lt;br&gt;&lt;br&gt;
Don’t write “Hello” in one message and then write your question. Whoever you write “Hello” to is going to get a notification disturbing them, and then sit and wait for you to formulate your question.&lt;br&gt;&lt;br&gt;
And definitely don’t wait for them to say “Hello” back before asking your question. That’s just going to delay the whole process even further.&lt;/p&gt;

&lt;p&gt;Compose one message, that contains both the formalities and the question:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--is8LgptD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/good-message-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--is8LgptD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/ask-good-questions/good-message-example.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ask Questions In Public
&lt;/h1&gt;

&lt;p&gt;A lot of teams have a tendency to ask questions in private, because they know which person usually has the answers.&lt;br&gt;&lt;br&gt;
This will get the question answered - but it’s not the best way. Here’s why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It leads to more work for the person who’s answering&lt;/strong&gt; 
Someone else might have asked the exact same question last week, and maybe someone will next week. This person will end up answering the same question over and over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your team doesn’t get smarter&lt;/strong&gt;
Anything that goes on in private chats or mails is invisible to the rest of the team who might be struggling with similar questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Someone else might know better&lt;/strong&gt;
Even if you think you’re asking someone who you think knows the answer, they might not be the best person to answer it. Someone else might have much more expertise with a particular topic, but if you ask in private you’ll never find out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of asking in private - here’s what you should do:  &lt;strong&gt;Ask your question in the most public forum that the question is relevant to.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This could be StackOverflow if you have questions that aren’t specific to your particular project or company, or it could be a company issue tracker or Q&amp;amp;A platform. If you can ask it somewhere where it’s easy to find it later that’s best, but if not, the appropriate Teams or Slack channel is also fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But if I do that, people don’t answer my question!&lt;/strong&gt;&lt;br&gt;
Some teams have cultures where people are slower to help out if not explicitly asked, and some teams have cultures where people are eager.&lt;br&gt;&lt;br&gt;
You can still ask questions in public - just make sure to tag the people who you would normally write to in private.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But I’m afraid to look stupid if everyone can see I don’t know something?&lt;/strong&gt;&lt;br&gt;
That’s very human. But not knowing stuff stuff is part of the game. If you ask good questions, no one will judge you for them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Share The Answer
&lt;/h1&gt;

&lt;p&gt;Sometimes you can’t get your answer in a public forum. Maybe you’ll have to explain the problem in-person or do some extra troubleshooting with someone. That happens. When it does, you should always write down the answer where you asked the question.&lt;br&gt;&lt;br&gt;
Perhaps your colleagues who tried to help you are curious, or perhaps they will struggle with similar questions. Asking questions in public doesn’t help much if you don’t also share the answers in public.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ask Good Questions
&lt;/h1&gt;

&lt;p&gt;A lot of stuff has been written about asking good questions. &lt;a href="https://jvns.ca/blog/good-questions/"&gt;This guide&lt;/a&gt; is excellent and friendly, and &lt;a href="http://www.catb.org/~esr/faqs/smart-questions.html"&gt;this guide&lt;/a&gt; is also excellent - but much less friendly.&lt;/p&gt;

&lt;p&gt;You should read those guides - but quickly summing up there’s two things you should consider when you ask someone a question:&lt;/p&gt;

&lt;p&gt;Did you give them enough information to understand your question?&lt;br&gt;&lt;br&gt;
Your message should contain enough information that anyone reading doesn’t need to ask any follow-up questions to understand what your problem is. So read your message before sending it, and consider whether or not you’ve provided enough information.&lt;/p&gt;

&lt;p&gt;Have you given them enough information to answer your question?&lt;br&gt;&lt;br&gt;
Most problems can have many potential issues. You need to explain whether or not you have any theories as to what’s going on, and what you have already tried to solve the problem.&lt;/p&gt;

&lt;p&gt;If someone is going to answer your question, they’ll need this information. So either you’ll write it down at the start or they’re going to ask you for it. Let’s save them some time and give them all the information right off the bat.&lt;/p&gt;

&lt;p&gt;Asking good questions is hard and a skill that takes a while to master. But we can always try to improve our communications. Try noticing if you often have exchanges where someone misunderstands your question or asks for clarification - and try to see if you can do better.&lt;/p&gt;

</description>
      <category>communication</category>
      <category>softwaredevelopment</category>
      <category>remoteworking</category>
    </item>
    <item>
      <title>How Microsoft Teams Kills Knowledge Management</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Thu, 19 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/how-microsoft-teams-kills-knowledge-management-npp</link>
      <guid>https://dev.to/geewee/how-microsoft-teams-kills-knowledge-management-npp</guid>
      <description>&lt;p&gt;Microsoft Teams seems like it’s trying to be the one-stop tool for all your organisational needs. I think it works fine for chat and calls, but for knowledge management it is extremely unimpressive, often making things much harder than they need to be. Here’s four ways Teams is killing your knowledge management.&lt;/p&gt;

&lt;h1&gt;
  
  
  Important and Irrelevant files are mixed
&lt;/h1&gt;

&lt;p&gt;Teams has a “Files” tab where you can save files that are relevant for a channel.&lt;br&gt;&lt;br&gt;
The concept is good, but unfortunately it’s plagued by an unfortunate decision: &lt;em&gt;If anyone posts a file inside a conversation it’s uploaded to the Files tab.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This makes it impossible to distinguish between these two scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This file is here because someone consciously chose to save it so you could look at it&lt;/li&gt;
&lt;li&gt;This file is here because someone needed to share it that one time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which means that the top level folder quickly becomes an interspersed mess of really important stuff™ and stuff that doesn’t matter at all.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Wiki Is Unsearchable
&lt;/h1&gt;

&lt;p&gt;Teams also has a wiki functionality where each channel gets its own wiki tab.&lt;br&gt;&lt;br&gt;
That’s wonderful - you and your team can share information and collaboratively edit it!&lt;/p&gt;

&lt;p&gt;Except the information can be almost impossible to find again, because there’s no way to search for a specific wiki page or the content inside it.&lt;/p&gt;

&lt;p&gt;This means that if you want to find something you have to either know exactly what channel and wiki page it’s located at, or go meandering through all the wikis of all your channels. Writing down stuff isn’t worth anything if you don’t easily let people find it again.&lt;/p&gt;

&lt;h1&gt;
  
  
  You Can’t Search For Directories
&lt;/h1&gt;

&lt;p&gt;But for files, at least you can group them inside directories and then easily find those again right?&lt;/p&gt;

&lt;p&gt;For example, we have a directory inside one of our channels called “Books” for, well, books. And if I want to find the books, I can just search for “Books” and Teams will surely get me the directory right?&lt;br&gt;&lt;br&gt;
Not a chance buddy. Teams only shows you files, not directories.&lt;/p&gt;

&lt;p&gt;This means that to figure out what’s in a directory you either have to remember the channel it was in and find it that way, or go search through SharePoint, which luckily manages to get it right.&lt;/p&gt;

&lt;h1&gt;
  
  
  You Can’t Archive Channels
&lt;/h1&gt;

&lt;p&gt;Often you create channels for projects or events, and those channels at some point become irrelevant.&lt;br&gt;&lt;br&gt;
Teams makes it very easy to be stuck with those channels forever. You can delete them - but what if there’s information in there you might need later?&lt;/p&gt;

&lt;p&gt;There’s no way to mark that a channel isn’t active anymore. The best thing you can do is rename it and have everyone hide it so it doesn’t show up all the time - but that’s a real band-aid solution.&lt;/p&gt;




&lt;p&gt;While Teams has come a long way for chat, it’s still lagging behind in regards to all the auxiliary functionality it offers.&lt;br&gt;&lt;br&gt;
It seems like it wants to do everything. Unfortunately it doesn’t do any of the things particularly well.&lt;/p&gt;

&lt;p&gt;Many of these issues have been open on Microsoft UserVoice for years, with tens of thousand of votes, and no response from Microsoft.&lt;/p&gt;

&lt;p&gt;So if you haven’t moved your wikis and file management to Teams yet - I’d suggest you wait a year or two. But if you have, like us, and the cost of switching away is too high, there’s nothing to do but arm yourself with a truckload of patience.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Being In A Hurry Makes You Slower</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Sun, 01 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/being-in-a-hurry-makes-you-slower-5f6k</link>
      <guid>https://dev.to/geewee/being-in-a-hurry-makes-you-slower-5f6k</guid>
      <description>&lt;p&gt;Not too long ago I was working on an unfamiliar project, with a technology stack I didn’t really know. I had a short deadline, and (what I thought was) a pretty short assignment. Turns out it wasn’t. Every time I thought I was done the requirements shifted slightly and every time I thought I had solved the last bug a new one appeared.&lt;/p&gt;

&lt;p&gt;Because I was pressed for time, I did two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.gustavwengel.dk/death-spirals"&gt;I cut corners&lt;/a&gt;. I didn’t refactor things I should have and I should have tested things I didn’t. I didn’t feel like I had time to do those things - but I also didn’t always know exactly how. This leads to my next point:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I neglected to learn the things I needed. I felt like I couldn’t justify the time spent to learn how to do X properly, when I didn’t have very much time to do X in the first place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In another world where the task had been as small as we thought, these could have been the right decisions.&lt;br&gt;&lt;br&gt;
However as soon as the task became just a little bigger than we thought, neglecting to &lt;a href="https://www.franklincovey.com/the-7-habits/habit-7.html"&gt;learn my tools&lt;/a&gt; properly made me much less effective. I traded a short-term benefit for a long-term loss.&lt;/p&gt;

&lt;p&gt;I’m not saying you should always spend the time to learn how to do everything properly. But if you’re always in a hurry, and you never get the time to slow down, you might have an issue. Likewise, if you have a short deadline for something and you decide that it’s not worth the time, but then the deadline shifts - it’s time to re-evaluate. A deadline and scope that shifts once, will probably shift again.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How To Not Get Blocked While You’re Waiting For A Code Review</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Wed, 23 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/how-to-not-get-blocked-while-you-re-waiting-for-a-code-review-170c</link>
      <guid>https://dev.to/geewee/how-to-not-get-blocked-while-you-re-waiting-for-a-code-review-170c</guid>
      <description>&lt;p&gt;You’ve made your awesome new Pull Request, but the person who has to review it won’t have time for several hours.&lt;br&gt;&lt;br&gt;
While we all strive to review code as fast as possible, there’s always going to be delays.&lt;br&gt;&lt;br&gt;
So what do you do while you’re waiting for that review?&lt;br&gt;&lt;br&gt;
There’s always the coffee machine, but if you’re going to be hanging out there for hours, people might start asking questions like &lt;em&gt;“Why are you here all the time?”&lt;/em&gt;, &lt;em&gt;“Is that much coffee healthy for you”&lt;/em&gt; and &lt;em&gt;“Please stop staring at me”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s three ways to avoid those comments and keep working, while you’re waiting for a code review&lt;/p&gt;

&lt;h2&gt;
  
  
  Work On Something Else In The Codebase
&lt;/h2&gt;

&lt;p&gt;A good strategy is to always have at least two tasks you can work on - preferably tasks that have as little as possible to do with each other.&lt;br&gt;&lt;br&gt;
That way, when you’re done with your first task, you can branch out from your main branch again to do some completely unrelated work.&lt;/p&gt;

&lt;p&gt;Examples of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your first PR was on the backend, start working on something in the frontend or vice versa.&lt;/li&gt;
&lt;li&gt;After your PR, find a juicy bug to hunt down and fix. Generally switching between developing new features and bug-fixing works well.&lt;/li&gt;
&lt;li&gt;Or just find another issue to solve that doesn’t have any overlap in the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--taJQZBOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/git-diagrams/simultaneous-branches.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--taJQZBOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/git-diagrams/simultaneous-branches.svg" alt=""&gt;&lt;/a&gt;&lt;em&gt;Here we see two branches branch out from main. When your first branch is ready for review, start the second branch and keep working.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To me this is one of the most effective ways to keep your velocity up, but it requires that you can juggle multiple tasks (and that there are multiple tasks to juggle)&lt;/p&gt;

&lt;h2&gt;
  
  
  Do Something Non Code-Related
&lt;/h2&gt;

&lt;p&gt;There’s a lot to do in software development that isn’t just software development. There’s a lot of possible tasks we can do that don’t have anything to do with the code. These tasks are perfect to spend time on while waiting for review. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answer emails&lt;/li&gt;
&lt;li&gt;Review a pull request from someone else&lt;/li&gt;
&lt;li&gt;Write documentation&lt;/li&gt;
&lt;li&gt;Write or break down tasks&lt;/li&gt;
&lt;li&gt;Help a co-worker with something&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or just take a break so you’re ready to start working again afterwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue Working From The Same Code
&lt;/h2&gt;

&lt;p&gt;Unfortunately it’s not always feasible to do something else.&lt;br&gt;&lt;br&gt;
Sometimes there’s only one thing to work on - and you have to base your work on the stuff you’ve just submitted in your PR.&lt;br&gt;&lt;br&gt;
You can branch out from the branch you’re looking to merge into master.&lt;br&gt;&lt;br&gt;
This means that while you’re waiting for the branch, you can simply continue working. You can then merge in the first branch, and later on the second one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nxz2Q3pS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/git-diagrams/branch-from-branch.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nxz2Q3pS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/git-diagrams/branch-from-branch.svg" alt=""&gt;&lt;/a&gt;&lt;em&gt;An example of this workflow. When you're done with your first branch, you create a PR, but also a new branch, based on the first branch.Then you can keep working, while keeping all your original changes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some caveats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re expecting to get a lot of feedback in your original Pull Request, you will probably have to deal with some merge conflicts when merging your second branch in.&lt;/li&gt;
&lt;li&gt;If you squash your commits when merging PR’s in - this becomes quite a bit more problematic. You’re going to have to do a few merges or rebases to make your second branch merge cleanly. However usually for large branches, this doesn’t take more than a few minutes.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>4 Ways To Make Your Pull Requests Faster To Review</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Tue, 22 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/4-ways-to-make-your-pull-requests-faster-to-review-43pc</link>
      <guid>https://dev.to/geewee/4-ways-to-make-your-pull-requests-faster-to-review-43pc</guid>
      <description>&lt;p&gt;It can be frustrating to wait for someone to review your pull request.&lt;br&gt;&lt;br&gt;
While everyone is interested in pull requests getting reviewed as fast as possible, reviewing code takes time.&lt;br&gt;&lt;br&gt;
Here’s 4 ways to make your pull request as easy to read, and as fast to review as possible.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Keep It Short
&lt;/h1&gt;

&lt;p&gt;Pull Requests that are shorter, are much faster to review.&lt;/p&gt;

&lt;p&gt;The shorter your pull request is - the better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s easier to think through each change and how it interacts with the other changes. This means the review process will take less time.&lt;/li&gt;
&lt;li&gt;It takes less time to review. While a short PR can be done when you have 20 minutes of downtime, a longer one might require finding several hours in the calendar.\
Which one do you think will be looked at faster?&lt;/li&gt;
&lt;li&gt;Studies indicate that shorter PR’s lead to finding more issues - if your PR has 300 lines, the reviewer will read them carefully, but if it has 2000 they will skim it.\
Shorter PR’s make the reviews more impactful&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  2. Split Your Changes Up
&lt;/h1&gt;

&lt;p&gt;To keep pull requests short, you’ll often need to split the work you’re doing up into multiple pull requests.\&lt;br&gt;&lt;br&gt;
While working, you might spot something that needs to be refactored, or a rename of a field that will touch many files.&lt;/p&gt;

&lt;p&gt;Don’t make the changes directly in your branch - instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Branch out from main again and do the refactoring&lt;/li&gt;
&lt;li&gt;Create a PR with the refactoring into main&lt;/li&gt;
&lt;li&gt;Continue work on your original branch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of having one PR that touches many files, you’ll have two isolated PR’s. Each which does only one thing.&lt;/p&gt;

&lt;h1&gt;
  
  
  3 Write A Good Description
&lt;/h1&gt;

&lt;p&gt;The reviewer has to understand what was changed in the PR and why. The easier you make this - the faster the review.&lt;/p&gt;

&lt;p&gt;You should add a clear description that tells the reviewers what changes the PR contains and the purpose of them - sort of like an introduction to the code.&lt;br&gt;&lt;br&gt;
This description can also help future-you. When you’re looking at that code in six months, good commit messages and pull request descriptions are invaluable.&lt;/p&gt;

&lt;p&gt;If anything needs to be manually tested by the reviewer to ensure that it works, make sure to also include a short description on how the reviewer can test this. In complex cases, it might also be beneficial to describe what result the reviewer should expect from running it.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Leave Comments For The Reviewer
&lt;/h1&gt;

&lt;p&gt;It’s okay to write comments in the PR for the reviewer.&lt;br&gt;&lt;br&gt;
These comments can be used to proactively describe file moves or other things, you might expect the reviewer to ask questions about.&lt;br&gt;&lt;br&gt;
Note that these comments are different from comments you’d normally leave in the code. They’re codes that might not be relevant in six months, but which are relevant when the reviewer is looking at the code now. Examples could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you’ve moved part of a file to somewhere else, leave a comment. This way the reviewer doesn’t have to wonder why git has marked something as deleted, when in reality it has just moved.&lt;/li&gt;
&lt;li&gt;When choosing a solution that doesn’t seem obvious at first glance, you might want to note what other solutions you’ve tried and why they didn’t work.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Doing all of these things might seem like extra work, but most times the 10 minutes you spend on creating a good, reviewable PR, are saved in terms of less back and forth with questions and discussions between you and the reviewer&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Work Efficiently With Pull Requests</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Mon, 21 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/how-to-work-efficiently-with-pull-requests-d77</link>
      <guid>https://dev.to/geewee/how-to-work-efficiently-with-pull-requests-d77</guid>
      <description>&lt;p&gt;I’ve experimented a bit with different kinds of pull requests during the years - and I think this way of doing them is the Two Pass Pull Request. I like to name it that - because there’s one pass made by you, and one pass made by the reviewer. Let’s take a look at how, and why, it works.&lt;/p&gt;

&lt;h1&gt;
  
  
  First Pass
&lt;/h1&gt;

&lt;p&gt;You’ve branched out, made some changes and you’re ready to get them merged in.&lt;br&gt;&lt;br&gt;
The first thing you do is to create a Pull Request just for your eyes - a Draft PR.&lt;br&gt;&lt;br&gt;
You can do this by marking the PR as a draft or prefixing the title with &lt;em&gt;[WIP]&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Make sure to write a good, but short description for the PR. Explain both what changes have been made and why. This will help both the reviewer look at the changes, but will also help future-you when you look back through the history.&lt;/p&gt;

&lt;p&gt;The description should also describe how the reviewer can validate that the code works as it should. This can be as complex as “Do X and Y, and then validate that Z happens”, or it can be as simple as “See the tests”&lt;/p&gt;

&lt;p&gt;After you’ve created the draft PR, this is your time to go through it and make sure your code is up to snuff.&lt;br&gt;&lt;br&gt;
Go through each file. If something needs changing, change it immediately before moving onto the next file.&lt;/p&gt;

&lt;p&gt;Things you might want to look for / change in the code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove any code you’ve commented out instead of deleting&lt;/li&gt;
&lt;li&gt;Change names so they’re descriptive&lt;/li&gt;
&lt;li&gt;Refactor code if necessary&lt;/li&gt;
&lt;li&gt;Add comments to code that are not self-explanatory, such as complex workarounds or reasons WHY some code does what it does&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While reviewing the code, there’s a few other tasks you might want to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the PR description if you’ve made more changes than you first thought&lt;/li&gt;
&lt;li&gt;Leave thoughtful comments for your reviewer. If you’ve moved some stuff from one file to another, git will mark it as added/deleted. If you leave a comment saying “Moved to X” you save the reviewer from wondering why something was deleted and then having to review the moved code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unless you’ve made large changes, you don’t need to check the PR again.&lt;br&gt;&lt;br&gt;
You might have missed a few things, but that’s fine. It’s hard to keep re-reading the same PR without just skimming over it, so it’s not worth the time. Anything you’ve missed will be caught in the next pass.&lt;br&gt;&lt;br&gt;
After this first pass, you’ve looked at the Pull Request, and made any changes you needed. This Pull Request is now no longer a draft. Remove the [WIP] or draft status. &lt;/p&gt;

&lt;h2&gt;
  
  
  Second Pass
&lt;/h2&gt;

&lt;p&gt;This is the second pass - by someone else than you. &lt;br&gt;
Inform the reviewer about the PR, either through a direct message or through tagging them as a reviewer.&lt;/p&gt;

&lt;p&gt;The reviewer will look at the description, and validate that the code works as it should, based on the description.&lt;br&gt;&lt;br&gt;
After that, the reviewer looks at the code, to find errors or possible refactorings. There are many articles describing what a good review is, so I’m not going to recap them here.&lt;/p&gt;

&lt;p&gt;The reviewer should leave comments/suggestions that are detailed enough, that you can resolve the issues without asking them for further clarification.&lt;/p&gt;

&lt;p&gt;The reviewer should write what is needed for the pull request to be approved. This can range from: &lt;em&gt;“You can merge this in once you’ve fixed X”&lt;/em&gt; to &lt;em&gt;“I’d like to discuss X with you before we merge this in”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Azure DevOps has a handy “Approve with suggestions” feature, that essentially makes the reviewer say “I can approve everything here as is, but I have some suggestions I believe you can handle yourself”.&lt;/p&gt;

&lt;p&gt;Sometimes the reviewer might suggest changes that mainly differ in style, rather than substance, often phrased as &lt;em&gt;“This is good, but if it was me, I would change it to X instead, because Y.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
In these situations, you decide whether or not to go with the suggestion - it is an optional suggestion. It can be beneficial to prepend such comments with a pre-approved-upon word that clearly states that it is optional, such as “optional” or “nitpick”.&lt;/p&gt;

&lt;p&gt;After the second pass, you can go through your PR and fix the issues that the reviewer has flagged. If the issues are small enough and the comments are good enough, you should be able to do this without asking the reviewer again.&lt;/p&gt;

&lt;p&gt;However, if there are comments that are hard to understand, you disagree about something, or there’s something you need to discuss about how to best solve - you should answer the comments, or reach out to the reviewer so you can find a proper conclusion.&lt;/p&gt;

&lt;p&gt;When you think the issues have been resolved, you merge the PR into the main branch yourself. The reviewer never does it for you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You Aren’t Going To Need It - Yet</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Mon, 07 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/you-aren-t-going-to-need-it-yet-jhk</link>
      <guid>https://dev.to/geewee/you-aren-t-going-to-need-it-yet-jhk</guid>
      <description>&lt;p&gt;You’re on a project. You’re developing an API to count the amount of apples in a cart. You expect to have it done, and people using it in 6 months.&lt;br&gt;&lt;br&gt;
Obviously this API needs to be documented, after all you don’t want your consumers to have to guess how it works.&lt;br&gt;&lt;br&gt;
You all agree, that when writing a new endpoint you’ll document it properly.&lt;br&gt;&lt;br&gt;
Four months later it’s looking good - you have a bunch of endpoints that are beautifully documented.&lt;/p&gt;

&lt;p&gt;Oops, turns out someone had misunderstood something. You actually need to count occurrences of different fruits from the cart. And there’s multiple carts.&lt;br&gt;&lt;br&gt;
Well, that’s life. We’re agile. Requirements change.&lt;br&gt;&lt;br&gt;
So now it’s time to create some new endpoints. And document them. All over again.&lt;/p&gt;




&lt;p&gt;In hindsight, the right call here would be to write the documentation at the end, when the API had stabilized. Could we have known this in advance?&lt;/p&gt;

&lt;p&gt;When deciding when to perform tasks, there’s a few things we might want to take into consideration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Can the task be delayed?&lt;/strong&gt;&lt;br&gt;
If we have someone who needs this done in six months, and it’ll take us six months to create, we obviously can’t delay it. In our example, the documentation probably wouldn’t take more than a few weeks at most - meaning that we could have delayed it until then.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Does completing the task create value right away, or only in the future?&lt;/strong&gt;&lt;br&gt;
Some tasks, like tests, create value the minute they’re created. Documentation for external consumers doesn’t. It only creates value when the external users start using the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is the price to maintain the task, when requirements change?&lt;/strong&gt;&lt;br&gt;
I like to call this the &lt;em&gt;upkeep&lt;/em&gt;. Different tasks have different upkeeps.  The upkeep for maintaining API documentation for five endpoints is low. The upkeep for maintaining pages of tutorials, quickstart examples etc, is much higher.  The higher the upkeep, the riskier it is to do too early.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How uncertain are the requirements?&lt;/strong&gt;&lt;br&gt;
Are we in a mature stable project, or in the wild west, in regards to requirements? The more mature and sure we are about the requirements, the less we need to be afraid of tasks with high upkeep.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The Right Task For The Wrong Time
&lt;/h1&gt;

&lt;p&gt;Let’s look at a real-life example where I wasted quite a bit of time, doing a task at the wrong time.&lt;/p&gt;

&lt;p&gt;I used to work at a project with reasonably complex cloud infrastructure.&lt;/p&gt;

&lt;p&gt;At the start of the project, I spent a week or two writing scripts to automatically create the whole cloud environment.&lt;br&gt;&lt;br&gt;
Six months later as the project evolved, many of the cloud components changed.&lt;/p&gt;

&lt;p&gt;Every time a cloud component changed, I had to change the scripts. Doing that could easily take a few hours, and at this point in time, we didn’t really use them very much.&lt;/p&gt;

&lt;p&gt;Let’s try to use the questions to see whether or not we could’ve been smarter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Can the task be delayed?&lt;/strong&gt;&lt;br&gt;
Yes. We did this because we figured it would pay off in the long run. We figured we would save time each time we had to provision a new environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Does completing the task create value right away, or only in the future?&lt;/strong&gt;&lt;br&gt;
It only creates value when we have to provision new environments, and as mentioned before - we rarely did that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is the price to maintain the task when requirements change?&lt;/strong&gt;&lt;br&gt;
It was very high. Provisioning scripts are impossible to test, and can take quite a while to run. Using a few hours every time a service changed was not unusual.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How uncertain are the requirements?&lt;/strong&gt;&lt;br&gt;
We made this decision in the start of the project, when we were very uncertain about the requirements and the cloud services we needed. If I’d been smarter, I would have realized that this meant I should have postponed this work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, we should have realized that the value gain wasn’t worth the cost. Particularly not when we were this early in the project. The right call would have been to build the scripts, when provisioning environments by hand happened so often, it became a major pain point. This might never have happened, and we never would have written the scripts. &lt;a href="http://agilemanifesto.org/principles.html"&gt;We would have maximized the amount of work not done.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So next time you’re about to start a large task, ask yourself “Is this the right time to do this?” - just maybe it’ll save you from doing it multiple times.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My publishing workflow</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Tue, 18 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/my-publishing-workflow-5ebb</link>
      <guid>https://dev.to/geewee/my-publishing-workflow-5ebb</guid>
      <description>&lt;p&gt;I’m trying to get a little more structured when it comes to how I publish and syndicate the content I write.These are primarily my notes to myself about my process, but maybe you’ll find them interesting.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Write in Google Docs
&lt;/h3&gt;

&lt;p&gt;I’ve tried a couple of different ways to write, including plain text editors, using markdown and using a collaborative editor like Google Docs.I used to author my posts in markdown, but I’ve since gone away from that for the following reasons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s much easier to collaborate and get feedback and reviews. A markdown file published to github somewhere is much less accessible than Google Docs, where reviewers can leave actual comments.&lt;/li&gt;
&lt;li&gt;It’s just a little easier. In markdown you’re free to add spaces to the lines, but you also have to manual do line breaking, and you need a separate window open to check the output of your work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Convert it into markdown
&lt;/h3&gt;

&lt;p&gt;When you’re done writing in Google Docs, you can (reasonably) easily convert it into markdown, by using something like &lt;a href="https://euangoddard.github.io/clipboard2markdown/"&gt;clipboard2markdown&lt;/a&gt;.It’s not perfect, and e.g. it doesn’t convert headings automatically. But it will get you 95% of the way there, and the rest doesn’t take that long.It’s primarily about adding heading, checking everything through once, and adding some images if needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Publish to own website
&lt;/h3&gt;

&lt;p&gt;When I’ve then made my post into markdown, I publish it here at &lt;a href="//www.gustavwengel.com"&gt;www.gustavwengel.com&lt;/a&gt;.It’s a Jekyll based blog which uses markdown, so when I have the markdown from above, I’m basically good to go.I use the &lt;a href="https://github.com/jekyll/jekyll-feed"&gt;jekyll-feed&lt;/a&gt; plugin to automatically create an RSS feed based on my content as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Syndicate To Other Platforms
&lt;/h3&gt;

&lt;p&gt;The main reason I write, is because it helps me to learn and that I enjoy it. With that being said - I get immense joyfrom someone telling me that they enjoyed something I’ve written.Because of that, I also try to syndicate the content to some different platforms to get a bunch of different eyes on it.&lt;/p&gt;

&lt;p&gt;I syndicate content to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@geewee"&gt;Medium&lt;/a&gt;Say what you will about the UX these days, but the Import Feature of Medium is very nice to use. Apart from code blockswhich the auto-importer doesn’t get, syndicating to medium is pretty frictionless.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/geewee"&gt;Dev.to&lt;/a&gt;Dev.to is a nice developer community. It gives you the ability to automatically import your stories from your RSS feeds as drafts.This functionality works extremely well, and I almost don’t have to do anything to make the stories work on dev.to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m also considered syndicating to Hackernoon, but I never really got around to switching over after they moved off, of Medium.I also don’t know how big their reach is anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Post on social media
&lt;/h3&gt;

&lt;p&gt;I’m part of a couple of communities on social media, primarily twitter, hacker news and the subreddits /r/csharp and /r/programming.If I think the post might speak to an audience in any of these groups, I also try to share them there.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>On Inclusive Language In Tech</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Sun, 05 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/on-inclusive-language-in-tech-29e9</link>
      <guid>https://dev.to/geewee/on-inclusive-language-in-tech-29e9</guid>
      <description>&lt;p&gt;Twitter &lt;a href="https://mobile.twitter.com/twittereng/status/1278733305190342656"&gt;recently announced&lt;/a&gt; that they’re beginning to change many of the words they use, to “more inclusive” variants.They announced this on twitter. Which of course meant everyone wanted to fight about it.&lt;br&gt;&lt;br&gt;
How much of this is just white silicon valley folks changing words they think are offensive? Is this cancel culture just with words? Does this actually matter or is it just virtue signalling?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qo3QufJS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/twitter-inclusive-language.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qo3QufJS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/twitter-inclusive-language.jpg" alt=""&gt;&lt;/a&gt;The words twitter are changing, and what they're changing them to.&lt;/p&gt;

&lt;p&gt;Honestly I’m not sure how much the inclusive language matters in regards to minorities. I haven’t heard many members of actual minority groups say that this matters to them.But considering that tech has a huge diversity problem, perhaps this isn’t so surprising - there aren’t that many people to speak up.&lt;/p&gt;

&lt;p&gt;So let’s sidestep that discussion for a moment, and talk about another argument for making these changes. Most of the new terms are &lt;strong&gt;better&lt;/strong&gt;!&lt;br&gt;&lt;br&gt;
At least if &lt;em&gt;you don’t know the old ones already&lt;/em&gt;. People naturally prefer the terms they’re used to, because things we’re used to seem natural and right.&lt;br&gt;&lt;br&gt;
But I think if you’re just getting into tech, many of the new terms are better. They’re more self-explanatory and descriptive:&lt;/p&gt;

&lt;h2&gt;
  
  
  Blacklists and Denylists
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;blacklist&lt;/code&gt; and &lt;code&gt;whitelist&lt;/code&gt; have the advantages of piggybacking on “regular” english words.But we’re creating technical terms here, so we don’t &lt;em&gt;have&lt;/em&gt; to use existing words, if a better alternative exist.Using &lt;code&gt;allowlist&lt;/code&gt; and &lt;code&gt;denylist&lt;/code&gt; have some wonderful advantages. They’re self-contained and very explicit. The first time you read about an &lt;code&gt;allowlist&lt;/code&gt;, you know exactly what it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Masters or Leaders
&lt;/h2&gt;

&lt;p&gt;I particularly like changing the &lt;code&gt;master/slave&lt;/code&gt; terminology to something that’s more nuanced. Often it seems like every relationshipwhere there’s a primary (or master) instance, we describe it as a &lt;code&gt;master/slave&lt;/code&gt; relationship.But we can do better than that. If we describe it as &lt;code&gt;primary/standby&lt;/code&gt;, we get extra information. There’s a primary instance, &lt;em&gt;and the role of the follower instance is to be a standby in case of errors&lt;/em&gt;.Changing &lt;code&gt;master/slave&lt;/code&gt; means that we get to use much more expressive terminology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dummies vs. Placeholders
&lt;/h2&gt;

&lt;p&gt;I think &lt;code&gt;placeholder value&lt;/code&gt; is a much better term than &lt;code&gt;dummy value&lt;/code&gt;. It’s much more explicit.&lt;br&gt;&lt;br&gt;
You might think &lt;code&gt;dummy value&lt;/code&gt; is pretty explicit already - but I’d argue it’s not.As an international developer, I had no idea that you could “dummy up” something fake.I knew that &lt;code&gt;dummy&lt;/code&gt; could mean something that resembled the real thing, but I’d never made the connection betweenthat and &lt;code&gt;dummy value&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
It was just one of those terms I used because &lt;em&gt;that’s what we call it._Contrast that with &lt;code&gt;placeholder value&lt;/code&gt; - which says _exactly&lt;/em&gt; what it is.&lt;/p&gt;




&lt;p&gt;A lot of these new words meet resistance. Partly because they’re new, and partly because people disagree on whether or not they’re racist, and if it matters.&lt;br&gt;&lt;br&gt;
I think we should try to keep the broader picture in mind.Generations of people are going to have to learn these terms and use these words in the future. We owe it to them to pick the best damn ones.&lt;br&gt;&lt;br&gt;
Even if it does inconvenience us slightly.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Death Spirals and Working Too Damn Hard</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Mon, 08 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/death-spirals-and-working-too-damn-hard-4o05</link>
      <guid>https://dev.to/geewee/death-spirals-and-working-too-damn-hard-4o05</guid>
      <description>&lt;p&gt;Recently I’ve been thinking a lot about what I call &lt;em&gt;Death Spirals&lt;/em&gt;. The name might be a bit much but I like the dramatic flair.&lt;/p&gt;

&lt;p&gt;A Death Spiral is a special kind of positive feedback loop.A positive feedback loop is something that’s self-reinforcing.Examples of positive feedback loops:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you have a lot of followers on social media, more people view and share your content. When more people share it, more people see it and follow you. The more followers you have, the easier it is to get new ones.&lt;/li&gt;
&lt;li&gt;When you’re out of shape, exercise is harder so you’re less likely to do it. The less likely you are to exercise, the more you become out of shape, the less likely you are to exercise, and so it goes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Death Spiral
&lt;/h2&gt;

&lt;p&gt;A Death Spiral is special kind of positive feedback with some unique characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking out of it requires more resources than you currently have&lt;/li&gt;
&lt;li&gt;The longer you’re in it, the harder it is to break out of it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Death Spirals can happen for many reasons and hit both companies and individuals. Let’s take a look at two examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jane And Her Diabetes
&lt;/h2&gt;

&lt;p&gt;Jane has diabetes. She hasn’t responded well to any medicine&lt;sup id="fnref:0"&gt;1&lt;/sup&gt; and she’s feeling very sick.Her doctor tells her that exercise will help her.&lt;br&gt;&lt;br&gt;
Jane’s symptoms are so severe that after coming home from work she has no energy left to exercise.&lt;br&gt;&lt;br&gt;
Jane is in a Death Spiral. Her diabetes will continually get worse. As it gets worse, she gets and less energy for exercising.The longer she waits, the harder it becomes to break out.&lt;/p&gt;

&lt;h2&gt;
  
  
  JojaCo: The Burnout Factory
&lt;/h2&gt;

&lt;p&gt;Death Spirals happen to companies too. One of my good friends used to work at a company &lt;em&gt;JojaCo&lt;/em&gt;.JojaCo helped their customers manage technical infrastructure.&lt;/p&gt;

&lt;p&gt;JojaCo employees were a little overworked. Then someone became long-term sick. Fewer people had to do the same work.To get all of the new work done on time, the employees had to cut some corners.&lt;/p&gt;

&lt;p&gt;The company used to have documentation for each customer describing how to make changes in their systems.You usually updated this after interacting with a customer.This documentation slowly stopped being up-to-date as no one had time to update it anymore.&lt;br&gt;&lt;br&gt;
While not updating it saved time in the short run, helping the customer the next time took much longer.This meant that the employees got further behind, and had to cut even more corners.&lt;/p&gt;

&lt;p&gt;In a stressful environment like this, people started falling ill due to stress. This left even more work for fewer people.At the end my friend was working 70+ hours a week.He was miserable. Everyone were sick or quitting, and new hires didn’t stick around for long.&lt;/p&gt;

&lt;h1&gt;
  
  
  Breaking Out of Death Spirals
&lt;/h1&gt;

&lt;p&gt;So how &lt;em&gt;do&lt;/em&gt; you break out of a Death Spiral? You somehow have to find energy and resources you don’t have.This can be extremely difficult, and if there is a step-by-step guide I haven’t found it.&lt;br&gt;&lt;br&gt;
These are my best bets:&lt;/p&gt;

&lt;h2&gt;
  
  
  Do Less
&lt;/h2&gt;

&lt;p&gt;If you don’t have to do as much, you’ll have more resources to break free of the Death Spiral.&lt;/p&gt;

&lt;p&gt;If you’re JojaCo you can call up some of your customers, and tell them that you can’t currently help them.They probably won’t be your customers in the future. But it might save you from losing other customers because your employees are burned out.&lt;/p&gt;

&lt;p&gt;If you’re Jane, try to take some days off from your job and use them to start exercising.Or maybe you can do find a routine that requires less chores, or try some healthy meal box services.&lt;/p&gt;

&lt;p&gt;“Do less” is advice that’s easy to give, but &lt;em&gt;really&lt;/em&gt; hard to follow.It’s not always possible to do less. Your boss might not let you take days off. You might not be able to pay yoursalaries if you turn away some of your customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get help
&lt;/h2&gt;

&lt;p&gt;If you can’t reduce the amount of work, you might be able to share it among more people.More people to do the same work means there’s less work for everyone.&lt;/p&gt;

&lt;p&gt;JojaCo could hire new employees or temps.&lt;br&gt;&lt;br&gt;
Jane could get someone to run with, or help her with some of the other responsibilities she has.&lt;/p&gt;

&lt;p&gt;Getting help isn’t always easy though. Perhaps you don’t have the social support to find someone to run with.Maybe you can’t afford or find qualified people to work at JojaCo.&lt;/p&gt;




&lt;p&gt;Death Spirals are particularly tricky because there’s often no easy way out once you’re in them.Often we keep struggling along, while hoping that something will change.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perhaps you’ll wake up one day, invigorated with new energy to start exercising.&lt;/li&gt;
&lt;li&gt;Perhaps your employee will stop getting sick from stress soon.&lt;/li&gt;
&lt;li&gt;Perhaps things will improve somehow, even though you’re not really sure how.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don’t think Death Spirals usually correct themselves until you hit rock bottom.We just stay in that slow, steady decline, because all the ways to break free are either impossible or requireschoices we can’t get ourselves to make.&lt;/p&gt;

&lt;p&gt;So here’s my plea to you: If you observe someone in a Death Spiral - say something.Breaking free without help can be extremely difficult. It’s okay to ask if someone needs help.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do you have any experiences with death spirals? How did you get out of it? I’d really like to hear some other opinions or stories!&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m not actually sure if there are people who don’t respond well to diabetes medicine. However I have seen the situation play out in real life with people who were unwilling to take it. ↩&lt;/p&gt;

</description>
    </item>
    <item>
      <title>5 Reasons To Not Use Observables in C#</title>
      <dc:creator>Gustav Wengel</dc:creator>
      <pubDate>Wed, 29 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/geewee/5-reasons-to-not-use-observables-in-c-518l</link>
      <guid>https://dev.to/geewee/5-reasons-to-not-use-observables-in-c-518l</guid>
      <description>&lt;p&gt;When I was first introduced to Observables in C#, they sounded pretty damn good.“They just model streams of data”, “It’s just data over time” and “It’s just the push equivalent of an IEnumerable”.After working with them for a little while, I don’t think they’re as good as I was told.&lt;/p&gt;

&lt;p&gt;The statements above might be true. Observables might be simple from a birds-eye perspective. Unfortunately simple doesn’t always mean easy and there’s are some things that will end up biting you in the ass.Here’s five of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework Has No Consistent Name
&lt;/h2&gt;

&lt;p&gt;When searching for documentation and solutions to problems with Observables, I always felt like I didn’t know what to search for.Previously I’ve always known the terms to use, &lt;code&gt;django {your-problem-here}&lt;/code&gt;, &lt;code&gt;serilog {how-to-do-x}&lt;/code&gt; &lt;code&gt;{framework}-{problem description}&lt;/code&gt;&lt;br&gt;&lt;br&gt;
However with Observables I had a lot of problems finding people encountering similar issues, and I was never really sure what to put for the &lt;code&gt;{framework}&lt;/code&gt; partof my queries.&lt;/p&gt;

&lt;p&gt;I spent a little time trying to figure out what the right term is. Turns out - nobody seems to know.&lt;/p&gt;

&lt;p&gt;On Stack Overflow the most used tag is &lt;code&gt;system.reactive&lt;/code&gt;, but looking official documentation and Stack Overflow questions, I’ve seen it referred to as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reactive Extensions &lt;a href="https://docs.microsoft.com/en-us/previous-versions/dotnet/reactive-extensions/hh242985(v=vs.103)?redirectedfrom=MSDN"&gt;[1]&lt;/a&gt; &lt;a href="https://github.com/dotnet/reactive"&gt;[2]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rx (short for Reactive Extensions) &lt;a href="https://docs.microsoft.com/en-us/previous-versions/dotnet/reactive-extensions/hh242985(v=vs.103)?redirectedfrom=MSDN"&gt;[1]&lt;/a&gt; &lt;a href="https://github.com/dotnet/reactive"&gt;[2]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rx.Net &lt;a href="https://github.com/dotnet/reactive#flavors-of-rx"&gt;[1]&lt;/a&gt; &lt;a href="http://reactivex.io/languages.html"&gt;[2]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;.NET Reactive Framework &lt;a href="https://stackoverflow.com/questions/1596158/good-introduction-to-the-net-reactive-framework/1749252#1749252"&gt;[1]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ReactiveX &lt;a href="http://reactivex.io/"&gt;[1]&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all of these names that are subtly different - what am I supposed to search for?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We’ll call it Rx.Net in the rest of the post - at least it’s short&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Documentation Is Hard To Find
&lt;/h2&gt;

&lt;p&gt;Finding documentation online for Rx.Net is pretty close to impossible.While figuring out the search terms to use is hard, finding comprehensive documentation is much, much harder.&lt;/p&gt;

&lt;p&gt;Rx.Net is the .NET flavour of &lt;a href="http://reactivex.io/"&gt;ReactiveX&lt;/a&gt;, which luckily seems to have quite a bit of documentation!Unfortunately you pretty much have to know what you’re looking for already.If I want to read the documentation for how the C# &lt;code&gt;Select&lt;/code&gt; works, I need to know that in ReactiveX, &lt;code&gt;Select&lt;/code&gt; is called &lt;code&gt;Map&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When I know that, in the ReactiveX documentation I can find a language-agnostic explanation of what a &lt;code&gt;Map/Select&lt;/code&gt; does.There’s also language-specific documentation for each of the different flavours, including Rx.Net!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4ajDlFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/reactivex-docs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4ajDlFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/reactivex-docs.png" alt=""&gt;&lt;/a&gt;Just kidding&lt;/p&gt;

&lt;p&gt;There’s also no API reference online anywhere. I can find the documentation in the editor, so I know it’s been &lt;em&gt;written&lt;/em&gt; - but it isn’t hosted anywhere.The closest we get is this API reference from &lt;a href="https://docs.microsoft.com/en-us/previous-versions/dotnet/reactive-extensions/hh244252(v%3Dvs.103)"&gt;MSDN&lt;/a&gt;. From 2011.&lt;/p&gt;
&lt;h2&gt;
  
  
  Observables are hard to debug
&lt;/h2&gt;

&lt;p&gt;Observables can be a pain to debug. Most debuggers aren’t particularly suited for tracing streams of data,and the stack traces you get are unimpressive. Let’s dive a little deeper into the stack traces. Take this pieceof code which throws an error after a few integers have passed through the stream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Fact]
public void ObservableTest()
{
   IObservable&amp;lt;int&amp;gt; observable = Observable.Range(0, 5)
       .Select(i =&amp;gt; i * 2)
       .Do(i =&amp;gt;
       {
           if (i &amp;gt; 5)
           {
               throw new Exception("That's an illegally large number");
           }
       });

   observable.Subscribe(
       onNext: (i) =&amp;gt; Console.WriteLine(i),
       onError: (err) =&amp;gt;
   {
       throw err;
   });
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The humongous Stacktrace is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error Message:
   System.Exception : That's an illegally large number
  Stack Trace:
     at MyProject.Test.ObservableTest.&amp;lt;&amp;gt;c.&amp;lt;Foo1&amp;gt;b__0_3(Exception err) in /home/geewee/programming/MyProject.Test/ObservableTest.cs:line 30
   at System.Reactive.AnonymousSafeObserver`1.OnError(Exception error) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\AnonymousSafeObserver.cs:line 62
   at System.Reactive.Sink`1.ForwardOnError(Exception error) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\Sink.cs:line 61
   at System.Reactive.Linq.ObservableImpl.Do`1.OnNext._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Do.cs:line 42
   at System.Reactive.Sink`1.ForwardOnNext(TTarget value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\Sink.cs:line 50
   at System.Reactive.Linq.ObservableImpl.Select`2.Selector._.OnNext(TSource value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Select.cs:line 48
   at System.Reactive.Sink`1.ForwardOnNext(TTarget value) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\Sink.cs:line 50
   at System.Reactive.Linq.ObservableImpl.RangeRecursive.RangeSink.LoopRec(IScheduler scheduler) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Range.cs:line 62
   at System.Reactive.Linq.ObservableImpl.RangeRecursive.RangeSink.&amp;lt;&amp;gt;c.&amp;lt;LoopRec&amp;gt;b__6_0(IScheduler innerScheduler, RangeSink this) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\Observable\Range.cs:line 62
   at System.Reactive.Concurrency.ScheduledItem`2.InvokeCore() in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\ScheduledItem.cs:line 208
   at System.Reactive.Concurrency.CurrentThreadScheduler.Trampoline.Run(SchedulerQueue`1 queue) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\CurrentThreadScheduler.cs:line 168
   at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, TimeSpan dueTime, Func`3 action) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\CurrentThreadScheduler.cs:line 118
   at System.Reactive.Concurrency.LocalScheduler.Schedule[TState](TState state, Func`3 action) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\LocalScheduler.cs:line 32
   at System.Reactive.Concurrency.Scheduler.ScheduleAction[TState](IScheduler scheduler, TState state, Action`1 action) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Concurrency\Scheduler.Simple.cs:line 61
   at System.Reactive.Producer`2.SubscribeRaw(IObserver`1 observer, Boolean enableSafeguard) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\Producer.cs:line 119
   at System.Reactive.Producer`2.Subscribe(IObserver`1 observer) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Internal\Producer.cs:line 97
   at System.ObservableExtensions.Subscribe[T](IObservable`1 source, Action`1 onNext, Action`1 onError) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Observable.Extensions.cs:line 95
   at MyProject.Test.ObservableTest.ObservableTest() in /home/geewee/programming/OAI/MyProject.Test/ObservableTest.cs:line 25

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Removing all the Rx.Net internal stuff, this is the only information in the stack trace we care about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error Message:
   System.Exception : That's an illegally large number
  Stack Trace:
     at MyProject.Test.ObservableTest.&amp;lt;&amp;gt;c.&amp;lt;ObservableTest&amp;gt;b__0_3(Exception err) in /home/geewee/programming/MyProject.Test/ObservableTests.cs:line 30
     at MyProject.Test.ObservableTest.ObservableTest() in /home/geewee/programming/OAI/MyProject.Test/ObservableTests.cs:line 25


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We get the line number where we subscribed to the observable, and the function inside the chain where the error was thrown.I have no idea what transformations the data has gone through.If the stream has been dynamically constructed I might not even know what it looks like.&lt;/p&gt;

&lt;p&gt;These issues aren’t unique to observables. Composing long LINQ-expressions suffer from the same issues.When composing several different functions together, the stack traces very quickly stop becoming meaningful.The below is the complete stack trace the Enumerable/LINQ version of the Observable code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Error Message:
   System.Exception : That's an illegally large number
  Stack Trace:
     at MyProject.Tests.ObservableTests.&amp;lt;&amp;gt;c.&amp;lt;TestLinq_StackTraces&amp;gt;b__2_1(Int32 i) in /home/geewee/programming/MyProject.Test/ObservableTests.cs:line 55
   at System.Linq.Utilities.&amp;lt;&amp;gt;c __DisplayClass2_0`3.&amp;lt;CombineSelectors&amp;gt;b__ 0(TSource x)
   at System.Linq.Enumerable.SelectRangeIterator`1.MoveNext()
   at MyProject.Tests.ObservableTests.TestLinq_StackTraces() in /home/geewee/programming/MyProject.Test/ObservableTests.cs:line 60

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It’s much cleaner, but it doesn’t give us any more information than the observable version.&lt;/p&gt;

&lt;p&gt;The poor debugging and stack-traces are a perpetual thorn in my side when working with Observables.But if the same issues exist with long chains of Enumerable, why is that less of an issue? The short answer - I don’t know.&lt;/p&gt;

&lt;p&gt;My best guess is that when using Observables there’s a strong tendency to keep everything as an Observable stream.The longer your streams are the harder debugging with a minuscule stack trace becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s Hard To Use Scopes
&lt;/h2&gt;

&lt;p&gt;A very common thing I need to do is attach some sort of context to a request or a series of events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var id = "myCoolId"
using (LogContext.PushProperty("id", id))
{
    // Every log statement in here will have the `id=myCoolId` attached 
    await DoSomething(id);
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a very common usage patterns for logging, for example in Web Apps if you want to attach a specific GUID to a Request, soyou can later correlate all logs for that specific request.&lt;/p&gt;

&lt;p&gt;Something like this isn’t possible when using Rx.Net, as it’s threading model doesn’t carry over the ExecutionContext. &lt;a href="https://github.com/dotnet/reactive/issues/14"&gt;[1]&lt;/a&gt; &lt;a href="https://stackoverflow.com/questions/51279665/net-core-asynclocal-loses-context-with-system-reactive"&gt;[2]&lt;/a&gt;&lt;br&gt;&lt;br&gt;
This means that we can’t use something like an &lt;code&gt;AsyncLocal&lt;/code&gt; or a &lt;code&gt;ThreadLocal&lt;/code&gt; to keep context for a specific piece of data or stream.If we want the &lt;code&gt;myCoolId&lt;/code&gt; to be attached to all of the logs, we’ll need to pass it into every step of our observable chain, and manually pass it to every logging call.I know there’s a value in being explicit, but this is a time where choosing Rx.Net locks you out of some pretty handy language features.&lt;/p&gt;

&lt;h2&gt;
  
  
  It never really took off
&lt;/h2&gt;

&lt;p&gt;Looking at the timelines, it seems like Rx.net in the hype cycled peaked a few years ago. If it ever really took off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jT6Lr8l2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/google-trends.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jT6Lr8l2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/google-trends.png" alt=""&gt;&lt;/a&gt;Google Trends for system.reactive compared to the Javascript version of the ReactiveX framework.&lt;/p&gt;

&lt;p&gt;Comparing it in google searches to RxJS it seems much less widely used. Looking at the Stack Overflow trendsreveals a little more nuanced picture however:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w555HwDj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/stackoverflow-trends.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w555HwDj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.gustavwengel.dk/assets/img/observable/stackoverflow-trends.png" alt=""&gt;&lt;/a&gt;Stack Overflow trends for system.reactive compared to the Javascript and Java versions of the ReactiveX framework.&lt;/p&gt;

&lt;p&gt;While still much less popular than RxJS and the Java ReactiveX version, Rx.Net does seem to predate their popularityby quite a few years. Microsoft was out early with the reactive paradigm but never really seemed to manage to make it take off.&lt;/p&gt;

&lt;p&gt;Now while your technology choices shouldn’t be about how hyped something is - the popularity is always worth taking into account.Some old technologies are sturdy, battle-tested and well-documented. Then they don’t have to be shiny.&lt;/p&gt;

&lt;p&gt;However with some of the pitfalls, particularly around the documentation issues, Rx.Net feels neither robust or shiny to me.&lt;/p&gt;




&lt;p&gt;While this is a negative article, I’m not saying Rx.Net or the Reactive paradigm is &lt;em&gt;always&lt;/em&gt; bad.Some of the issues are about the tooling and documentation.I mention that most debuggers aren’t suited for debugging streams, but this is a tooling problem and not inherent to the reactive paradigm.E.g. Jetbrains has an excellent &lt;a href="https://plugins.jetbrains.com/plugin/9696-java-stream-debugger"&gt;Java Stream Debugger&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Observables seems like a very natural fit for some languages and domains, like reacting to user interactions in JavaScript, as the large adoption of RxJs suggests.I’m just saying that it doesn’t feel like a particularly natural fit for C#, and if you have some data that can be modelled as either Enumerables or Observables,I would think twice about using Observables.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
