<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Michal Charemza</title>
  <subtitle>Software, data, and cloud infrastructure engineer</subtitle>
  <link href="https://charemza.name/feed.xml" rel="self" />
  <link href="https://charemza.name/" />
  <updated>2026-01-04T08:35:00Z</updated>
  <id>https://charemza.name/</id>
  <author>
    <name>Michal Charemza</name>
    <email>michal@charemza.name</email>
  </author>
  <entry>
    <title>I don&#39;t use the term technical debt</title>
    <link href="https://charemza.name/blog/posts/software/communication/I-dont-use-the-term-technical-debt-and-neither-should-you/" />
    <updated>2026-01-04T08:35:00Z</updated>
    <id>https://charemza.name/blog/posts/software/communication/I-dont-use-the-term-technical-debt-and-neither-should-you/</id>
    <content type="html">&lt;p&gt;I generally avoid referring to anything as technical debt. While not an &lt;em&gt;entirely&lt;/em&gt; meaningless term, I suspect that in almost all contexts there are better things to say. In this post I argue why I think the term shouldn&#39;t be used, and what should be said instead.&lt;/p&gt;&lt;h3&gt;It means too many things&lt;/h3&gt;&lt;p&gt;I&#39;ve heard the term technical debt being used for:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Bugs that exist right now&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Properties that risk introducing bugs with future development&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Properties that risk slowing future development&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Not having some form of quality assurance or tests&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Not using a consistent architecture&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Limits of scalability of a system in terms of users/usage&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Things that mean security isn&#39;t as tight as it could be&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Things that mean performance/efficiency isn&#39;t as good as it could be&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Even just regular not-implemented user-facing features&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Putting all this together &quot;technical debt&quot; means virtually any property of a system that can be improved in any way! It&#39;s far too vague to have meaningful conversations about it in general.&lt;/p&gt;&lt;h3&gt;It sounds absolute&lt;/h3&gt;&lt;p&gt;The debt metaphor makes it sound absolute: for a financial debt, who can argue that it exists and it has to be dealt with. But this is engineering dealing with humans, trade-offs and risks, all of which can change over time when situations evolve or when information is revealed, and so very much &lt;em&gt;not&lt;/em&gt; absolute.&lt;/p&gt;&lt;h3&gt;You may never feel the effects of the debt&lt;/h3&gt;&lt;p&gt;Even if limiting to what I think are the most typical definitions — properties of code that slow development or risk more bugs when code is changed — it would only involve a subset of all possible changes. If the need for those changes doesn&#39;t arise then you never realise the effect of the so-called debt. This is where the debt metaphor really breaks down: other than by taking drastic actions, most of us can&#39;t escape the consequences of financial debt, but this is not true for technical debt.&lt;/p&gt;&lt;h3&gt;It can lead to wishful thinking&lt;/h3&gt;&lt;p&gt;I think because the term debt sounds like it &lt;em&gt;will&lt;/em&gt; be addressed, it can lead to wishful thinking, which itself leads to affecting decisions on what you do today. Veering slightly from the point of this post into avoiding &quot;technical debt&quot;, I very rarely make a change that is contingent on a future task in order to be acceptable.&lt;/p&gt;&lt;h3&gt;The term can sound so negative it can lead to over-engineering&lt;/h3&gt;&lt;p&gt;On the other hand, I suspect sometimes technical debt sounds so negative, the avoidance of it can lead to over-engineering solutions, rather than considering the fact that if something is needed later, it often can and should be done later.&lt;/p&gt;&lt;h3&gt;It&#39;s not obviously linked to real-world consequences&lt;/h3&gt;&lt;p&gt;From what I know the term was coined to communicate technical concepts to non-technical people. But because the term is so vague, and I think still sounds quite technical, I think this ironically makes it harder to convince that things labelled (just) as &quot;technical debt&quot; have real-world consequences and so should be avoided or addressed.&lt;/p&gt;&lt;h3&gt;It can suggest an ideal architecture independent of constraints&lt;/h3&gt;&lt;p&gt;If you don&#39;t have the resources — for example time/knowledge/money — to make an architecture, then it&#39;s clearly not the perfect architecture for the situation at hand. If it can&#39;t exist, it&#39;s not ideal in any meaningful sense, so labelling non-achievement of such an architecture as &quot;technical debt&quot; can be a waste of words, time, or even emotions.&lt;/p&gt;&lt;h3&gt;What to say instead?&lt;/h3&gt;&lt;p&gt;Say the thing: bug, scalability limitation, performance issue (ideally with at least rough numbers), security issue (stating how severe or how it would be exploited), development productivity issue (around what specific classes of features), missing user-facing feature, lack of quality assurance, and ideally along with the consequences of not addressing it. It&#39;s such a clearer starting off point for discussions around if/when it should be addressed or not.&lt;/p&gt;&lt;p&gt;For changes that allow you to &lt;em&gt;subsequently&lt;/em&gt; address a need, for example some types of refactorings, make sure to say that need when talking about it: &quot;doing X will allow us to easily or more safely do Y&quot; for example. Make sure it&#39;s clear that you&#39;re aware that refactoring is often necessary, but is never an end unto itself.&lt;/p&gt;&lt;p&gt;And finally, explain rather than apologise in almost all cases! Achieving requirements within constraints is something to be proud of, even if some decisions led to one of the many things that could be labelled as &quot;technical debt&quot;. If you&#39;ve not done X, Y, or Z because they weren&#39;t as high priority as other things, that is something to feel good about, not guilty (as long as you haven&#39;t made it meaningfully harder to do those things if/when they &lt;em&gt;are&lt;/em&gt; needed). Apologise only if you&#39;ve made a mistake and would not take the same steps next time.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>It&#39;s not done if...</title>
    <link href="https://charemza.name/blog/posts/software/communication/not-done-if-there-are-more-steps-to-take/" />
    <updated>2025-10-19T21:30:00Z</updated>
    <id>https://charemza.name/blog/posts/software/communication/not-done-if-there-are-more-steps-to-take/</id>
    <content type="html">&lt;p&gt;It can be extremely tempting to announce that something is &lt;em&gt;done&lt;/em&gt;, essentially because it can make you and others smile and feel good—we&#39;ve made progress! But if there are still steps to be taken it&#39;s almost definitely not going to be seen as done from the point of view of the person or people you&#39;re talking to. Saying something is &lt;em&gt;done&lt;/em&gt; when it&#39;s not at best is not helpful, but at worst makes you seem dishonest.&lt;/p&gt;&lt;p&gt;Here are some examples of what &lt;em&gt;not done&lt;/em&gt; can look like, depending on the team or task:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If there are remaining tests to write or fix&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If QA/review/approval is pending&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If it&#39;s not yet released to production&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If no one outside of the team can use it&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If there is documentation to write&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If we&#39;re waiting on confirmation that it does solve the problem&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If any of these are the case, I suggest using some other language. For example, you can be specific on what&#39;s been completed and what&#39;s outstanding. And if you&#39;re not sure what&#39;s outstanding: ask!&lt;/p&gt;&lt;p&gt;You can sometimes say &lt;em&gt;almost done&lt;/em&gt;—it is safer than &lt;em&gt;done&lt;/em&gt;. But I suggest only saying this occasionally, and only if you have a high level of confidence that it really is extremely close to getting over the line. If you overuse &lt;em&gt;almost done&lt;/em&gt;, it will inevitably not be true in some cases, and people will lose trust in you.&lt;/p&gt;&lt;p&gt;Of course, teams should probably have an agreed &quot;definition of done&quot;. But even if there isn&#39;t one here&#39;s one that&#39;s applicable to many situations:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;It&#39;s done when there are no more steps to take&lt;/p&gt;&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <title>It&#39;s not a hack to satisfy known requirements</title>
    <link href="https://charemza.name/blog/posts/agile/over-engineering/not-a-hack-to-meet-requirements/" />
    <updated>2025-10-04T14:10:00Z</updated>
    <id>https://charemza.name/blog/posts/agile/over-engineering/not-a-hack-to-meet-requirements/</id>
    <content type="html">&lt;p&gt;I so frequently see extremely capable software engineers waste their skills with over-engineering, and it makes me feel sad. Here are some tips to help avoid the over-engineering trap, and so also to help keep me happy 😀.&lt;/p&gt;&lt;h3&gt;Find out what is seen as valuable&lt;/h3&gt;&lt;p&gt;We&#39;re not here to write code, but to solve problems. Find exactly what problems you are expected to solve and focus on those. Remember that code that clearly solves just those problems is in no way a hack.&lt;/p&gt;&lt;h3&gt;Deliver value as often as possible to get feedback&lt;/h3&gt;&lt;p&gt;Frequently delivering value is a great way to avoid over-engineering. It basically gives you regular course correction towards appropriate-engineering, because you quickly and frequently find out if there is no value for the code you&#39;re writing.&lt;/p&gt;&lt;p&gt;I generally argue for at least daily delivery of value; see the &lt;a href=https://delivervaluedaily.dev/ &gt;&quot;Deliver value daily&quot; manifesto&lt;/a&gt; (which I co-wrote).&lt;/p&gt;&lt;h3&gt;Write and maintain integration tests that survive refactoring&lt;/h3&gt;&lt;p&gt;One of the worst pieces of advice that I ever received was that every function should be unit tested. This is the path to designing code that you never want to change because no matter what change you make, tests will break, and thus leads you to trying to handle every possible future up-front. Please, I beg you, no.&lt;/p&gt;&lt;p&gt;Instead, write higher level tests close to the client/user facing behaviour that actually give you protection against breaking things unintentionally, and so free to you make changes later once you have evidence they&#39;re needed.&lt;/p&gt;&lt;h3&gt;Avoid Object-Oriented Programming, or at least be extra careful with it&lt;/h3&gt;&lt;p&gt;Object-oriented code is more susceptible to over-engineering if you&#39;re not careful, because every object has its own set of responsibilities on what it looks after, often quite divorced from the actual data flows in your application. So many problems have only a handful of possible cases, and yet if you look at all the classes and member functions involved in typical object-oriented solutions, they&#39;re coded up as though there were many orders of magnitude more cases, which makes them difficult to optimise for the actual cases. Inheritance-based reuse is also notoriously hard to change, and so pushes you to design the &quot;perfect&quot; system up front.&lt;/p&gt;&lt;p&gt;Don&#39;t be scared of keeping data and code separate via free functions, especially pure functions. Basic data-in data-out patterns often result in very clear separation of responsibilities, and they are often easy to refactor.&lt;/p&gt;&lt;h3&gt;Remember you can still add in that complication tomorrow&lt;/h3&gt;&lt;p&gt;Train yourself to realise you can always add in that complication tomorrow if you judge that it&#39;s still needed tomorrow. Sometimes the answer will be yes, but so often the answer will be no, and that&#39;s a great thing.&lt;/p&gt;&lt;p&gt;This is much easier when high-level integration tests are in place.&lt;/p&gt;&lt;h3&gt;Be concious of what makes you over-engineer&lt;/h3&gt;&lt;p&gt;Run a search for &lt;a href=&quot;https://www.google.com/search?q=what+causes+software+over-engineering&quot;&gt;&quot;What causes software over-engeneering?&quot;&lt;/a&gt; and see which apply to you. Self-awareness is half the battle.&lt;/p&gt;&lt;h3&gt;Get yourself a better definition of perfection&lt;/h3&gt;&lt;p&gt;If you think you&#39;re fighting against a drive for perfectionism, give in to the drive but instead find a better definition of perfection. This is basically mine:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&lt;/p&gt;&lt;cite&gt;Antoine de Saint-Exupéry&lt;/cite&gt;&lt;/blockquote&gt;&lt;h3&gt;When &lt;em&gt;should&lt;/em&gt; you create stuff just in case?&lt;/h3&gt;&lt;p&gt;This all being said, there are times when you should create something just in case, and that&#39;s when all three of the following are satisfied:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;There is a reasonable chance it will be useful later&lt;/li&gt;&lt;li&gt;It will be difficult to add in later&lt;/li&gt;&lt;li&gt;It won&#39;t meanginfully slow down the meeting of more likely requirements&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To determine if all those hold true, you have to have an idea of what features are likely going to be needed. This is beyond the scope of code and much more do with people—users or stakeholders—that you will have to speak to. You can always choose to assume without validating the assumption, but doing so will almost definitely be due to arrogance or fear. Do not make engineering decisions because of arrogance or fear!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Ordering work: a skill and culture gap</title>
    <link href="https://charemza.name/blog/posts/agile/deliver-value-daily/ordering-work-skill-culture-gap/" />
    <updated>2025-10-03T08:50:00Z</updated>
    <id>https://charemza.name/blog/posts/agile/deliver-value-daily/ordering-work-skill-culture-gap/</id>
    <content type="html">&lt;p&gt;There are virtually infinite options on how to split up all but the most trivial pieces of software engineering work, but rarely is emphasis placed on the skill of making that choice. But this choice is extremely important: the order in which work is done affects how frequently feedback is received (even from just running the code yourself) and so can seriously affect how successful projects are in the long term.&lt;/p&gt;&lt;p&gt;Emphasis is all too frequently put on the final properties of systems, as if components are made all at once in a single step. Even skipping over any iterative versus waterfall debate, a person can only do a single thing at once (or write one prompt at once 😜): you still have to decide to write one line of code first, another line of code second, and so on. As a parallel imagine if in other professions the order in which to do work was not a primary consideration: that would be madness.&lt;/p&gt;&lt;p&gt;In terms of what to do about this, my main suspicion is that a cultural shift is needed, and skills will be developed from that. Engineers must be encouraged to internalise that the order of the work they do is of primary consequence, and they &lt;em&gt;must&lt;/em&gt; be empowered to continually set that order. I think also others in the organisation must also understand that while designs and plans are in general good, feedback from real use will so often suggest changes, and it&#39;s almost always better for such changes to happen early than late (or worse, not at all).&lt;/p&gt;&lt;p&gt;This is one of the several reasons I (with others) have written the &lt;a href=https://delivervaluedaily.dev/ &gt;&quot;Deliver value daily&quot;&lt;/a&gt; manifesto. Our claim (backed up at least from our own experience) is that a focus on small increments of at most day-sized work really helps with making decisions on what to do when.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>6 rules when making data dashboards</title>
    <link href="https://charemza.name/blog/posts/data/visualisation/six-rules-for-making-dashboards/" />
    <updated>2024-02-04T13:00:00Z</updated>
    <id>https://charemza.name/blog/posts/data/visualisation/six-rules-for-making-dashboards/</id>
    <content type="html">&lt;p&gt;I&#39;ve made a few data dashboards recently, and I&#39;ve realised it can be hard to know where to begin sometimes. Hopefully these rules can help focus your thoughts.&lt;/p&gt;&lt;h3&gt;1. Know the use cases&lt;/h3&gt;&lt;p&gt;Just like designing anything, if you don&#39;t know how it&#39;s going to be used, it&#39;s not likely you&#39;re going to do a good job.&lt;/p&gt;&lt;p&gt;Often there aren&#39;t actually that many use cases. But if there are - you can construct different dashboards/sections in the dashboard optimised for them.&lt;/p&gt;&lt;h3&gt;2. Prefer &quot;explain&quot; to &quot;explore&quot;&lt;/h3&gt;&lt;p&gt;An &quot;explore&quot; chart doesn&#39;t have a clear conclusion or story associated with the data - it lets the user come up with them. But often exploring the data is not want users need to do!&lt;/p&gt;&lt;p&gt;Instead, users often need some very specific question(s) answering, which are what &quot;explain&quot; charts do.&lt;/p&gt;&lt;h3&gt;3. Use titles that make clear how each component can be used&lt;/h3&gt;&lt;p&gt;Titles can be useful to the users, especially new users, so they know what they can use the dashboard or each visual for.&lt;/p&gt;&lt;p&gt;But also, if you can&#39;t come up with good titles, then you probably don&#39;t know the use cases well enough, or you don&#39;t know what you&#39;re trying to achieve, or you&#39;re maybe trying to make each visual satisfy too many use cases.&lt;/p&gt;&lt;p&gt;A word of caution - visuals shouldn&#39;t be so complex that they strongly depend on the title. They should be reasonably clear at a glance.&lt;/p&gt;&lt;h3&gt;4. Keep interactivity to a minimum&lt;/h3&gt;&lt;p&gt;Including interactivity often feels like a safe bet, because it allows more data to be discovered &quot;just in case&quot;. But that &quot;just in case&quot; probably means you don&#39;t know what&#39;s important to show.&lt;/p&gt;&lt;p&gt;It also leaves the uses that need the interaction second class citizens, and has the consequence of making it harder to tailor visuals to any of the uses.&lt;/p&gt;&lt;p&gt;Instead, find out the use cases, and then if you need to create separate visuals each tailed to one (or few) use cases.&lt;/p&gt;&lt;h3&gt;5. Make sure the users will trust the dashboard&lt;/h3&gt;&lt;p&gt;If the users don&#39;t trust the dashboard, then they won&#39;t take action based on it. At best it&#39;s pointless, but at worst you&#39;ve wasted yours and other people&#39;s time.&lt;/p&gt;&lt;p&gt;How to acheive trust is tricky, and is probably specific to each situation. Some ideas include making sure it has consistent layout/spacing/colours; making sure there aren&#39;t unnecessary or broken components; making sure the data is self consistent, and consistent with external data the user has access to; making it very clear up front if there are limitations or innacuracies; making it clear when the data was last updated; or making sure that it actually answers the questions it claims to. Sometimes visuals that are technically unnecessary to answer the questions, but lend weight to the veracity of the data, help acheive trust.&lt;/p&gt;&lt;h3&gt;6. Put in the work&lt;/h3&gt;&lt;p&gt;Especially if you&#39;re new to making dashboards, it can take many iterations of both the UI and the data to end up with something good. If you&#39;re focusing in on use cases while you&#39;re making it, doubly so. Be prepared for this!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Questions to ask yourself when talking with users</title>
    <link href="https://charemza.name/blog/posts/users/support/questions-to-ask-yourself-when-communicating-with-users/" />
    <updated>2022-08-14T16:15:00Z</updated>
    <id>https://charemza.name/blog/posts/users/support/questions-to-ask-yourself-when-communicating-with-users/</id>
    <content type="html">&lt;p&gt;I&#39;ve been fortunate to work on projects where there is often a direct (or at least short) route between myself and the users of products I&#39;ve worked on. These are the sorts of questions I ask myself when communicating with them.&lt;/p&gt;&lt;h3&gt;Am I answering their question?&lt;/h3&gt;&lt;p&gt;I might suspect that they&#39;re not asking a question where the answer will ultimately help them (an XY problem), but I can&#39;t be sure. In most cases I do really try to answer their question.&lt;/p&gt;&lt;h3&gt;Do I understand what they&#39;re trying to do?&lt;/h3&gt;&lt;p&gt;Even if I answer a question, understanding the context and what they&#39;re trying to do can lead to much better help. If I don&#39;t think I understand the context enough, I ask them for more details.&lt;/p&gt;&lt;h3&gt;Am I explaining why I need the answer to a question?&lt;/h3&gt;&lt;p&gt;I think it can be a bit frustrating to be asked to do things without understanding why. For example, if I ask for a screenshot, it&#39;s not because I don&#39;t believe the user, it&#39;s because there can be subtle bits of information along with the error message that explains what the problem is. &quot;Oh it&#39;s that sort of 403. Right... I think I know what&#39;s up.&quot;&lt;/p&gt;&lt;h3&gt;Can I offer alternatives, even imperfect ones?&lt;/h3&gt;&lt;p&gt;There are often just so many alternatives that might help a user. I often try to think of the closest thing to what the user is asking for, and suggest that. (And if it&#39;s perhaps a ridiculous suggestion, I state that I&#39;m aware it is!)&lt;/p&gt;&lt;h3&gt;Have I asked my collegues if there is a better way?&lt;/h3&gt;&lt;p&gt;There are always things I don&#39;t know, even about systems I&#39;ve worked on for a while. A quick message to collegues is often helpful: for the user since it might result in a solution to their immediate problem, but it&#39;s also helpful for the team, since it communicates what users are struggling with, and what parts of the system might need some attention.&lt;/p&gt;&lt;h3&gt;Am I acknowledging pain points?&lt;/h3&gt;&lt;p&gt;You don&#39;t need to go overboard with this, but just a tiny bit of empathy goes so far. I think it can even be efficient as well - it can serve as a very clear statement that you understand what the user is trying to do and why. Then the conversation will probably move on to working around or fixing whatever the pain point is.&lt;/p&gt;&lt;h3&gt;Am I giving an appropriate amount of technical detail?&lt;/h3&gt;&lt;p&gt;This is a tricky one - I don&#39;t want to bore users with too much detail, or for them to think &quot;why are you telling me this? Just fix my problem!&quot;, but also feels a bit odd to not communicate anything at all. I think in general it&#39;s helpful to give some detail. Knowing, even roughly, what the problems/limitations are can help users come up with their own workarounds.&lt;/p&gt;&lt;h3&gt;Am I being realistic in promises?&lt;/h3&gt;&lt;p&gt;Saying no can be hard, but it&#39;s usually so much better to be up front about what&#39;s realistic. In so many situations people are happy to plan given realistic information.&lt;/p&gt;&lt;h3&gt;Am I over-apologising?&lt;/h3&gt;&lt;p&gt;Apologising is tricky one to get right, and I don&#39;t think I&#39;m quite there yet. It&#39;s probably extremely culture and situation-dependant, but so far I think I try to keep apologising to a minimum. In so many cases it just doesn&#39;t really help. Instead, I acknowledge pain points, and try to get a solution to the user&#39;s problem.&lt;/p&gt;&lt;p&gt;I think I might even imagine I&#39;m talking to Marla Singer from Fight Club. She&#39;s gives the impression that she&#39;s been apolgoised to a lot, that apologies have no value to her, and she just wants to move the conversation past them:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Yeah, you&#39;re sorry, I&#39;m sorry, everybody&#39;s sorry&lt;/p&gt;&lt;cite&gt;Marla Singer, Fight Club&lt;/cite&gt;&lt;/blockquote&gt;&lt;h3&gt;Have I checked what I&#39;m suggesting works?&lt;/h3&gt;&lt;p&gt;I try to check what I&#39;m telling users, even if I&#39;m confident about it. Or if I can&#39;t for some reason, I say I can&#39;t. Quite a few times I have been so close to hitting that &quot;Send&quot; button, but I decide to paranoia check X, and I realise I was about to be wrong.&lt;/p&gt;&lt;h3&gt;How would I feel if I read/heard this if I were them?&lt;/h3&gt;&lt;p&gt;This is easier to to with written communication, but I think worth just putting yourself in their shoes for a moment. It might be worth tweaking the message a bit (or asking yourself more of the questions above!)&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>How to offer better downloads</title>
    <link href="https://charemza.name/blog/posts/http/downloads/how-to-offer-better-downloads/" />
    <updated>2021-02-28T07:20:00Z</updated>
    <id>https://charemza.name/blog/posts/http/downloads/how-to-offer-better-downloads/</id>
    <content type="html">&lt;p&gt;To offer HTTP file downloads via your own code [rather than redirecting elsewhere], it&#39;s often easy to rustle something up. However, the default behaviour in a lot of cases may not give users as good an experience as possible. With a bit of effort, you can polish that right up, and here are 4 sets of HTTP headers that help you do just that.&lt;/p&gt;&lt;h3&gt;content-length&lt;/h3&gt;&lt;p&gt;If you are able to, set the &lt;code class=inline&gt;content-length&lt;/code&gt; header with the total size of the file.&lt;/p&gt;&lt;p&gt;This simple header will cause browsers to tell users [estimates for] the time-to-completion of downloads. [It&#39;s also required for browsers to attempt to do range requests, as in the following section.]&lt;/p&gt;&lt;p&gt;Note that if streaming a file to the client, e.g. using &lt;a href=https://docs.djangoproject.com/en/3.1/ref/request-response/#streaminghttpresponse-object&gt;Django&#39;s StreamingHttpResponse&lt;/a&gt;, then at the point the HTTP headers are generated, the full bytes of the file are not available, so this can&#39;t happen automatically. You have to explicitly determine the length of the file and set the header. For example, if the file is stored in S3, S3 returns a &lt;code class=inline&gt;content-length&lt;/code&gt; header with all responses, and you can take the value of this header and return it to the client.&lt;/p&gt;&lt;h3&gt;accept-ranges / range / content-range [/ content-length]&lt;/h3&gt;&lt;p&gt;By default, if the connection is interrupted, browsers will have to restart the download from the beginning. If you support HTTP range requests, which use the &lt;code class=inline&gt;accept-ranges&lt;/code&gt;, &lt;code class=inline&gt;range&lt;/code&gt;, &lt;code class=inline&gt;content-range&lt;/code&gt; headers, [and &lt;code class=inline&gt;content-length&lt;/code&gt; header] then browsers can resume downloads from where they left off.&lt;/p&gt;&lt;p&gt;See the &lt;a href=https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests&gt;MDN docs on HTTP range requests&lt;/a&gt; for more information. Note that &lt;a href=https://docs.aws.amazon.com/whitepapers/latest/s3-optimizing-performance-best-practices/use-byte-range-fetches.html&gt;S3 supports range requests&lt;/a&gt;, so if your code is essentially a proxy to S3, you can proxy the headers to and from S3 to support this fairly easily.&lt;/p&gt;&lt;h3&gt;content-disposition&lt;/h3&gt;&lt;p&gt;By default, browsers will guess at a suitable filename for the downloaded file, typically using the last path-component from the URL. Instead, consider what would be a more helpful filename, and set something like &lt;code class=inline&gt;content-disposition: attachment; filename=&quot;very-helpful-filename.csv&quot;&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;accept-encoding / content-encoding&lt;/h3&gt;&lt;p&gt;Some files compress well, for example typical CSV files. Serving compressed versions of these would often make downloads much faster. However, if the most likely thing users will do will do is immediately and manually uncompress the file, you&#39;ve just made their life a tiny bit harder.&lt;/p&gt;&lt;p&gt;However, the browser can do this so the user will never even notice. For example, if the browser sends an &lt;code class=inline&gt;accept-encoding&lt;/code&gt; header specifying it accepts gzip [which most modern browsers do], and if the server returns a header of &lt;code class=inline&gt;content-encoding: gzip&lt;/code&gt; with gzipped data, the browser will automatically decompress this data on download. The user will notice nothing other than faster downloads.&lt;/p&gt;&lt;p&gt;Unfortunately, S3 doesn&#39;t support this sort of content negotiation. If you&#39;re storing your data on S3, and want to support both gzipped and non-gzipped versions of an object, you&#39;ll have to store them under separate keys. To avoid this, you might be tempted to compress on-the-fly. However, you then won&#39;t be able to send a &lt;code class=inline&gt;content-length&lt;/code&gt;, or handle range requests.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;That&#39;s it!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>S3 is not a filesystem</title>
    <link href="https://charemza.name/blog/posts/s3/s3-is-not-a-filesystem/" />
    <updated>2021-02-14T13:00:00Z</updated>
    <id>https://charemza.name/blog/posts/s3/s3-is-not-a-filesystem/</id>
    <content type="html">&lt;p&gt;Something that occasionally catches developers out is the fact that S3 is not a filesystem, but a key-value store. Specifically&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the keys can be any UTF-8 encoded string, between 1 and 1024 bytes long;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the values can be any binary string, beteen 0 bytes and 5 terabytes long.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Yes, you can emulate certain features of a filesystem using slashes in the keys. In fact, the AWS console does this: it creates a folder by creating a 0-byte object with a trailing slash in its key.&lt;/p&gt;&lt;p&gt;But, you don&#39;t have to be limited by the key-structure that a filesystem imposes. For example, if you want to:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; you can have objects, with data, at both of the keys &lt;code class=inline&gt;a&lt;/code&gt; and &lt;code class=inline&gt;a/b&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; and you can have objects, with data, that have keys ending in &lt;code class=inline&gt;/&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Both of these are impossible in a traditional filesystem.&lt;/p&gt;&lt;p&gt;An example of using this is to store an uploaded file, &lt;code class=inline&gt;some-unique-name.txt&lt;/code&gt; say, and then store derived data inside its &quot;folder&quot;, for example &lt;code class=inline&gt;some-unique-name.txt/analysis1&lt;/code&gt; and &lt;code class=inline&gt;some-unique-name/analysis2&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Now a warning&lt;/h3&gt;&lt;p&gt;If you&#39;re about to leverage the fact S3 is a key-value store by having non filesystem-compatible keys, be warned: there are consequences.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You won&#39;t be able to easily sync from your S3 bucket to a filesystem.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Everything that claims to be S3 compatible may not be, and so migrating to those systems, or using them in a test environment, may be trickier. Specifically, &lt;a href=https://github.com/minio/minio/issues/10160&gt;minio [that I have used many times and generally really like] is not S3-compatible in this way&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, there are some valid pragmatic reasons to make sure your keys are filesystem-compatible. But, I can&#39;t help the niggling feeling that it&#39;s a shame to be limited by systems you&#39;re not using.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Django&#39;s transaction.atomic()</title>
    <link href="https://charemza.name/blog/posts/django/postgres/transactions/not-as-atomic-as-you-may-think/" />
    <updated>2020-10-10T11:00:00Z</updated>
    <id>https://charemza.name/blog/posts/django/postgres/transactions/not-as-atomic-as-you-may-think/</id>
    <content type="html">&lt;style type=text/css&gt;.reference-counter-reset {
      counter-reset: reference-counter;
    }
    .reference::before {
        counter-increment: reference-counter;
        content: &quot;[&quot; counter(reference-counter) &quot;]&quot;;
    }&lt;/style&gt;&lt;p class=reference-counter-reset&gt;I have a confession: I assumed things about Django&#39;s &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt; that are not true, at least not true by default in PostgreSQL. I assumed that in a &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt; context as below, database statements are protected from any race conditions, and everything will Just Work™.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Database statements&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But that&#39;s really not true.&lt;/p&gt;&lt;p&gt;Enter the world of transaction &lt;em&gt;isolation levels&lt;/em&gt;: None with &lt;em&gt;autocommit&lt;/em&gt;, &lt;em&gt;Read committed&lt;/em&gt;, &lt;em&gt;Repeatable read&lt;/em&gt;, &lt;em&gt;Serializable&lt;/em&gt;, and &quot;do it yourself&quot;.&lt;/p&gt;&lt;h3&gt;Django &lt;span style=&quot;font-size:150%; position: relative; top: 2px&quot;&gt;⬄&lt;/span&gt; SQL mapping&lt;/h3&gt;&lt;p&gt;Firstly, this post discusses transactions mostly in terms of SQL. As such, it&#39;s good to have a reasonable understanding of what Django does in terms of SQL queries.&lt;/p&gt;&lt;style&gt;.table td, .table th {padding-top: 7px;}
  .table td:first-child {border-right: 2px solid #950000;}&lt;/style&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;background:none; padding-left: 10px&quot;&gt;Django&lt;/th&gt;&lt;th&gt;SQL&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Fetch from a QuerySet&lt;/td&gt;&lt;td&gt;SELECT&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Existing model &lt;code class=inline&gt;save&lt;/code&gt;, or QuerySet &lt;code class=inline&gt;update&lt;/code&gt;&lt;/td&gt;&lt;td&gt;UPDATE&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Enter an &lt;code class=inline&gt;atomic&lt;/code&gt; context&lt;/td&gt;&lt;td&gt;START TRANSACTION&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Exit an &lt;code class=inline&gt;atomic&lt;/code&gt; context without exception&lt;/td&gt;&lt;td&gt;COMMIT&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Exit an &lt;code class=inline&gt;atomic&lt;/code&gt; context with an exception&lt;/td&gt;&lt;td&gt;ROLLBACK&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;No explicit transaction, with autocommit&lt;/h3&gt;&lt;p&gt;For completeness, &lt;em&gt;without&lt;/em&gt; &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt;, by default Django runs in &lt;em&gt;autocommit&lt;/em&gt; mode, which means every statement runs in its own &lt;em&gt;Read committed&lt;/em&gt; transaction and committed immediately. While tempting to translate &quot;auto&quot; as &quot;don&#39;t worry&quot;, even in autocommit mode UPDATEs can block &lt;a class=reference title=&quot;Test showing autocommit updates can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_autocommit_update_blocks.py&gt;&lt;/a&gt;, deadlock &lt;a class=reference title=&quot;Test showing autocommit updates can deadlock&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_autocommit_update_deadlock.py&gt;&lt;/a&gt;, or miss rows &lt;a class=reference title=&quot;Test showing autocommit updates can miss rows&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_autocommit_update_misses_rows.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Read committed&lt;/h3&gt;&lt;p&gt;The default isolation level of a PostgreSQL transaction, and so also of &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt;, is &lt;em&gt;Read committed&lt;/em&gt;. Such a transaction has 4 important properties.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Each of its SELECTs behaves as though a snapshot of the database is taken at the start of the SELECT, containing only committed data from other transactions &lt;a class=reference title=&quot;Test showing read committed SELECTs see snapshots of committed data&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_sees_snapshots.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Each of its UPDATEs can block if concurrent transactions have UPDATEd the same rows, and block until those transactions COMMIT or ROLLBACK &lt;a class=reference title=&quot;Test showing autocommit updates can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_update_blocks.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; This blocking can lead to deadlock if concurrent UPDATEs on the same rows are done in different orders &lt;a class=reference title=&quot;Test showing autocommit updates can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_update_deadlock.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Its COMMIT &lt;em&gt;won&#39;t&lt;/em&gt; fail due to concurrent transactions COMMITting the same rows &lt;a class=reference title=&quot;Test showing autocommit updates can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_update_succeeds.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This leaves a lot of room for race conditions, which can be roughly split into two classes.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Between multiple SELECTs in a Read committed transaction, other concurrent transactions can COMMIT, and so their changes become visible &lt;a class=reference title=&quot;Test showing read committed SELECTs see snapshots of committed data&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_sees_snapshots.py&gt;&lt;/a&gt;. Consider a Sock model, where each sock is either white or black.&lt;p&gt;&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    black_socks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Sock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colour&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;black&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# A SELECT query&lt;/span&gt;
    white_socks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Sock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colour&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;white&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# A SELECT query&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might be tempted to assume that due to the &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt;, each sock will be in exactly one of &lt;code class=inline&gt;black_socks&lt;/code&gt; or &lt;code class=inline&gt;white_socks&lt;/code&gt;. However, since each SELECT uses a different snapshot of database state, a given sock can be in both, or neither, of these lists.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;&lt;p&gt;UPDATEs with WHERE clauses, have more complex semantics, effectively using mutiple snapshots over their lifetimes. Similar to SELECT, they effectively take a snapshot at start to initially choose the rows. However, they then &lt;em&gt;block&lt;/em&gt; until the COMMIT of concurrent transactions that are updating those rows; and once unblocked, take snapshots again to re-evaluate the WHERE clause; and, if it passes for any given row, performs the update on it. This re-evaluation on new snapshots means that such statements may &quot;miss&quot; rows &lt;a class=reference title=&quot;Test showing updates in read committed transactions can miss rows&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_read_committed_update_misses_rows.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;What are typically safe from this class of race-conditions are UPDATEs where the WHERE clause is based on columns that do not change, such as primary keys. From experience, this is the vast majority of UPDATEs.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Repeatable read&lt;/h3&gt;&lt;p&gt;A &lt;em&gt;Repeatable read&lt;/em&gt; transaction&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    cursor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; connection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cursor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    cursor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;SET TRANSACTION ISOLATION LEVEL REPEATABLE READ&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;has 4 important properties.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; It behaves as though a snapshot of the database is taken at the first non transaction-control statement [e.g. a SELECT, UPDATE], which is used throughout the entire transaction, and data it sees is not affected by other transactions COMMITting modifications &lt;a class=reference title=&quot;Test showing repeatable read SELECTs see a single snapshot of committed data&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_repeatable_read_sees_snapshot.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Each of its UPDATEs can block if concurrent transactions UPDATE the same rows, until those transactions COMMIT or ROLLBACK &lt;a class=reference title=&quot;Test showing repeatable read UPDATEs can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_repeatable_read_update_blocks.py&gt;&lt;/a&gt;. This is the same as Read committed.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; This blocking can lead to deadlock if UPDATEs are not ordered &lt;a class=reference title=&quot;Test showing repeatable read UPDATEs can deadlock&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_repeatable_read_update_deadlock.py&gt;&lt;/a&gt;. This is the same as Read committed.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; It will fail on COMMIT if a concurrent transaction committed updates to the same rows &lt;a class=reference title=&quot;Test showing repeatable reads can fail on commit&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_repeatable_read_fails_if_updating_same_rows.py&gt;&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;While attractive, this isn&#39;t enough to avoid race conditions. Multiple concurrent transactions can use the same snapshot &lt;a class=reference title=&quot;Test showing concurrent repeatable reads can see the same snapshot&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_repeatable_read_concurrent_see_same_snapshot.py&gt;&lt;/a&gt;, violate assumptions of your code, and cause bugs.&lt;/p&gt;&lt;h3&gt;Serializable&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Serializable&lt;/em&gt; is the strongest isolation level. It&#39;s similar to Repeatable read in that a snapshot is taken at the beginning of the first non transaction-control statement &lt;a class=reference title=&quot;Test showing serializable transactions see a single snapshot&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_serializable_sees_snapshot.py&gt;&lt;/a&gt;, and it will fail if concurrent transactions attempt to commit updates to the same rows &lt;a class=reference title=&quot;Test showing serializable transactions fail if attempting to commit updates to the same rows&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_serializable_fails_if_update_same_rows.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;However, it will fail in more situations than Repeatable read. Specifically, if at COMMIT the database cannot determine that the transaction could have been performed serially with respect to the read/writes of other transactions, then it will fail with a &lt;code class=inline&gt;django.db.DatabaseError&lt;/code&gt;. This can happen even if they updated different rows &lt;a class=reference title=&quot;Test showing serializable transactions can fail on commit even if they updated different rows&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_serializable_fails_if_updating_different_rows.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;PostgreSQL is somewhat overcautious doing this. For example, the following faily simple example can fail if performed concurrently &lt;a class=reference title=&quot;Test showing serializable transactions can fail on commit if they used count&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_serializable_count_can_fail.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    cursor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; connection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cursor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    cursor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;SET TRANSACTION ISOLATION LEVEL SERIALIZABLE&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    Sock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    Sock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;POST&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;sock__id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Do it yourself: select_for_update&lt;/h3&gt;&lt;p&gt;You can &quot;add to&quot; isolation inside transactions using &lt;code class=inline&gt;select_for_update&lt;/code&gt;. This blocks until the current transaction can obtain the same locks as an UPDATE would on the matching rows, which are then kept until the end of the transaction &lt;a class=reference title=&quot;Test showing select_for_update can block&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_select_for_update_blocks.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A use for this is in a &lt;em&gt;Read committed&lt;/em&gt; transaction to enforce serializability, without the risk of commits failing as they could in a true Serializable transaction, but at the cost of the time of blocking, and the risk of deadlock &lt;a class=reference title=&quot;Test showing select_for_update can deadlock&quot; href=https://github.com/michalc/django-postgres-isolation-levels/blob/master/test_select_for_update_can_deadlock.py&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;At the time of writing this appears to be the only technique that is a first-class Django citizen: no need to write explit SQL.&lt;/p&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;There is no magic or one-size-fits-all approach to database transactions, and you can&#39;t trust Django to always do the right thing, even with a &lt;code class=inline&gt;transaction.atomic()&lt;/code&gt; or &lt;code class=inline&gt;select_for_update&lt;/code&gt;.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;Thank you to a colleague of mine who basically told me what I thought I knew was wrong. Thanks also to the &lt;a href=https://www.postgresql.org/docs/12/transaction-iso.html&gt;PostgreSQL isolation levels documentation&lt;/a&gt; and to the &lt;a href=https://wiki.postgresql.org/wiki/SSI&gt;PostgreSQL Serializable Snapshot Isolation (SSI) documentation&lt;/a&gt; on which some of the above examples are based. These pages are good for further reading for more details on INSERT, DELETE, and other forms of SELECT which are ommitted in the above for brevity.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>JavaScript task queue</title>
    <link href="https://charemza.name/blog/posts/javascript/async/javascript-queue-with-concurrency-limit/" />
    <updated>2020-05-17T11:00:00Z</updated>
    <id>https://charemza.name/blog/posts/javascript/async/javascript-queue-with-concurrency-limit/</id>
    <content type="html">&lt;p&gt;Here&#39;s &lt;code class=inline&gt;Queue&lt;/code&gt;, a small utility function to queue and run tasks with limited concurrency.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Queue&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;concurrency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; running &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tasks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;running &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; concurrency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;running&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;running&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You enqueue a task by passing it to the function returned by &lt;code class=inline&gt;Queue&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token comment&quot;&gt;// Create the queue with a concurrency limit&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; concurrency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; enqueue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Queue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;concurrency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// In this case, each task is an async upload function...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;upload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ... and each task uploads a file&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
files&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;enqueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If there is available concurrency, the task will run [almost] immediately. Otherwise, it will wait until enough tasks ahead of it have completed for it to run within the concurrency limit.&lt;/p&gt;&lt;h3&gt;Use case&lt;/h3&gt;&lt;p&gt;A use for this is part of a file uploader that allows arbitrary numbers of uploads. Although browsers limit the number of connections, they also limit how many requests are queued: Chrome can throw &lt;code class=inline&gt;net::ERR_INSUFFICIENT_RESOURCES&lt;/code&gt; if you attempt to queue too many. To avoid this, you can queue the uploads up front.&lt;/p&gt;&lt;h3&gt;Features&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Can add tasks at any point after queue creation&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; No recursion&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; No polling&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Small API&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Small amount of code&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Leverages async/await syntax: no handling of promises or callbacks, either internally or in client code&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That&#39;s it!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>I admit it: I like Python&#39;s asyncio</title>
    <link href="https://charemza.name/blog/posts/python/asyncio/I-like-python-asyncio/" />
    <updated>2020-05-08T18:50:00Z</updated>
    <id>https://charemza.name/blog/posts/python/asyncio/I-like-python-asyncio/</id>
    <content type="html">&lt;p&gt;Python&#39;s asyncio gets a fair bit of bad press. Some of it I agree with, but there is one aspect of asyncio I like: the API needed for a lot of common tasks is actually fairly small and clear.&lt;/p&gt;&lt;p&gt;Here&#39;s a small but fairly realistic program. It creates a pool of HTTP connections, and uses this to make two concurrent chains of requests.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; asyncio
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; httpx

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;async_main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; httpx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AsyncClient&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        task_1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; asyncio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_task&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;make_http_requests&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;some&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;data&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        task_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; asyncio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_task&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;make_http_requests&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;more&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;data&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; asyncio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gather&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; task_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make_http_requests&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    resp_1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://postman-echo.com/post&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    resp_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://postman-echo.com/post&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;resp_1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;json&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

asyncio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;async_main&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Tasks&lt;/h3&gt;&lt;p&gt;A task is an asyncio thread of execution. Multiple tasks can run concurrently: typically when a task is waiting for some data to be sent/received on the network, other tasks can progress. This is in fact the whole point of asyncio.&lt;/p&gt;&lt;p&gt;In the above example, &lt;code class=inline&gt;asyncio.run&lt;/code&gt; creates the first task, and during that task, each call to &lt;code class=inline&gt;asyncio.create_task&lt;/code&gt; creates another task that runs concurrently.&lt;/p&gt;&lt;h3&gt;await my_function()&lt;/h3&gt;&lt;p&gt;If you see &lt;code class=inline&gt;await my_function()&lt;/code&gt; it means two things:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the current task will schedule &lt;code class=inline&gt;my_function&lt;/code&gt; to run, and wait for it to finish;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; in the meantime other tasks can progress, typically during network I/O.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;asyncio.gather&lt;/h3&gt;&lt;p&gt;To wait for multiple tasks to finish, pass them to &lt;code class=inline&gt;asyncio.gather&lt;/code&gt;, and &lt;code class=inline&gt;await&lt;/code&gt; the result.&lt;/p&gt;&lt;h3&gt;async def my_function():&lt;/h3&gt;&lt;p&gt;A function declared as &lt;code class=inline&gt;async&lt;/code&gt; is very similar to a regular function, but just calling it won&#39;t do anything: it then needs to be scheduled. This is done by either &lt;code class=inline&gt;await&lt;/code&gt;ing its result, or passing it to another function such as &lt;code class=inline&gt;create_task&lt;/code&gt; that will schedule it for you.&lt;/p&gt;&lt;p&gt;Some don&#39;t like having to write &lt;code class=inline&gt;async&lt;/code&gt; and &lt;code class=inline&gt;await&lt;/code&gt;, but in complex multi-task programs, I find it useful to be clear which functions allow other tasks to progress, and which don&#39;t.&lt;/p&gt;&lt;h3&gt;async with&lt;/h3&gt;&lt;p&gt;&lt;code class=inline&gt;async with&lt;/code&gt; is like a regular context manager&#39;s &lt;code class=inline&gt;with&lt;/code&gt;, except that during entry and exit, other tasks may progress. It&#39;s commonly used to create and destroy pools of network connections, often a part of HTTP or database clients.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;That&#39;s it! There are more parts to the API, but for a lot of common use-cases, you don&#39;t need them.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Streaming: a skill gap?</title>
    <link href="https://charemza.name/blog/posts/streaming/data/streaming-not-just-for-big-data/" />
    <updated>2020-02-02T10:40:00Z</updated>
    <id>https://charemza.name/blog/posts/streaming/data/streaming-not-just-for-big-data/</id>
    <content type="html">&lt;p&gt;I&#39;ve noticed a bit of a skill gap: I think a lot of developers are not able to code up &quot;streaming&quot; solutions to problems.&lt;/p&gt;&lt;p&gt;However, streaming can often be useful, even needed, in what are now run-of-the-mill web applications; and wonderfully, we often don&#39;t need anything fancier than the tools already being used: we just need to know how to use them.&lt;/p&gt;&lt;h3&gt;What is streaming?&lt;/h3&gt;&lt;p&gt;Any situation when you process data concurrently with receiving it. This process can be analyzing the data, or just forwarding it onwards.&lt;/p&gt;&lt;h3&gt;What are the benefits of streaming?&lt;/h3&gt;&lt;p&gt;There are two main [potential] benefits.&lt;/p&gt;&lt;h4&gt;Speed&lt;/h4&gt;&lt;p&gt;If you start processing the data sooner, before its all received, then you [might] finish sooner.&lt;/p&gt;&lt;h4&gt;Support higher concurrency / size limits&lt;/h4&gt;&lt;p&gt;Say you would like users to be able to upload 500mb files: in these days of video and hi-res images, this isn&#39;t a far-fetched requirement, even for a standard web application. If you don&#39;t forward the uploaded data onwards while it&#39;s still being uploaded, just a few users uploading concurrently could use all the memory on a server.&lt;/p&gt;&lt;p&gt;[You can upload directly from a browser to the underlying data store. For example, to S3 using presigned URLs. However, this has its own set of drawbacks, ommitted here for brevity.]&lt;/p&gt;&lt;h3&gt;What are typical problems with streaming?&lt;/h3&gt;&lt;p&gt;Streaming is not a perfect/one-size-fits-all solution: it does have its downsides.&lt;/p&gt;&lt;h4&gt;Testing&lt;/h4&gt;&lt;p&gt;You&#39;re testing an upload with a 5KB file, and it works. Are you &lt;em&gt;sure&lt;/em&gt; it&#39;s streaming and will work with a 5GB file? There are two options that I&#39;m aware of.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Actually test a 5GB file [making you have less than 5GB of memory available]. While this is quite a good &quot;real&quot; test, it can be slow.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Hook into both sides of the streaming process, and ensure that the target receives data before the source has sent all of its. You can do this with smaller data, and so such a test can be quick. However, this can be more brittle with respect to refactorings, i.e. the test can fail while the production behaviour continues to work.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Errors&lt;/h4&gt;&lt;p&gt;Handling errors, i.e. communicating and responding to them, can be more difficult.&lt;/p&gt;&lt;p&gt;Conveniently, HTTP has some of this built-in. If streaming an HTTP body with a &lt;code class=inline&gt;content-length&lt;/code&gt; header specifying the number of bytes, if the receiver doesn&#39;t receive that amount by the time the connection has closed, they know an error has occurred. If &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt; is used, if the receiver doesn&#39;t receive a 0-length chunk at the end, they know there has been an error.&lt;/p&gt;&lt;p&gt;It&#39;s not perfect though: there is no way to send an HTTP status code once the body has begun to stream. But for many situations, this is enough.&lt;/p&gt;&lt;p&gt;What to do when an error has occured may be more tricky. With a non-streaming multi-stage pipeline, if one part fails, you can usually retry because you have the source bytes to retry with. However if streaming, the bytes have gone. To retry, have to build in a mechanism to re-retrieve them from the source.&lt;/p&gt;&lt;h4&gt;Complexity&lt;/h4&gt;&lt;p&gt;Especially when considering error handling, retrying, or say, efficiently dealing with bandwidth differences/variation in different parts of the stream, there could be more complexity compared to a non-streaming solution.&lt;/p&gt;&lt;p&gt;This being said, a) you may not need to implement such things [e.g. OS-provided TCP buffers may adequately compensate for bandwidth variation], and b) I suspect the complexity is sometimes overstated, and conflated with unfamiliarity [although it would be naive to think this is isn&#39;t a problem, as mentioned below].&lt;/p&gt;&lt;h4&gt;Performance&lt;/h4&gt;&lt;p&gt;Ironically, there might be a performance &lt;em&gt;penalty&lt;/em&gt; compared to non-streaming solutions due to what could be radically different operations / orders of operations. This could be especially true if using streaming for smaller amounts of data.&lt;/p&gt;&lt;h4&gt;Homogeneity&lt;/h4&gt;&lt;p&gt;Each part of the pipeline needs to support streaming. It&#39;s not the default in a lot of cases: which is unfortunate since you can use code that supports streaming to process data in a non-streaming way [by just using a single &quot;chunk&quot;], but it&#39;s impossible to do the opposite.&lt;/p&gt;&lt;h4&gt;Unfamiliarity&lt;/h4&gt;&lt;p&gt;Streaming has an unfortunate problem: it&#39;s the skill gap itself.&lt;/p&gt;&lt;p&gt;Since fewer developers are familiar with it, issues are less likely to be spotted in code reviews, streaming behaviour may be accidentially broken [if there aren&#39;t appropriate tests on it], there are fewer people to ask for help, and unfortunately any help that is given has a higher chance of being misleading.&lt;/p&gt;&lt;p&gt;This is admittedly a bit of a chicken/egg situation!&lt;/p&gt;&lt;h3&gt;What can I do?&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;I keep hearing my mother say, practice, Harry, practice!&lt;/p&gt;&lt;cite&gt;Harry Kim, Star Trek Voyager&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;Wonderfully, I think you can get a lot of valuable experience from just a few small practice web-based projects.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A GET endpoint that responds with a generated HTTP response of several GBs, just of some fake data.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A GET endpoint that responds with a file from the filesystem of several GBs. Try with with both &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt; and with a specified &lt;code class=inline&gt;content-length&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Proxying a file to or from S3 through a server. Try with a plain HTTP client, not just one that is AWS-aware such as Boto3.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Downloading a Postgres table of several GBs. Try with just a single query. Try responding with CSV or JSON.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Accept a large CSV upload and calculate some basic stats on the columns while its being uploaded, e.g. min, max, mean, standard deviation.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once you have done these, you would be in a much better place to weigh up the trade-offs to know if a streaming solution is right for any given real-world project. At the very least, you&#39;ll be in a better place to review collegues&#39; streaming-based code.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Python generators</title>
    <link href="https://charemza.name/blog/posts/python/streaming/python-streaming-pipelines-and-generators/" />
    <updated>2020-01-12T11:00:00Z</updated>
    <id>https://charemza.name/blog/posts/python/streaming/python-streaming-pipelines-and-generators/</id>
    <content type="html">&lt;p&gt;In these days of &lt;em&gt;medium&lt;/em&gt; data [data that is too big to fit in memory on a single machine, but could otherwise be processed by one], it&#39;s important to know what features your programming language offers to help you process data using streaming. &lt;em&gt;Generator functions&lt;/em&gt; in Python are one such feature. [For brevity, this post will refer to generator functions as &lt;em&gt;generators&lt;/em&gt;].&lt;/p&gt;&lt;h3&gt;Generators vs functions&lt;/h3&gt;&lt;p&gt;Generators differ from functions in that while a function can only return a value once, generators allow you to &quot;return&quot; multiple times. The keyword &lt;code class=inline&gt;return&lt;/code&gt; is not used for this however; instead &lt;code class=inline&gt;yield&lt;/code&gt; is.&lt;/p&gt;&lt;h3&gt;Basic examples&lt;/h3&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;first&#39;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;second&#39;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;third&#39;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Will print out: &quot;first, second, third, &quot;&lt;/span&gt;
words &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; generate_words&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; words&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;word&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;, &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Often the keyword &lt;code class=inline&gt;yield&lt;/code&gt; is itself in a loop. For example, the above is equivalent to the below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;first&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;second&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;third&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; word

&lt;span class=&quot;token comment&quot;&gt;# Will print out: &quot;first, second, third, &quot;&lt;/span&gt;
words &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; generate_words&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; words&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;word&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;, &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Generators can then be chained together to make a pipeline.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generate_words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;first&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;second&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;third&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; word

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;process_words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;words&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; words&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;word&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; apple&#39;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Will print out: &quot;first apple, second apple, third apple, &quot;&lt;/span&gt;
words &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; generate_words&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
processed_words &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; process_words&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;words&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; word &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; processed_words&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;word&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; end&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;, &#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Declaring a generator&lt;/h3&gt;&lt;p&gt;A generator is declared as a function, i.e. with &lt;code class=inline&gt;def function_name(&lt;/code&gt;, but somewhere in its &lt;em&gt;body&lt;/em&gt; it contains at least one instance of the keyword &lt;code class=inline&gt;yield&lt;/code&gt;. [&lt;a href=https://charemza.name/blog/posts/python/streaming/python-streaming-pipelines-and-generators/#criticism&gt;See criticism&lt;/a&gt;]&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Using a generator&lt;/h3&gt;&lt;p&gt;As in the above example, you call the generator and iterate over its return value: each &lt;code class=inline&gt;yield&lt;/code&gt; encountered results in an iteration.&lt;/p&gt;&lt;h3&gt;Purpose of generators&lt;/h3&gt;&lt;p&gt;They allow you to&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; process data in a streaming way [i.e. without loading it all into memory at once];&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; while separating code with different responsibilities [which is often seen as a good thing], into a pipeline of chained generators;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; without having to write custom classes that implement &lt;code class=inline&gt;__iter__&lt;/code&gt; and &lt;code class=inline&gt;__next__&lt;/code&gt; [which is quite boilerplate heavy, and so can be hard to see the data processing that&#39;s going on].&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The earlier basic examples show some of this: the data generation code is separate from the processing code, which is separate from the printing code.&lt;/p&gt;&lt;h3&gt;Real-world example&lt;/h3&gt;&lt;p&gt;A more real-world, and complex, example is constructing a CSV dump of table from a Postgres database using psycopg2, using a single database query [not using an ORM], and streaming it from a Django view. You could do something like the following, which uses a chain of generators.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; csv
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; psycopg2
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; django&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;http &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; StreamingHttpResponse

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch_db_rows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dsn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Named cursor =&gt; server side cursor. Without this, _all_ data from the&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# query will be fetched into memory, which defeats the purpose of streaming&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &#92;
            psycopg2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;connect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dsn&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; conn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &#92;
            conn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cursor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;my_csv_dump&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; cur&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        cur&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;itersize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;
        cur&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;arraysize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;
        cur&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            rows &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cur&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetchmany&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; row &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; row
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;to_csv_bytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rows&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Python&#39;s csv.writer expects a file-like object with a `write` method&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# We give it one, but the `write` method just returns the bytes passed&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DummyFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; value

    csv_writer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; csv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writer&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DummyFile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; quoting&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;csv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;QUOTE_NONNUMERIC&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; row &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; rows&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; csv_writer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writerow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;utf-8&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_streaming_csv_view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    dsn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;DSN&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;SELECT * FROM my_table ORDER BY id&#39;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Define a pipeline of two steps&lt;/span&gt;
    db_rows &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fetch_db_rows&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dsn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    csv_bytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; to_csv_bytes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db_rows&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Django/the web-server adds to this pipeline: adding HTTP chunked&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# headers, and sending data to the underlying socket&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; StreamingHttpResponse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;csv_bytes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;text/csv&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is ok, especially in terms of separation of components in the pipeline: fetching from the database is separate from conversion to CSV, which in turn is separate from any HTTP concerns.&lt;/p&gt;&lt;p&gt;However, &lt;code class=inline&gt;StreamingHttpResponse&lt;/code&gt; has some hidden behaviour [depending on configuration/web-server]. Every time it iterates over the value passed, it results in an HTTP chunk [which includes a short header] being sent through various layers of code, to the socket, and maybe even over the wire. Especially if each CSV line is small, this has quite a high overhead per byte of actual data.&lt;/p&gt;&lt;p&gt;We can do better.&lt;/p&gt;&lt;p&gt;We can send HTTP chunks of [for example] 8KB, even if each CSV row is smaller or bigger than 8KB. To do this we add a buffering step to the pipeline: we don&#39;t need to touch the database code, the CSV-writing code, or the code of &lt;code class=inline&gt;StreamingHttpResponse&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chunk_size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bytes_items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    queue_length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; bytes_item &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; bytes_items&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bytes_item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        queue_length &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bytes_item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; queue_length &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; chunk_size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            to_send_bytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            chunk&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to_send_bytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &#92;
                to_send_bytes&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;chunk_size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to_send_bytes&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;chunk_size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

            queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &#92;
                &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;to_send_bytes&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; to_send_bytes &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &#92;
                &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            queue_length &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;to_send_bytes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; chunk

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; queue_length&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;join&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_streaming_csv_view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    dsn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;DSN&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;SELECT * FROM my_table ORDER BY id&#39;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Our pipeline has an added step to buffer the data into 8KB chunks&lt;/span&gt;
    db_rows &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fetch_db_rows&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dsn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    csv_bytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; to_csv_bytes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;db_rows&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    chunked_csv_bytes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; csv_bytes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; StreamingHttpResponse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;chunked_csv_bytes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content_type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;text/csv&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This mechanism of being able to define and maintain a pipeline, in code, with the minimum of boilerplate, and without needing any extra libraries, in my opinion is wonderful.&lt;/p&gt;&lt;h3&gt;Possible limitations&lt;/h3&gt;&lt;p&gt;Each component in the above pipeline is on the same thread: none of them can actually do anything while another is processing. Specifically, between each of the &lt;code class=inline&gt;fetchmany&lt;/code&gt; calls to the database, the database connection is sitting idle, when it could have been fetching the next batch of data. You may be tempted to do something about this by using threads[/similar] with another intermediate buffer.&lt;/p&gt;&lt;p&gt;My suspicion is that in a lot of situations this wouldn&#39;t increase performance. The downstream connection to the client would already have buffers, and its bandwidth is likely to be much lower than upstream to the database, so the buffers would never get empty: the downstream connection may already be sending as many bytes per second as it can. Threads[/similar] may do nothing but use more resources on the server, hurting performance and increasing costs. My recommendation is to KISS and only complicate the pipeline if you have good evidence it will help in your production cases.&lt;/p&gt;&lt;h3 id=criticism&gt;Criticism&lt;/h3&gt;&lt;p&gt;I find it odd/confusing that the only way to differentiate a function from a generator is to look inside its body and look for the keyword &lt;code class=inline&gt;yield&lt;/code&gt;. Thinking how asyncio functions are declared with &lt;code class=inline&gt;async def my_func():&lt;/code&gt;, I think &lt;code class=inline&gt;generator def my_func():&lt;/code&gt; would have been clearer and more consistent.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Mini HTTP guide for developers</title>
    <link href="https://charemza.name/blog/posts/abstractions/http/http-guide-for-developers/" />
    <updated>2020-01-04T16:00:00Z</updated>
    <id>https://charemza.name/blog/posts/abstractions/http/http-guide-for-developers/</id>
    <content type="html">&lt;p&gt;Frameworks often hide/abstract parts of HTTP away. I think this is often a bit of a shame: it hides what&#39;s possible with HTTP, and so can lead to effects on engineering decisions.&lt;/p&gt;&lt;p&gt;This short guide aims to rectify that. It details a few of the most common and useful parts of HTTP, and is aimed for developers with some experience making or receiving HTTP requests. [In this post, the term HTTP is used to refer to the bytes of the HTTP protocol, which is the same if those bytes are sent over plain TCP, or through a TLS tunnel. The term HTTPS is used only when necessary to distinguish HTTP over TLS.]&lt;/p&gt;&lt;h3&gt;Initialising the connection&lt;/h3&gt;&lt;p&gt;Say we ask our HTTP client to make a GET request to the URL https://example.com/the/path. Firstly, there is no such a thing as a URL in HTTP: it&#39;s just a shorthand that the client parses and uses the different components at various points in the process.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The client resolves example.com to an IP address, say to 1.2.3.4. Note that typically in many cases this would involve sending the string example.com unencrypted across the network.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Initiate a TCP connection to the IP address 1.2.3.4 on port 443: if no port is specified in an HTTPS URL, port 443 is assumed. For HTTP URLs, port 80 is assumed.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Initiate a TLS connection over the top of this TCP connection. This again would uses the domain example.com, in both SNI, and verification of the subsequently supplied certificate. In many cases, the domain name example.com would be transmitted unencrypted across the internet.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Then start the HTTP request/response process. This would use both the domain example.com, as well as /the/path. This process is detailed below.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;The HTTP request&lt;/h3&gt;&lt;p&gt;The client sends the bytes of the HTTP request message over the TLS connection. This is made of a &lt;em&gt;request-line&lt;/em&gt; containing the method and the path, followed by a number of &lt;em&gt;header&lt;/em&gt; key:value pair lines, a blank line, and then the &lt;em&gt;body&lt;/em&gt;. In this case, the body is 0-bytes long, which is typical for GET requests.&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;GET /the/path HTTP/1.1&#92;r&#92;n
host: example.com&#92;r&#92;n
&#92;r&#92;n&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A &quot;line&quot; ends with the two characters &lt;code class=inline&gt;&#92;r&#92;n&lt;/code&gt;. The visual line breaks in the examples shown here are for ease of comprehension, and are not characters that are transmitted.&lt;/p&gt;&lt;h3&gt;The HTTP response&lt;/h3&gt;&lt;p&gt;The server would then respond with a &lt;em&gt;status-line&lt;/em&gt;, some &lt;em&gt;headers&lt;/em&gt;, a blank line, and the body of the response.&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;HTTP/1.1 200 OK&#92;r&#92;n
content-length: 21&#92;r&#92;n
&#92;r&#92;n
The bytes of the body&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;Notable headers&lt;/h3&gt;&lt;p&gt;The important parts of HTTP are the headers: bits of metadata sent before the body of the message [usually].&lt;/p&gt;&lt;h4&gt;Host header&lt;/h4&gt;&lt;p&gt;Usually HTTP clients add a &lt;code class=inline&gt;host&lt;/code&gt; header automatically from the supplied URL. It has two common uses.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; CDNs or reverse proxies use the host header to determine how to route requests onwards.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Application server code uses the host header in a best-effort attempt to determine the domain the HTTP client used to make the request. Depending on the configuration of intermediate proxies, this can mean the application server may not be able to correctly determine what the original domain was.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Content-length header&lt;/h4&gt;&lt;p&gt;HTTP is sent over TCP [or TCP+TLS], which surfaces as a stream of bytes in client code. A &quot;stream of bytes&quot; means that the receiver could just receive a single byte at a time, perhaps even with seconds of delay between each. The receiver has no way to know if it has received all of the bytes, or the connection is just a bit slow. For this reason, requests and responses [that can have a body], can supply a header that tells the other end how many bytes are part of the body of the message. This is the &lt;code class=inline&gt;content-length&lt;/code&gt; header.&lt;/p&gt;&lt;p&gt;Often HTTP clients add this automatically if they know at the time of starting sending the HTTP message how many bytes will be sent in the body.&lt;/p&gt;&lt;h4&gt;Transfer-encoding header&lt;/h4&gt;&lt;p&gt;A HTTP message sender may want to send a body, but it does not know at the start how many bytes make up that body. One option is that it can wait until it knows how many bytes, and set the &lt;code class=inline&gt;content-length&lt;/code&gt; header appropriately. However, this may involve having to buffer all the bytes in memory, which may not be possible or desirable.&lt;/p&gt;&lt;p&gt;An alternative is to use &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt;. With this header, the body of the message is sent in chunks, each prefixed by the number of bytes in that chunk [as it happens, in hexadecimal]. This means the body transfer can be started without knowing how many bytes in total will be sent. Common chunk sizes are between 8kb and 64kb. Often HTTP clients &quot;do the chunking&quot; themselves, adding the chunk header before each chunk as needed.&lt;/p&gt;&lt;p&gt;However, it is usually better to avoid &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt; and instead set a &lt;code class=inline&gt;content-length&lt;/code&gt; header. The receiver can use this in various ways, such as to or be able to allocate resources needed at the start of downloading the body, or estimate time remaining. If the receiver needs to know how many bytes are in the body, using &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt; may be forcing it to buffer the entire body in memory before it can process it further.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Wonderfully, you &lt;em&gt;can&lt;/em&gt; often still stream bodies with a correctly set &lt;code class=inline&gt;content-length&lt;/code&gt;, but you may need to go to a bit of effort to find the right value. For example, to stream a file you may need to query the file system explicity to find the length of the file before starting to fetch its bytes.&lt;/p&gt;&lt;h4&gt;Connection header&lt;/h4&gt;&lt;p&gt;HTTP/1.1 by default keeps connections open after a HTTP request/response, so they can be used for subsequent request/response, and avoid the overhead of new TCP [or TCP+TLS] connections. This referred to as persistant connections, and is often a good thing, but has downsides.&lt;/p&gt;&lt;p&gt;Usually servers would only keep the connections alive for a certain period of time, and then close them. This means there is a race condition: a server could have closed the connection from their point of view, but the client not be aware of this and attempt to re-use the connection, send its bytes [but the server wouldn&#39;t process them], and only later some time would the client would be aware of an error condition. The client may not know if it&#39;s safe to retry the request or not. For example, a client may have no way of determining if a POST errored before or after it was processed by the server. If designing an API, you may wish to implement some sort of unique idempotency-key for such requests. With this, the client can safely retry requests that have failed from its point of view, while the server knows not to reprocess any duplicates, and can still return the response corresponding to the original request.&lt;/p&gt;&lt;p&gt;Another downside is that if you don&#39;t end up re-using the connection, resources would continue to be used needlessly on both the client and the server.&lt;/p&gt;&lt;p&gt;If you want a smaller chance of issues like this, you may explicitly set a &lt;code class=inline&gt;connection: close&lt;/code&gt; header. If you &lt;em&gt;can&lt;/em&gt; deal with such issues, you may wish to design the system to take better advantage of persistant connections. For example, instead of choosing to have multiple S3 buckets each on a different domain, you choose to have one, to take better advantage of per-domain HTTP persistent connections and speed up S3 requests/responses.&lt;/p&gt;&lt;h4&gt;X-forwarded-proto&lt;/h4&gt;&lt;p&gt;This is a modern header: it is often added to requests by HTTP-aware intermediate CDNs or reverse proxies. If the proxy has received an HTTPS connection, it can add &lt;code class=inline&gt;x-forwarded-proto: https&lt;/code&gt;, and otherwise adds &lt;code class=inline&gt;x-forwarded-proto: http&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Without this header, the application server behind a reverse proxy would have no mechanism to know if the client made its request via HTTP or HTTPS. This may be important if you would like to respond to HTTP requests with redirects to HTTPS URLs.&lt;/p&gt;&lt;h4&gt;X-forwarded-for&lt;/h4&gt;&lt;p&gt;Often an application server would like to know the IP address of the client. However, if the client connects to a reverse proxy, and then the reverse proxy connects to the application server, the application server only has details of that final TCP connection. From its point of view, its TCP client is the reverse proxy. This is often not helpful.&lt;/p&gt;&lt;p&gt;The solution to this is that each intermediate proxy adds (to) the &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; header in the request, setting the IP address that its &lt;em&gt;incoming&lt;/em&gt; TCP connection is &lt;em&gt;from&lt;/em&gt;. If there is already an &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; header on its incoming HTTP request, it appends the IP address to this in a comma separated list before forwarding the HTTP request onwards.&lt;/p&gt;&lt;p&gt;This means that the application server can receive an &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; with a long list of IP addresses in it, for example &lt;code class=inline&gt;x-forwarded-for: 1.2.3.4, 5.6.7.8, 9.10.11.12&lt;/code&gt;. Because each server adds to the value of the existing &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; header supplied by a potentially untrustworthy client, care must be taken before trusting any particular value in this list.&lt;/p&gt;&lt;p&gt;For example, you may have an application accessible behind a CDN, which adds an &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt;, so in the application server you may be tempted to trust the first IP in &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt;. However, the CDN would append to any existing values in &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt;. This means that an evil client can send a request with an existing &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; header, set with some IP, and trick the application into thinking the client is at that IP. Knowing this, you may choose to use the &lt;em&gt;last&lt;/em&gt; IP address in the list, thinking that this can be trusted. However, this may also not be a good choice: often applications are accessible both from the CDN, but also directly, even if just via an IP address. An evil client could connect to this with a spoofed &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; header, and again trick the application.&lt;/p&gt;&lt;p&gt;Solutions to this trust issue involve only using the last N values of &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt;, where you have a mechanism to ensure that those N hops a) definitely involved certain infrastructure and b) you trust that infrastruture to manipulate any existing &lt;code class=inline&gt;x-forwarded-for&lt;/code&gt; in a certain way.&lt;/p&gt;&lt;h3&gt;Summary: Reconstructing URLs&lt;/h3&gt;&lt;p&gt;Reconstructing the URL that a client used involves multiple parts of the HTTP request: the path of the start-line, the &lt;code class=inline&gt;host&lt;/code&gt; header, as well as the &lt;code class=inline&gt;x-forwarded-proto&lt;/code&gt; header. For all this to work, intermediate proxies must be appropriately configured.&lt;/p&gt;&lt;h3&gt;Summary: Streaming&lt;/h3&gt;&lt;p&gt;HTTP is often enough for streaming: you may not need anything fancier. If you can determine the full length of the body, set the &lt;code class=inline&gt;content-length&lt;/code&gt; header; otherwise, use &lt;code class=inline&gt;transfer-encoding: chunked&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Summary: HTTP is leaky&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;All non-trivial abstractions, to some degree, are leaky.&lt;/p&gt;&lt;cite&gt;Joel Spolsky&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;HTTP is a leaky abstraction, exposing information on the lower-level TCP [or TCP+TLS] connection via the &lt;code class=inline&gt;x-forwarded-*&lt;/code&gt; headers; giving the ability to control that connection via the &lt;code class=inline&gt;connection&lt;/code&gt; header; and requiring one of &lt;code class=inline&gt;content-length&lt;/code&gt; or &lt;code class=inline&gt;transfer-encoding&lt;/code&gt; headers to make up for the fact that TCP doesn&#39;t have any concept of message length.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;If you want to take full advantage of HTTP, you should be aware of these; compensate for them; and even be able to leverage them when needed to avoid unnecessary time, memory, code, or infrastructure use.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>The core S3 API is beautiful</title>
    <link href="https://charemza.name/blog/posts/http/s3/the-core-s3-api-is-beautiful/" />
    <updated>2019-12-31T08:10:00Z</updated>
    <id>https://charemza.name/blog/posts/http/s3/the-core-s3-api-is-beautiful/</id>
    <content type="html">&lt;p&gt;One of the beautiful, and maybe even genius, things about the core S3 API: it&#39;s just an HTTP PUT to store an object, and an HTTP GET to fetch it. You need &lt;a href=https://gist.github.com/michalc/ccb87856363a895fd1fadf52ab4cdcec&gt;a few headers&lt;/a&gt;, but that&#39;s it.&lt;/p&gt;&lt;h4&gt;Structure of an S3 PUT request&lt;/h4&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;PUT /key/of/the/object HTTP/1.1&#92;r&#92;n
host: my-example-bucket.s3-eu-west-1.amazonaws.com&#92;r&#92;n
authorization: ...&#92;r&#92;n
content-length: ...&#92;r&#92;n
x-amz-content-sha256: ...&#92;r&#92;n
x-amz-date: ...&#92;r&#92;n
&#92;r&#92;n
The bytes of the object&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4&gt;Structure of an S3 GET request&lt;/h4&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;GET /key/of/the/object HTTP/1.1&#92;r&#92;n
host: my-example-bucket.s3-eu-west-1.amazonaws.com&#92;r&#92;n
authorization: ...&#92;r&#92;n
x-amz-content-sha256: ...&#92;r&#92;n
x-amz-date: ...&#92;r&#92;n
&#92;r&#92;n&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This means that as long as you can inject the right headers, you can use &lt;em&gt;any&lt;/em&gt; HTTP client to make the requests. Here&#39;s an example using Python requests.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; requests

&lt;span class=&quot;token comment&quot;&gt;# from https://gist.github.com/michalc/ccb87856363a895fd1fadf52ab4cdcec&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; aws_sig_v4_headers &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; aws_sig_v4_headers

host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;my-example-bucket.s3-eu-west-1.amazonaws.com&#39;&lt;/span&gt;
service &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;s3&#39;&lt;/span&gt;
region &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;eu-west-1&#39;&lt;/span&gt;
path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;/key/of/the/object&#39;&lt;/span&gt;
pre_auth_headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;b&#39;&#39;&lt;/span&gt;
headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; aws_sig_v4_headers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;AWS_ACCESS_KEY_ID&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;AWS_SECRET_ACCESS_KEY&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pre_auth_headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	service&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; region&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;GET&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; requests&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;https://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the core wasn&#39;t so straightforward, I suspect S3 would not be anywhere near as popular, and S3-compatible storage providers may not even exist.&lt;/p&gt;&lt;p&gt;I don&#39;t often say this: but thank you AWS.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Questions to ask yourself when considering a dependency</title>
    <link href="https://charemza.name/blog/posts/methodologies/dependencies/questions-to-ask-yourself-when-considering-a-dependency/" />
    <updated>2019-12-29T12:40:00Z</updated>
    <id>https://charemza.name/blog/posts/methodologies/dependencies/questions-to-ask-yourself-when-considering-a-dependency/</id>
    <content type="html">&lt;h3&gt;What is the underlying data transformation I need?&lt;/h3&gt;&lt;p&gt;If it&#39;s trivial, or almost trivial, consider writing it yourself.&lt;/p&gt;&lt;h3&gt;What does it do in my specific case?&lt;/h3&gt;&lt;p&gt;Consider the actual data transformation you need done, and go through it in the dependency&#39;s codebase. Often libraries have extremely generic components to support lots of use cases. You however, may just have the one, and so this genericness is unnecessary. Generic components are often difficult to debug and difficult to optimise: make sure it&#39;s worth having them.&lt;/p&gt;&lt;h3&gt;What would I do if I do need to make changes to it?&lt;/h3&gt;&lt;p&gt;Ensure you look through its code to see how much of a project it would be to make changes to it, ideally with some specific changes in mind. Keep in mind that in many cases, the dependency authors have no obligation to address your issues, so being aware of what it would take to make certain changes yourself is important. If it would be extremely time-consuming, consider not using the dependency.&lt;/p&gt;&lt;h3&gt;Am I treating code in the dependency as not part of my software?&lt;/h3&gt;&lt;p&gt;It&#39;s an easy bias to fall into: out of sight, out of mind. But dependencies are part of your software: they take your CPU cycles, your memory, their bugs are your bugs, their security issues are your security issues, their updates are your updates. Consider reviewing its code as you would any other PR into your codebase.&lt;/p&gt;&lt;h3&gt;How much of its API am I actually using?&lt;/h3&gt;&lt;p&gt;If you&#39;ve using 1 function of a 30 function API, you may be introducing a lot of dead/unreachable code into your software, as well as something that may not be as tailored to your use case as it could be. This means that if changes need to be made to tailor to your case, they would likely be harder than they would otherwise be. Consider just writing it yourself, or if licensing allows, just including that function in your codebase.&lt;/p&gt;&lt;h3&gt;What&#39;s the coverage like when I run my tests on it?&lt;/h3&gt;&lt;p&gt;Consider introducing the dependency, but then running your test suite with code coverage &lt;em&gt;including&lt;/em&gt; the dependency&#39;s code. If it&#39;s low, you would be introducing a lot of code into your project that is not covered by your own test suite.&lt;/p&gt;&lt;h3&gt;Can I write a simpler version myself that&#39;s enough for now?&lt;/h3&gt;&lt;p&gt;What has been specified as &quot;needed&quot; often isn&#39;t really needed quite yet: often it&#39;s acceptable to release something incrementally. Consider writing a simpler version, geting feedback, and then moving to the fuller/more complex versions armed with confirmation on exactly what complexity is needed. You can iterate on your own-rolled solution, or decide that introducing the dependency really is the best move.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;How much does it offer over its dependencies?&lt;/h3&gt;&lt;p&gt;Sometimes dependencies just offer a thin layer over their own dependencies. Consider depending on those directly [and then asking yourself these questions for all of them].&lt;/p&gt;&lt;h3&gt;Am I adding it because I&#39;m scared of implementing it myself?&lt;/h3&gt;&lt;p&gt;Consider spending some time trying to do it to overcome the fear. You might realise it&#39;s not such a big and scary thing. Keep the scope focused: your aims are often not the aims of the dependency&#39;s authors, such as creating a generic library to be used in a lot of cases. Even if you do think you will need generic components, this can often be done later when you have confirmation of your requirements.&lt;/p&gt;&lt;h3&gt;How long would it take for me write the functionality I need?&lt;/h3&gt;&lt;p&gt;If your estimate is a few hours or days, consider just doing it. Even if you abandon this and decide to use the dependency in the end, this is not necessarily time wasted: you would have learnt more about what the dependency does, and so what your own software does, and puts you in a better position for supporting a wider range of future requirements.&lt;/p&gt;&lt;h3&gt;Am I adding it because its marketing suggests it does a lot?&lt;/h3&gt;&lt;p&gt;Often dependencies market themselves as doing/having done a lot [even just via a README], which indirectly suggests that attempting the same thing yourself would be foolish. This may be misleading in two ways: they may have not done a lot; or they may well have done a lot, but you might be depending on just a tiny sliver of that work. Consider keeping in mind &lt;em&gt;your&lt;/em&gt; specific use case, the data transformation &lt;em&gt;you&lt;/em&gt; need it to perform, and looking through its code.&lt;/p&gt;&lt;h3&gt;Can I still add it later easily?&lt;/h3&gt;&lt;p&gt;If yes, consider implementating part of it yourself, and adding it later when you have more evidence of its usefulness.&lt;/p&gt;&lt;h3&gt;Am I adding it &quot;just in case&quot; I need some of the functionality?&lt;/h3&gt;&lt;p&gt;Be &lt;em&gt;very&lt;/em&gt; careful of this. It&#39;s often easier to add a dependency later than to remove it, so consider deferring the addition until you have good evidence that it&#39;s a benefit.&lt;/p&gt;&lt;h3&gt;Am I treating recent commits as evidence of free work?&lt;/h3&gt;&lt;p&gt;It&#39;s easy to look at recent commits and see the author as another member of your team. In most cases, they are under no obligation to do anything about your issues. It&#39;s a risk to depend on this. This risk may be required or acceptable, but it may be unnecessary or too high.&lt;/p&gt;&lt;h3&gt;Am I treating a lack of recent commits as a dead project and so something to avoid?&lt;/h3&gt;&lt;p&gt;There may be nothing wrong with a project that has had no recent activity. Say it has a small API, few or no dependencies, you look through the code and its fine: then there may be little to do on it. It may be just be finished! Or at very least, finished enough for you to use.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>You might not need a class</title>
    <link href="https://charemza.name/blog/posts/python/state/you-might-not-need-a-class/" />
    <updated>2019-05-09T20:35:00Z</updated>
    <id>https://charemza.name/blog/posts/python/state/you-might-not-need-a-class/</id>
    <content type="html">&lt;p&gt;When writing Python, sometimes you need to store/manipulate state. There are two typical options:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Plain data structures [dictionaries, lists, sets etc.], passed to functions which perform mutation.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Instances of classes, i.e. objects, with the state as members, mutated using instance methods.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;However, there is a third way:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A class-like function [I didn&#39;t come up with this term], with the state stored in a closure.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A class-like function is a &quot;constructor&quot; that returns &quot;public&quot; functions that can manipulate its state.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Capitalised to make it clear it&#39;s a &quot;constructor&quot;&lt;/span&gt;

    state_1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
    state_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;func_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;nonlocal&lt;/span&gt; state_1
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;func_2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;nonlocal&lt;/span&gt; state_2
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;func_3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; func_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; func_2  &lt;span class=&quot;token comment&quot;&gt;# Typically, 1 to 2 funcs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Used as, for example&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;func_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; func_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MyClass&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Such class-like functions have a few nice properties.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; They are &lt;em&gt;less&lt;/em&gt; flexible than classes. Yes: this is a nice property when dealing with state. You can&#39;t just define a few more methods, add @properties, override methods in a subclass etc. State is often seen a source of bugs, and sometimes it&#39;s better to really limit how it&#39;s mutated.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; To test it, you are strongly pushed to only test the public interface, i.e. the functions returned from the function, rather than private implemenation details.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; They encourage stronger separation of responsibilities between code that mutates state, and code that doesn&#39;t. I would be wary of too strongly touting benefits of &quot;separation of responsibilities&quot;; but separating stateful and non-stateful code, all-things-being-equal, is good.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You can name the returned functions whatever you like, even &lt;code class=inline&gt;_&lt;/code&gt; if not needed.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=http://tech.magnetic.com/2015/05/optimize-python-with-closures.html&gt;There are cases when it&#39;s faster&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; They allow you to escape &lt;a href=http://kmkeen.com/self-hell/ &gt;self-hell&lt;/a&gt; [although you may need more &lt;code class=inline&gt;nonlocal&lt;/code&gt;].&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As examples, &lt;a href=https://github.com/michalc/lowhaio&gt;lowhaio&lt;/a&gt; and &lt;a href=https://github.com/michalc/aiodnsresolver&gt;aiodnsresolver&lt;/a&gt; both use class-like functions.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>I admit it: I like Python&#39;s ternary operator</title>
    <link href="https://charemza.name/blog/posts/python/syntax/python-ternary-operator/" />
    <updated>2019-03-09T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/python/syntax/python-ternary-operator/</id>
    <content type="html">&lt;p&gt;Lots of people hate Python&#39;s ternary operator. If laid out as:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;selected_value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value_1 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_1 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; value_2 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_2 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; value_3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I can see why: it&#39;s hard to see what&#39;s going on. However, laid out differently, it&#39;s a different story:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;selected_value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &#92;
  value_1 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_1 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &#92;
  value_2 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_2 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &#92;
  value_3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can much more clearly see what the possible values are, and under what conditions they&#39;re used.&lt;/p&gt;&lt;p&gt;And I claim it&#39;s safer. The clarity itself is a contributing factor to this. But also, compared to an if-elif-else statement, it&#39;s harder to get a NameError by accidentally not assigning a value to a variable. This is especially true with complex cases, when you might otherwise have multiple nested if-elif-else statements.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Reducing risk of release day</title>
    <link href="https://charemza.name/blog/posts/git/workflows/reducing-risk-of-release-day/" />
    <updated>2019-03-02T22:30:00Z</updated>
    <id>https://charemza.name/blog/posts/git/workflows/reducing-risk-of-release-day/</id>
    <content type="html">&lt;p&gt;Ideally, changes of behaviour are released incrementally to base your next steps on feedback. But sometimes you think this just isn&#39;t possible. Maybe it had been decided that large public behaviour changes must all go live at once; or sometimes planned changes are so large, you might initially think that there is no alternative other than for it all to go live at once, a few days, weeks, months [or even longer!] down the road. Ironically, it is exactly for the sorts of changes where you might have difficulty seeing how it could be split up that are the most important to split up: they are complex and so high risk.&lt;/p&gt;&lt;p&gt;Three common classes of such changes are:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; a user-facing feature that is seemingly small, but actually needs large scale internal code changes;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; a larger user-facing feature-set that needs lots of UI and backend changes [often released at once for marketing reasons];&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; an internal property of an application that is seemingly all-or-nothing, such as bumping the version of a framework through a breaking change that requires large scale changes in the codebase.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can automated test, QA, or load test these large changes all you like, but these checks are rarely a replacement for feedback from production: in terms of bugs but &lt;em&gt;especially&lt;/em&gt; for performance. The performance characteristics of large swathes of code that has not run in production by large numbers of users can rarely be predicted.&lt;/p&gt;&lt;p&gt;However, it is often still possible to split up the changes to get production feedback on a lot of code before release day. As is typical for many [all?] changes, each change should be:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; small: ~1 day&#39;s work;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; safe: reviewed/tested/QA-ed as you deem appropriate;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; released: so the code actually runs in production, and its result used.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To split the work, on what seem to be &quot;all at once&quot; problems, into such pieces, there are two classes of techniques, detailed below.&lt;/p&gt;&lt;h3&gt;Long-running feature branch [but keeping it as small as possible]&lt;/h3&gt;&lt;p&gt;A long-running feature branch is often the traditional way of doing large changes, periodically merging in any changes from the master branch, and releasing by merging to master at the end. This is by far the worst technique. Not only are you essentially maintaining two versions of the application [similar to The Big Rewrite], but come release day, it will all hit production at once!&lt;/p&gt;&lt;p&gt;However, a variation of this can often have great properties that reduce risk on release day. Instead of just periodically taking changes from master into the feature branch, you also do it other way around. In more detail...&lt;/p&gt;&lt;p&gt;As you&#39;re working on a feature branch, always think about what could be released [and used in production] first, without changing the public behaviour. Put another way, try to refactor* the production code so it can run &lt;em&gt;both&lt;/em&gt; the original behaviours, and the new ones, and release the refactoring before the actual feature is released.&lt;/p&gt;&lt;p&gt;Ideally, you can plan this: do the refactoring up-front, and then move onto the new behaviour that uses the refactored code. However this is often not possible: not until having written some of the feature do you then realise some parts of the code need to be refactored, and this should/could be released first. It can be tricky to reorder this: the refactoring done &lt;em&gt;second&lt;/em&gt; is to be released &lt;em&gt;first&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;There is a technique that is especially helpful here: keep each commit small, releasable, and put test additions/changes in the same commit as the corresponding production code change. This requires a bit of diligence, and often use of &lt;code class=inline&gt;git rebase -i&lt;/code&gt; to edit and squash commits. But if you do this, then it&#39;s &lt;em&gt;far&lt;/em&gt; easier to re-order them safely, again using &lt;code class=inline&gt;git rebase -i&lt;/code&gt;: the safety is achieved by running the tests* for each re-ordered commit to make sure everything works. So, if you do refactoring at the &lt;em&gt;end&lt;/em&gt; of a feature branch, with small, releasable commits, you can then re-order them so the refactoring is put at the &lt;em&gt;beginning&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;There may be conflicts when you re-order, but if you fix them, run tests* on each commit, and it all works, then you know&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the refactoring doesn&#39;t break any of the existing code or the feature;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the refactoring can be usefully &lt;em&gt;released&lt;/em&gt; first.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So you do exactly that: you separate the refactoring commit(s) into a separate branch [&lt;code class=inline&gt;git cherry-pick&lt;/code&gt; can be used for this], and go through your process to merge this into master and get it released. You then &lt;em&gt;rebase&lt;/em&gt; your feature branch onto master, and ensuring to fix conflicts and making sure tests pass for each commit. At this point, master will contain the refactoring for the change, and the feature branch will just contain the [non refactoring] change. Repeat for as many refactorings as needed.&lt;/p&gt;&lt;p&gt;The rebase onto master, as opposed to a merge: this replays [the diff of] each commit from the feature branch, one by one, and with each you fix conflicts and can run tests. Here is where the benefit of rebase [over merge] with small releasable commits is revealed: you get smaller conflicts which are usually more managable.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Another benefit to this comes if you&#39;re not the only person working on this code. Getting each refactoring into master as soon as it&#39;s known to be required, means the rest of the team can rebase onto these changes, and deal with any conflicts sooner [and so typically with less or simpler code] rather than later. If each person in the team has been writing small, releasable commits on their own branches, then any conflicts can often be safely and quickly sorted out.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;The most extreme example of this that I&#39;ve done was for Django upgrade of a fairly complex application that was coupled to a lot of subtle/semi-private Django behaviour. To limit the risk of the Django upgrade + application code changes all going live at once, I repeatedly refactored the application code so the same code worked in both versions. Ultimately, there were about ~20 refactoring branches, each reviewed, QA-ed, and released, &lt;em&gt;before&lt;/em&gt; the actual Django upgrade itself.&lt;/p&gt;&lt;p&gt;Note: it was crucial that the actual code changes are run in production to get value from this technique. If I had code like the below,&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; DJANGO_VERSION &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; NEW&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I would have been effectively incrementally adding a feature flag with lots of code behind it, which would have all been switched on on release day. This may be acceptable for an initial investigation, but &lt;em&gt;before&lt;/em&gt; the actual production switch of Django version, it should be refactored to not have this conditional behaviour, as discussed below.&lt;/p&gt;&lt;h3&gt;Feature flag [minimising code behind flag]&lt;/h3&gt;&lt;p&gt;An alternative to a feature branch is a feature flag. This is in many ways similar to a feature branch, as in the feature code is kept from running by most users. However, with a feature flag the code is deployed to the production application, but it&#39;s only run by certain users with a certain flag enabled, or perhaps by hitting a certain URL.&lt;/p&gt;&lt;p&gt;This is often acceptable at the beginning of a feature [say, to get feedback on the UI of a feature before it&#39;s fully designed or working], but always consider what will happen down the line on release day. On release day, the feature flag will be effectivly enabled for all users, and potentially lots of code will be run by lots of users that wasn&#39;t before.&lt;/p&gt;&lt;p&gt;For this reason, don&#39;t enable the feature flag for everyone until the code behind the feature flag is minimised. Often it&#39;s possible to have not much more than just the UI that enables the particular feature. The rest of the code was run by large number of users long before the public release.&lt;/p&gt;&lt;p&gt;A great benefit of this technique is that often it is possible to incrementally refactor* a lot of the code out from behind the feature flag. Even if at the beginning there might be a fair bit of code behind it, you can go through several release/QA cycles, moving more and more of the code into production &lt;em&gt;before&lt;/em&gt; release day.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;A frequent example of this is changing a feature that uses 1 of &quot;something&quot;, to using many. You can have a feature flag that enables the UI for this, but often to get this working requires changes through multiple layers of code, and possibly even the database.&lt;/p&gt;&lt;p&gt;What you can often do is to make a configuration option that limits the maximum of the &quot;something&quot;, and configure all users to have a maximum of 1. Then you can work, layer at a time, making it work with N, but because each user is configured to have a maximum of 1, they will see no difference. Each layer can be tested*, QA-ed, and released. If there are problems, you have a lot of chances to get feedback before release day. Only when all the layers of the code are done, can you change the configuration option for production users.&lt;/p&gt;&lt;p&gt;In this particular case, once you know of nothing more to be done to the code, you don&#39;t even have to release the feature to all users all at once. You can slowly bump up the maximum for some users, in order to be able to get feedback from production, in terms of behaviour of the UI, from any reported bugs, and from performance. If you don&#39;t have a production use-case for each user to have a different maximum, then you can then set the maximum globally and remove some of the per-user configuration.&lt;/p&gt;&lt;h3&gt;When to use which technique?&lt;/h3&gt;&lt;p&gt;I don&#39;t know of a hard-and-fast rule: each case is different. However, some considerations:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A long running [but kept small] feature branch may not be feasible when more than one person needs to work on that feature branch. A feature flag is probably more helpful here: multiple people can more easily work on branches changing code behind the flag / refactoring it out from behind the flag.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Long-running feature branches, even if as small as possible, are harder to work with when there are lots of conflicting master branch changes: you may hit The Big Rewrite issues of maintaining two applications. A feature flag may be better here: impact on the &quot;other&quot; application will be visible in the code exactly when making changes, rather than making it a problem down the line when merging/rebasing.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A feature flag may not be helpful for a change that needs a lot of refactoring, but which is itself small in terms of final change that will be released on release day, and can/should be done by one person. A long-running [small] feature branch will likely be suitable in this case.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Addressing common critiscms&lt;/h3&gt;&lt;p&gt;There are a a few common critiscms of the frequent-release techniques:&lt;/p&gt;&lt;h4&gt;Each release introduces risk, and so releasing often is more risky than less.&lt;/h4&gt;&lt;p&gt;At first glance, this argument makes sense. However, these techniques push you to split up what you will be releasing &lt;em&gt;anyway&lt;/em&gt;, rather than releasing more things [which could be more risky].&lt;/p&gt;&lt;h4&gt;Frequent releasing == testing less. This is risky! We don&#39;t do risk here.&lt;/h4&gt;&lt;p&gt;Make sure each release is tested/QA-ed as you would any other change. This is not &quot;move fast and break things&quot;, this is &quot;do what you need to do to minimise the risk of each change that is going to happen anyway&quot;.&lt;/p&gt;&lt;h4&gt;This is wasting QA time: you&#39;ll testing the same thing multiple times&lt;/h4&gt;&lt;p&gt;If a change is deemed &quot;large&quot;, then I think it&#39;s more appropriate to spend longer on QA: this is time spent reducing risk.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;* It&#39;s important to have high-level feature/integration tests to support refactoring and safe rebasing. Low-level tests [often called unit tests] are less helpful.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>S3 path/pseudo-folder locking</title>
    <link href="https://charemza.name/blog/posts/python/asyncio/s3-path-locking/" />
    <updated>2018-11-18T18:50:00Z</updated>
    <id>https://charemza.name/blog/posts/python/asyncio/s3-path-locking/</id>
    <content type="html">&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML&quot; defer=&quot;&quot;&gt;&lt;/script&gt;&lt;p&gt;AWS S3 is a key/value store, with operations that only operate on a single key at a time. There is no native concept of a folder: the closest thing is a group of keys with the same prefix. These facts mean that in applications that treat S3 as a filesystem, operations on such &lt;em&gt;pseudo&lt;/em&gt;-folders, such as a renames or copies, are not atomic: if performed by different users at the same time, corruption of the key structure can occur. Here, I present a method to mitigate the chance of this based on locking.&lt;/p&gt;&lt;p&gt;Some familiarity with S3 is assumed, especially the &lt;a href=https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html&gt;PUT&lt;/a&gt;/&lt;a href=https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html&gt;GET&lt;/a&gt;/&lt;a href=https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html&gt;DELETE&lt;/a&gt; APIs for objects.&lt;/p&gt;&lt;blockquote&gt;&lt;p style=&quot;text-align: center&quot;&gt;&lt;strong style=&quot;font-weight: bold;&quot;&gt;This post is not finished: expect lots of typos and little sense&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;Pseudo-folders, paths, and key prefixes&lt;/h3&gt;&lt;p&gt;We describe pseudo-folders through an example. Consider 4 objects stored in an S3 bucket, with slashes in their keys. Other than the fact that they are in the same bucket, there is no structure.&lt;/p&gt;&lt;ul class=folder-root&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;( a/b/c &#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;( a/b/d &#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;( e/f/g &#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;( e/f/h &#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;However, since these keys have slashes, and they have common prefixes, we can seem them as though they are part of a tree [also known as a hierarchy] of paths, below the root path &#92;(/&#92;), where the lowest branches in the tree map to the objects in the bucket.&lt;/p&gt;&lt;ul class=folder-root&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li&gt;&lt;div class=folder-item-label&gt;&#92;(/a&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/a/b&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/a/b/c → a/b/c&#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/a/b/d → a/b/d&#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f/g → e/f/g&#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f/h → e/f/h&#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The pseudo-folders in this example are those at paths &#92;(/&#92;), &#92;(/a&#92;), &#92;(/a/b&#92;), &#92;(/a/b/c&#92;), &#92;(/e&#92;), &#92;(/e/f&#92;) and &#92;(/e/f/h&#92;).&lt;/p&gt;&lt;p&gt;This list of pseudo-folders &lt;em&gt;includes&lt;/em&gt; the paths that map to objects: /a/b/c and /e/f/h. While a traditional filesystem does not allow a path to be &lt;em&gt;both&lt;/em&gt; a folder and a file, S3 does not forbid the equivalent: for example both a/b and a/b/c could be keys to objects. This fact means that &lt;em&gt;every&lt;/em&gt; path should be treated as a pseudo-folder.&lt;/p&gt;&lt;p&gt;Note that &lt;a href=https://docs.aws.amazon.com/AmazonS3/latest/API/v2-RESTBucketGET.html&gt;List Objects API&lt;/a&gt; allows you to list objects in a pseudo-folder, i.e. objects with the same key prefix, using the &lt;code class=inline&gt;prefix&lt;/code&gt; and &lt;code class=inline&gt;delimeter&lt;/code&gt; options, and the AWS console uses this to provide a reasonable illusion of folders. However, there is no API that provides atomic operations on all the objects on such lists.&lt;/p&gt;&lt;h4&gt;Notation&lt;/h4&gt;&lt;p&gt;S3 object keys will not start with a slash. Corresponding paths and pseudo-folders will always be written in full, and starting with a foward slash /.&lt;/p&gt;&lt;h3&gt;Scope&lt;/h3&gt;&lt;p&gt;We consider 4 categories of operations on pseudo-folders that we would like to be atomic.&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Write &amp; Delete&lt;/dt&gt;&lt;dd&gt;A write of one pseudo-folder&lt;/dd&gt;&lt;dt&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Rename&lt;/dt&gt;&lt;dd&gt;A write of two pseudo-folders&lt;/dd&gt;&lt;dt&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Copy&lt;/dt&gt;&lt;dd&gt;A read of one pseudo-folder, write of another pseudo-folder&lt;/dd&gt;&lt;dt&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Read&lt;/dt&gt;&lt;dd&gt;A read of one pseudo-folder&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;We don&#39;t try to maintain atomicity in the case of the server going down mid-way through such operations. We also don&#39;t concern ourselves with the eventual consistency properties of some operations on S3. We also only consider locking schemes, and only consider schemes where locking and unlocking on a given path takes a number of operations that is independent of the number of locks currently held, and independent of the number of descendents the path has, i.e. is constant-time.&lt;/p&gt;&lt;h4 id=single-object-get&gt;Single-object GETs&lt;/h4&gt;&lt;p&gt;It should be noted that a GET to a single object in S3 is atomic: it will either succeed with a consistent object, or fail with a 404. Therefore GETs to single objects won&#39;t typically need to be protected by locks. Note that whenever we mention a read of a pseudo-folder, we are concerned with a read that need an atomic view of the entire pseudo-folder. For example, if we needed to make a zip file from all of its contents.&lt;/p&gt;&lt;p&gt;Single-object PUTs however, even though they are also atomic, depending on the strucure of keys the application enforces, may need locking in order to maintain.&lt;/p&gt;&lt;h3&gt;Locking interface &amp;amp; usage&lt;/h3&gt;&lt;p&gt;Knowing the categories of operations we are interested in, we can design an API for a class, &lt;code class=inline&gt;PathLock&lt;/code&gt;. If implemented, we could write something like the below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; asyncio
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; path_lock &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; PathLock

lock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PathLock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; write&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; write&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path_from&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path_to&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; write&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path_from&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path_to&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path_from&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path_to&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path_from&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; write&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path_to&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; write&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each &lt;code class=inline&gt;path&lt;/code&gt; argument can be some object that represents the path of a pseudo folder, such as &lt;a href=https://docs.python.org/3/library/pathlib.html#pathlib.PurePosixPath&gt;PurePosixPath&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Granularity&lt;/h3&gt;&lt;p&gt;As is typical with locks, we have the problem of making the lock as &lt;em&gt;granular&lt;/em&gt; as possible: it should only block operations that would be unsafe to run concurrently, and other operations should progress unhampered. In our case unsafe combinations of operations on a pseudo-folder are &quot;writes and writes&quot;, and &quot;writes and reads&quot;. We aim to make a locking system that blocks these, but allows everything else to proceed&lt;/p&gt;&lt;p&gt;At first thought, it might appear that a read/write lock on each pseudo-folder could be enough. However, given that pseudo folders can be nested, it requires some thought to actually implement such a lock around such operations in order to acheive a granular lock and constant time locking.&lt;/p&gt;&lt;p&gt;We&#39;ll start with an example, and then generalise.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;Consider a copy of &#92;(/a/b&#92;) to &#92;(/a/b&#39;&#92;). This is a read of the pseudo folder at the path &#92;(/a/b&#92;), i.e. from all possible keys prefixed with &#92;(a/b/&#92;), and a write of &#92;(/a/b&#39;&#92;), i.e. to keys prefixed with &#92;(a/b&#39;/&#92;).&lt;/p&gt;&lt;ul class=folder-root&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li&gt;&lt;div class=folder-item-label&gt;&#92;(/a&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=&quot;folder-item-label folder-item-label-read&quot;&gt;&#92;(/a/b&#92;) (read)&lt;/div&gt;&lt;ul class=&quot;folder-item-children folder-item-children-read&quot;&gt;&lt;li class=folder-item&gt;&lt;div class=&quot;folder-item-label folder-item-label-read&quot;&gt;&#92;(/a/b/c → a/b/c&#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=&quot;folder-item-label folder-item-label-read&quot;&gt;&#92;(/a/b/d → a/b/d&#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li class=&quot;folder-item folder-item-spacer&quot;&gt;&lt;div class=&quot;folder-item-label folder-item-label-write&quot;&gt;&#92;(/a/b&#39;&#92;) (write)&lt;/div&gt;&lt;ul class=&quot;folder-item-children folder-item-children-write&quot;&gt;&lt;li class=folder-item&gt;&lt;div class=&quot;folder-item-label folder-item-label-write&quot;&gt;&#92;(/a/b&#39;/c → a/b&#39;/c&#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=&quot;folder-item-label folder-item-label-write&quot;&gt;&#92;(/a/b&#39;/d → a/b&#39;/d&#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f&#92;)&lt;/div&gt;&lt;ul class=folder-item-children&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f/g → e/f/g&#92;)&lt;/div&gt;&lt;/li&gt;&lt;li class=folder-item&gt;&lt;div class=folder-item-label&gt;&#92;(/e/f/h → e/f/h&#92;)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;During this copy, the following operations are not compatible, and should be blocked to ensure atomicity:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; reads of the pseudo-folder &#92;(/a/b&#39;&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; reads of any descendant pseudo-folders of &#92;(/a/b&#39;&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; reads of the ancestor pseudo-folders of &#92;(/a/b&#92;) and &#92;(/a/b&#39;&#92;), namely &#92;(/a&#92;) and &#92;(/&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; writes of the pseudo-folders &#92;(/a/b&#92;) and &#92;(/a/b&#39;&#92;);&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; writes of an any descendent pseudo-folders of &#92;(/a/b&#92;) and &#92;(/a/b&#39;&#92;);&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; write of the ancestor pseudo-folders of &#92;(/a/b&#92;) and &#92;(/a/b&#39;&#92;), namely &#92;(/a&#92;) and &#92;(/&#92;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All other read and write operations are compatible.&lt;/p&gt;&lt;p&gt;We can write these rules more succinctly using the concept of &lt;em&gt;lineage&lt;/em&gt;. We define &#92;(&#92;mathbb{L}(p)&#92;) as the lineage of a path &#92;(p&#92;): the union of all of &#92;(p&#92;)&#39;s ancestors, descendants, and &#92;(&#92;{p&#92;}&#92;) itself. We also define &#92;(R(A)&#92;) as all the read operations on the set of paths &#92;(A&#92;), and &#92;(W(A)&#92;) as all the write operations on the set of paths &#92;(A&#92;). Using these terms, we can say that a copy from the pseudo-folder at path &#92;(/a/b&#92;) to &#92;(/a/b&#39;&#92;) should block&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(W(&#92;mathbb{L}(/a/b))&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(R(&#92;mathbb{L}(/a/b&#39;))&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(W(&#92;mathbb{L}(/a/b&#39;))&#92;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We generalise this further and state that for a path &#92;(p&#92;)&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(R(&#92;{p&#92;})&#92;) should block &#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(W(&#92;{p&#92;})&#92;) should block &#92;(W(&#92;mathbb{L}(p))&#92;) and &#92;(R(&#92;mathbb{L}(p))&#92;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We can express these rules a different way, and say that for any path &#92;(p&#92;)&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(R(&#92;mathbb{L}(p))&#92;) should block &#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(W(&#92;mathbb{L}(p))&#92;) should block &#92;(W(&#92;mathbb{L}(p))&#92;) and &#92;(R(&#92;mathbb{L}(p))&#92;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The second rule above implies the first, so we just need:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(W(&#92;mathbb{L}(p))&#92;) should block &#92;(W(&#92;mathbb{L}(p))&#92;) and &#92;(R(&#92;mathbb{L}(p))&#92;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We can see that out aim is to be able to construct a read/write lock on &#92;(&#92;mathbb{L}(p)&#92;) for all paths &#92;(p&#92;).&lt;/p&gt;&lt;p&gt;We can also express this as a compatibility table, showing what operations should, and should not, run concurrently for two tasks. We also define &#92;(&#92;mathbb{L}^c(p)&#92;) as the set of all paths &lt;em&gt;not&lt;/em&gt; in the lineage of &#92;(p&#92;) in order to better show how locking schemes differ in the concurrency they allow.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;This table also gives us a way to compare locking schemes. All schemes must block the 2 incompatible combinations of operations, but that leaves 4 combinations they should allow for maximum concurrency, and so we can assign each potential scheme a score out of 4.&lt;/p&gt;&lt;h3&gt;Global exclusive lock: 0/4&lt;/h3&gt;&lt;p&gt;As an initial example, we can consider an extremly simple implementation of &lt;code class=inline&gt;PathLock&lt;/code&gt; that ignores its arguments and defers to a single instance of &lt;a href=https://docs.python.org/3/library/asyncio-sync.html#asyncio.Lock&gt;asyncio.Lock&lt;/a&gt;.&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/3a50e77256079ea413746587160b0dc1.js&gt;&lt;/script&gt;&lt;p&gt;As you might expect, this doesn&#39;t have great concurrency properties:&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;But the implementation is tremendously simple. Keeping in mind that &lt;a href=https://charemza.name/blog/posts/python/asyncio/s3-path-locking/#single-object-get&gt;single-object GETs don&#39;t need to be locked&lt;/a&gt;, this may be good enough for many situations.&lt;/p&gt;&lt;h3&gt;Global read/write lock: 2/4&lt;/h3&gt;&lt;p&gt;Better locking can be acheived by using a global &lt;a href=https://charemza.name/blog/posts/python/asyncio/read-write-lock/ &gt;read/write lock&lt;/a&gt;, with two modes &#92;(&#92;overline{R}&#92;) and &#92;(&#92;overline{W}&#92;), with compatibility table&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{R}&#92;)&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{W}&#92;)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{R}&#92;)&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{W}&#92;)&lt;/th&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;[To distinguish read and write locks from the similarly named operations, we write locks with a horizontal bar.]&lt;/p&gt;&lt;p&gt;which could be implemented as below.&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/6e4b528d04b05e299ca714a9e8fa1dcd.js&gt;&lt;/script&gt;&lt;p&gt;As you might expect, this allows more concurrency than the global exclusive lock.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;As when using the global exclusive lock, this may well be good enough for many cases.&lt;/p&gt;&lt;h3&gt;Ancestor-locking and read/write locks on each path: 3/4&lt;/h3&gt;&lt;p&gt;To improve upon the above, we construct an algorithm inspired by &lt;a href=https://charemza.name/blog/posts/python/asyncio/s3-path-locking/#ref-1&gt;[1]&lt;/a&gt;. Instead of a global read/write lock, we maintain a read/write lock for each path &#92;(p&#92;).&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{R}(p)&#92;)&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{W}(p)&#92;)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{R}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{W}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;When we need to access, either read or write, to a pseudo-folders, we acquire the &lt;em&gt;write&lt;/em&gt; lock &#92;(&#92;overline{W}(p)&#92;) on the paths of the pseudo folders, and for all of the ancestor paths of the pseudo-folders, acquire a &lt;em&gt;read&lt;/em&gt; lock &#92;(&#92;overline{R}(p)&#92;) on each.&lt;/p&gt;&lt;p&gt;In order to access pseudo-folders at paths &#92;(P&#92;), we acquire the locks&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{W}(p)&#92;) for all &#92;(p&#92;) in &#92;(P&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{R}(p)&#92;) for all &#92;(p&#92;) that are ancestors of the paths in &#92;(P&#92;), except any in &#92;(P&#92;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To avoid deadlock, the locks are acquired ancestor-first, and then in lexographical order on path-component name; and each task attempts to acquire at most one lock at a time [&lt;a href=https://charemza.name/blog/posts/python/asyncio/s3-path-locking/#deadlock-free-proof&gt;proof&lt;/a&gt;]. For example, if a task needed to to access &#92;(/a/b&#92;) and &#92;(/a/b&#39;&#92;) it would&lt;/p&gt;&lt;ol&gt;&lt;li&gt;acquire a read lock on &#92;(/&#92;),&lt;/li&gt;&lt;li&gt;acquire a read lock on &#92;(/a&#92;),&lt;/li&gt;&lt;li&gt;acquire a write lock on &#92;(/a/b&#92;).&lt;/li&gt;&lt;li&gt;acquire a write lock on &#92;(/a/b&#39;&#92;).&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If a concurrent task wanted to lock anything in &#92;(&#92;mathbb{L}(/a/b)&#92;), it would get blocked. For example, if another task tried to access an &lt;em&gt;ancestor&lt;/em&gt; or &#92;(/a/b&#92;), such as, &#92;(/a&#92;), it would try to acquire the write lock on &#92;(/a&#92;), and get blocked by the original task&#39;s read lock on &#92;(/a&#92;). Alternatively, if a task tried to access a &lt;em&gt;descendant&lt;/em&gt; of &#92;(/a/b&#92;), such as &#92;(/a/b/c&#92;), it would get blocked by the write lock on &#92;(/a/b&#92;).&lt;/p&gt;&lt;p&gt;A downside of this is that there is no difference between reads and writes, which means that concurrent reads to the same lineage are forbidden, as can be seen in the below compatibility table.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;However, keeping in mind the single-object GET exception, this may be acceptable.&lt;/p&gt;&lt;p&gt;Note also that if a path isn&#39;t locked, then the lock object itself doesn&#39;t need to be retained in memory. As in the implementation below, using a weak-reference cache can be used for these.&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/786aa4f1ef93d957a5c8b7280612d7ea.js&gt;&lt;/script&gt;&lt;h3&gt;Ancestor locking and Read/write/ancestor locks on each path: 4/4&lt;/h3&gt;&lt;p&gt;We can improve on the above by maintaining a different sort of lock on each path. Instead of a read/write lock with two modes, &#92;(&#92;overline{R}&#92;) and &#92;(&#92;overline{W}&#92;), we construct one with 4: &#92;(&#92;overline{R}&#92;), &#92;(&#92;overline{W}&#92;), &#92;(&#92;overline{R_A}&#92;), &lt;em&gt;read-ancestor&lt;/em&gt;, and &#92;(&#92;overline{W_A}&#92;), &lt;em&gt;write-ancestor&lt;/em&gt;.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{R_A}(p)&#92;)&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{R}(p)&#92;)&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{W_A}(p)&#92;)&lt;/th&gt;&lt;th&gt;&#92;(&#92;overline{W}(p)&#92;)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{R_A}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large green background-grey&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large green background-grey&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{R}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{W_A}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red background-grey&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&#92;(&#92;overline{W}(p)&#92;)&lt;/th&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;In order to read the pseudo-folders at paths &#92;(P_R&#92;) and write the pseudo-folders at paths &#92;(P_W&#92;), we acquire the locks&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{W}(p)&#92;) for all &#92;(p&#92;) in &#92;(P_W&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{W_A}(p)&#92;) for all &#92;(p&#92;) that are ancestors of the paths in &#92;(P_W&#92;), except any in &#92;(P_W&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{R}(p)&#92;) for all &#92;(p&#92;) in &#92;(P_R&#92;), except any in in &#92;(P_W&#92;) and any ancestors of &#92;(P_W&#92;)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &#92;(&#92;overline{R_A}(p)&#92;) for all &#92;(p&#92;) that are ancestors of the paths in &#92;(P_R&#92;), except any in &#92;(P_W&#92;), and any ancestors of &#92;(P_W&#92;), and any in &#92;(P_R&#92;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To avoid deadlock, these lock are acquired ancestor-first, and then in lexographical order on path-component name; rand each task attempts to acquire at most one lock at a time [&lt;a href=https://charemza.name/blog/posts/python/asyncio/s3-path-locking/#deadlock-free-proof&gt;proof&lt;/a&gt;].&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/7c2e0333e0dd394265ded351e958d062.js&gt;&lt;/script&gt;&lt;p&gt;Using this set of locks, we then can acheive a perfect concurrency score of 4/4, and acheive the following concurrency table.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(W(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}(p))&#92;)&lt;/td&gt;&lt;td&gt;&#92;(R(&#92;mathbb{L}^c(p))&#92;)&lt;/td&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;As per the version that uses read/write locks, if a path isn&#39;t locked, then the lock object itself doesn&#39;t need to be retained in memory: a weak-reference cache can be used.&lt;/p&gt;&lt;h3 id=deadlock-free-proof&gt;Proof that ancestor-locking is deadlock-free&lt;/h3&gt;&lt;p&gt;The locks are always acquired along a sequence: ancestor first and then lexographic, and therefore the locks form a &lt;em&gt;total order&lt;/em&gt;. So we prove that for any algorithm where each task acquires its locks in a strictly increasing sequence along a total order, waiting for at most one lock at a time, that deadlock is impossible. The proof doesn&#39;t depend on properties of the modes of the lock, and so can be applied to both of the ancestor locking methods presented in this post.&lt;/p&gt;&lt;h4&gt;Conditions&lt;/h4&gt;&lt;p&gt;Let &#92;(L=&#92;{L_i&#92;}_{i &#92;in S} &#92;) for some &#92;(S &#92;subset &#92;mathbb{Z} &#92;) be a set of independent locks, each with at least one mode, and let &#92;(&amp;lt;_L&#92;) be a strict total order relation between elements of &#92;(L&#92;). Let &#92;(T = &#92;{T_i&#92;}_0^{M-1}&#92;) for some &#92;(M &#92;in &#92;mathbb{N} &#92;) be a set of tasks, where each acquires locks in &#92;(L&#92;) in a strictly increasing order according to &#92;(&amp;lt;_L&#92;), and at any given moment is waiting to acquire at most one lock.&lt;/p&gt;&lt;h4&gt;Statement&lt;/h4&gt;&lt;p&gt;It is not possible for &#92;(T&#92;) to be in deadlock.&lt;/p&gt;&lt;h4&gt;Proof&lt;/h4&gt;&lt;p&gt;Assume &#92;(T&#92;) are in deadlock. We&#39;ll show that this leads to a contradiction.&lt;/p&gt;&lt;p&gt;Without loss of generality, we index the &#92;( &#92;{L_i&#92;}_{i &#92;in S} &#92;) such that they form strictly increasing sequence according to &#92;(&amp;lt;_L&#92;)&lt;/p&gt;&#92;[ L_0 &amp;lt;_L L_1 &amp;lt;_L &#92;ldots .&#92;]&lt;p&gt;By &lt;a href=https://en.wikipedia.org/wiki/Deadlock#Necessary_conditions&gt;definition of deadlock&lt;/a&gt;, &#92;(M &#92;geq 2&#92;), each &#92;(T_i&#92;) has acquired at least one a lock, and each is waiting for a lock held by another task in &#92;( T &#92;). For each &#92;(T_i&#92;), let &#92;( A_i &#92;) be the indexes of the locks that &#92;(T_i&#92;) has acquired, and let &#92;(w_i&#92;) be the index that it waits for. Since all tasks acquire their locks in increasing order,&lt;/p&gt;&#92;[ L_a &amp;lt;_L L_{w_i}, &#92;forall a &#92;in A_i &#92;]&lt;p&gt;or equivalently&lt;/p&gt;&#92;[ a &amp;lt; w_i, &#92;forall a &#92;in A_i &#92;tag{1}&#92;label{eq:a} .&#92;]&lt;p&gt;Without loss of generality, we index the tasks such that each &#92;( T_i &#92;) is waiting for a lock held by &#92;( T_{i+1 &#92;pmod{M} } &#92;). So each &#92;(w_i &#92;in A_{i+1 &#92;pmod{M}}&#92;), and so by &#92;eqref{eq:a} &#92;(w_i &amp;lt; w_{i + 1 &#92;pmod{M}} &#92;). This is true for all &#92;( i &#92;in {0 &#92;ldots M-1} &#92;), and so&lt;/p&gt;&#92;[ w_0 &amp;lt; w_{1 &#92;pmod{M}} &amp;lt; &#92;ldots &amp;lt; w_{M-1&#92;pmod{M}} &amp;lt; w_{M &#92;pmod{M}} &#92;]&lt;p&gt;and therefore&lt;/p&gt;&#92;[ w_0 &amp;lt; w_{M &#92;pmod{M}} .&#92;]&lt;p&gt;However, &#92;(M &#92;pmod{M} = 0&#92;), which implies &#92;[ w_0 &amp;lt; w_0 .&#92;]&lt;/p&gt;&lt;p&gt;This is a contradiction. &#92;(&#92;square&#92;)&lt;/p&gt;&lt;hr&gt;&lt;ul&gt;&lt;li id=ref-1&gt;[1] Ritik Malhotra; An Efficient Locking Scheme for Path-based File Systems; &lt;a class=long href=https://people.eecs.berkeley.edu/~kubitron/courses/cs262a-F14/projects/reports/project6_report.pdf&gt;https://people.eecs.berkeley.edu/~kubitron/courses/cs262a-F14/projects/reports/project6_report.pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Python asyncio read/write lock</title>
    <link href="https://charemza.name/blog/posts/python/asyncio/read-write-lock/" />
    <updated>2018-11-11T14:50:00Z</updated>
    <id>https://charemza.name/blog/posts/python/asyncio/read-write-lock/</id>
    <content type="html">&lt;p&gt;In this post, I present an &lt;a href=https://charemza.name/blog/posts/python/asyncio/read-write-lock/#implementation&gt;implementation of an asyncio read/write lock&lt;/a&gt; [also known as a shared/exclusive lock].&lt;/p&gt;&lt;blockquote&gt;&lt;p style=&quot;text-align: center&quot;&gt;Since this post was written, the lower-level class, &lt;a href=https://github.com/michalc/fifolock&gt;FifoLock, has been released separately&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;What is a lock?&lt;/h3&gt;&lt;p&gt;When you have concurrent tasks, there may be parts of the code that have to be protected from being run by multiple tasks concurrently. A typical example is non-atomic reading from a file, concurrent with non-atomic writing to that same file. If a reading task reads the file half-way through a writing task, the reader may get a corrupt file: seeing some of the file before the write, and some of the file after.&lt;/p&gt;&lt;p&gt;A way to prevent this is to use what&#39;s called a &lt;em&gt;lock&lt;/em&gt;. Just before such code that needs to be protected, each task attempts to &lt;em&gt;acquire&lt;/em&gt; the lock, and just after the code, it &lt;em&gt;releases&lt;/em&gt; the lock so other task can acquire it. If a task cannot acquire the lock, it will wait until it can. [There are other possibilities if a task can&#39;t acquire the lock, but for simplicity, we just assume it waits.]&lt;/p&gt;&lt;h3&gt;Exclusive lock&lt;/h3&gt;&lt;p&gt;There are different sorts of lock, but a typical example is an &lt;em&gt;exclusive&lt;/em&gt; lock. Only one task can acquire this lock, all others must wait. Using an exclusive lock is a way to prevent corruption when multiple tasks are reading from/writing to a file.&lt;/p&gt;&lt;p&gt;Python&#39;s standard library comes with an &lt;a href=https://docs.python.org/3/library/asyncio-sync.html#asyncio.Lock&gt;exclusive lock&lt;/a&gt;. This can be used, for example:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; asyncio
lock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; asyncio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;locked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
       &lt;span class=&quot;token comment&quot;&gt;# only one task can be here at any given time&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that a lock in this context isn&#39;t really analogous to a lock on a door. An exclusive lock is better compared to a talking stick or a talking spoon, in that only the person who has acquired the talking stick can talk, others must wait until they acquire it. For other sorts of locks, it&#39;s a bit more complex and the analogy can break down.&lt;/p&gt;&lt;h3&gt;Read/write lock&lt;/h3&gt;&lt;p&gt;Using an exclusive lock is often enough to prevent corruption, but it may block tasks that would otherwise be safe to proceed. For example, concurrent readers on a file is often safe, and only if there is a writer should other tasks be blocked. To allow this, we use a different sort of lock: a &lt;em&gt;read/write&lt;/em&gt; lock.&lt;/p&gt;&lt;p&gt;A read/write lock is made of of two parts: a &lt;em&gt;read lock&lt;/em&gt; and a &lt;em&gt;write lock&lt;/em&gt;. The read lock can be acquired by multiple tasks concurrently, but only as long as no task holds the write lock; and a write lock can only be acquired if no tasks hold the read lock &lt;em&gt;and&lt;/em&gt; no task holds the write lock.&lt;/p&gt;&lt;p&gt;This can be summarised in the following table, showing what parts of the lock can be held concurrently by two tasks, A and B.&lt;/p&gt;&lt;table class=table&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;div class=top-right&gt;B&lt;/div&gt;&lt;div class=bottom-left&gt;A&lt;/div&gt;&lt;/th&gt;&lt;th&gt;Read&lt;/th&gt;&lt;th&gt;Write&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Read&lt;/th&gt;&lt;td class=&quot;large green&quot;&gt;✓&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Write&lt;/th&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;td class=&quot;large red&quot;&gt;✗&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Note that this table isn&#39;t quite enough to completely define how the lock behaves. When there are multiple tasks waiting to acquire the lock, some algorithm must be implemented to decide which tasks can be acquired. The implementation presented here allows tasks to proceed in a first-come-first-served order: a queue of tasks waiting to acquire the locks is maintained.&lt;/p&gt;&lt;p&gt;Note also that this type of lock isn&#39;t limited to reading or writing, hence this sort of lock is often called a shared/exclusive lock. However, it is so often used in the context of reading and writing, it is convenient and typical to call this a read/write lock [or similar].&lt;/p&gt;&lt;h3&gt;Read/write lock: usage&lt;/h3&gt;&lt;p&gt;The usage is very similar to the built-in exclusive lock, except that the lock object is callable with a required argument, an object representing which of the &lt;code class=inline&gt;Read&lt;/code&gt; and &lt;code class=inline&gt;Write&lt;/code&gt; lock modes is desired.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; asyncio_read_write_lock &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; FifoLock&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Read&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Write

lock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; FifoLock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Read&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
       &lt;span class=&quot;token comment&quot;&gt;# multiple tasks can be here, but only if there are no writers&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Write&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
       &lt;span class=&quot;token comment&quot;&gt;# only one task can be here at any given time, and only if no readers&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The lock class &lt;code class=inline&gt;FifoLock&lt;/code&gt; is general, and can support more complex locks than read/write, although here we just use it as a read/write lock.&lt;/p&gt;&lt;h3 id=implementation&gt;Read/write lock: comparison with aiorwlock.&lt;/h3&gt;&lt;p&gt;There is already a read/write lock available for asyncio at &lt;a href=https://github.com/aio-libs/aiorwlock&gt;aiorwlock&lt;/a&gt;. There are differences, which may be important for your use-case.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; This implementation has no support for Python versions less than 3.7, while aiorwlock appears to support earlier versions. This lack of support is a feature: it allows for simpler code.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Python 3.7&#39;s &lt;a href=https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager&gt;contextlib.asynccontextmanager&lt;/a&gt; is used internally. It allows for very concise creation of an asyncio context manager, without sacrificing flexibility or ability to handle errors.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; This implementation has no support for acquiring a write lock already held by the current task: attempting to do so would result in a deadlock. My use cases do not require this, and my instinct is to try to write client code so that this is not required. This would make the code of the lock more complex, and I suspect in a lot of cases using this would make client code more difficult to reason about.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; It appears that the algorithm aiorwlock uses to acquire a lock is &lt;a href=https://github.com/aio-libs/aiorwlock/blob/f47f427174e4b23abccba73126d7eaaf9a605f9b/aiorwlock/__init__.py#L117&gt;O(n) with respect to the number of tasks already holding a lock&lt;/a&gt;. This implementation is O(1) with respect to tasks holding a lock. Of course, this fact alone does not mean that this implementation is better or faster in practical terms.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Locks are acquired on a first-come-first-served basis, compared to aiorwlock giving preference to waiting writers: giving preference to waiting writers can starve the readers if the write lock is continually requested. Which of these is more appropriate depends on your use case, but my instinct is that unless you are sure there will will never be enough writers to starve the readers for any meaningful length of time, it&#39;s better to avoid such a bias.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=implementation&gt;Read/write lock: implementation&lt;/h3&gt;&lt;p&gt;The implementation is below.&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/ab9bd571cfab09216c0316f2302a76b0.js&gt;&lt;/script&gt;</content>
  </entry>
  <entry>
    <title>You might not need Boto 3</title>
    <link href="https://charemza.name/blog/posts/aws/python/you-might-not-need-boto-3/" />
    <updated>2018-10-28T11:15:00Z</updated>
    <id>https://charemza.name/blog/posts/aws/python/you-might-not-need-boto-3/</id>
    <content type="html">&lt;p&gt;It is not a requirement to &lt;a href=https://github.com/boto/boto3&gt;Boto 3&lt;/a&gt; in order to communicate with AWS from Python: you can make requests using any HTTP client, as long as you can work out the correct headers. Here&#39;s a function that does just that [with some &lt;a href=https://charemza.name/blog/posts/aws/python/you-might-not-need-boto-3/#design-descisions-and-limitations&gt;caveats&lt;/a&gt;].&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/ccb87856363a895fd1fadf52ab4cdcec.js&gt;&lt;/script&gt;&lt;p&gt;For example to PUT some data to S3 using aiohttp:&lt;/p&gt;&lt;script src=https://gist.github.com/michalc/1effe17a56f870a50148c764f242083b.js&gt;&lt;/script&gt;&lt;h3&gt;Why use this, and not Boto 3?&lt;/h3&gt;&lt;h4&gt;Your application is event-loop based&lt;/h4&gt;&lt;p&gt;This was my original reason for writing this: Boto 3 blocks the event loop. You can patch it or wrap it, and there are libraries that do this, but that&#39;s &lt;em&gt;even more&lt;/em&gt; code in your application, when you could have less.&lt;/p&gt;&lt;h4&gt;You can use the HTTP client you&#39;re already using in the rest of your project&lt;/h4&gt;&lt;p&gt;You may prefer that all your outgoing requests to go through the same function / library as the rest of the application. Say, for consistent logging, proxy configuration, or things like enforcing a global limit on outgoing connections.&lt;/p&gt;&lt;h4&gt;Free to boost performance: disk space, memory, and speed&lt;/h4&gt;&lt;p&gt;An install of Boto 3, with botocore, takes up at least an extra 35mb [and more depending on what other dependencies you already have]. If you&#39;re already using a HTTP library, then the function above adds 2.5kb [although yes, there could be more code at the call sites].&lt;/p&gt;&lt;p&gt;Or, you want to tease out as much performance as possible, in terms of speed or memory usage. You might not need to parse the entire JSON or XML from results if you don’t need to: you are free to be as performant (/hacky) as you like by using regex or just string matching against results; or you can use a faster JSON or XML parser; or you would like the option of doing these things in the future without lots of changes to your application or test code.&lt;/p&gt;&lt;h4&gt;You don’t want to wait for fixes or features to make it into Boto 3&lt;/h4&gt;&lt;p&gt;Boto 3 is not perfect [as no project is of course!], but also the developers don&#39;t have the same priorities as you. Having to wait for an upstream library update, where you have no influence over or knowledge of when the update will happen, is often not good place to be.&lt;/p&gt;&lt;p&gt;For example, AFAIK &lt;a href=https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html&gt;aws-chunked uploads to S3&lt;/a&gt; are &lt;a href=https://github.com/boto/botocore/pull/996&gt;not yet supported by Boto 3&lt;/a&gt;. [To be fair however, I suspect it&#39;s often of limited use, because you need to know the content length ahead of time, unlike standard HTTP chunked transfers.]&lt;/p&gt;&lt;p&gt;Another example is being able to change how/when the SHA-256 hash of the payload is calculated. The &lt;a href=https://docs.python.org/3/library/hashlib.html#hash-algorithms&gt;hash could be computed incrementally&lt;/a&gt;, and not all at once just before upload, and in a recent project I changed the signing function and surrounding code in order to be able to hash the payload as data comes into the application. AFAIK, this isn&#39;t possible with Boto 3.&lt;/p&gt;&lt;h4&gt;You want limit the bug surface area&lt;/h4&gt;&lt;p&gt;If something isn&#39;t working, is it your code, Boto 3, botocore, or AWS? You might want to limit the scope of investigations. For example, on a project I was involved with, repeatedly creating the Boto3 S3 client appeared to cause a memory leak.&lt;/p&gt;&lt;h4&gt;You want it to to be possible to understand what the application is doing&lt;/h4&gt;&lt;p&gt;You might have security requirements that code in your application must be reviewed. Doing this for every version of Boto 3 you need may not be a great option.&lt;/p&gt;&lt;h4&gt;You want the power to change the higher-level interface&lt;/h4&gt;&lt;p&gt;Boto 3 presents a higher-level interface to AWS that might not quite match up with the rest of your application. For example, how Boto 3 uses generators, exceptions, or even naming, may not be how the rest of your application is structured, and you may judge that consistency in your codebase to be valuable.&lt;/p&gt;&lt;h4&gt;You would like to directly apply the documentation from AWS&lt;/h4&gt;&lt;p&gt;The AWS documentation has a lot of examples: at least one on every action I&#39;ve looked it. I&#39;ve not seen this in Boto 3&#39;s documentation.&lt;/p&gt;&lt;h4&gt;You don&#39;t want another layer of abstraction&lt;/h4&gt;&lt;p&gt;Abstraction layers are often not free in terms of performace, ability to reason about behaviour, bugs introduced, or ability to change as your requirements change. [This is admittedly a succinct way of presenting several of the above points]&lt;/p&gt;&lt;h4&gt;You have a mocking/testing setup with other HTTP requests, and don’t want to include another one&lt;/h4&gt;&lt;p&gt;&lt;a href=https://github.com/spulec/moto&gt;Moto&lt;/a&gt; is great, but this is &lt;em&gt;yet another&lt;/em&gt; dependency, and obviously is only mocking Boto, and so only mocking calls to AWS. You may want to be completely free as to where you put the boundaries of your test, and a consistent approach when dealing with boundaries in tests is valuable. Also, using Moto also means you&#39;re &lt;em&gt;even more&lt;/em&gt; coupled to Boto 3.&lt;/p&gt;&lt;h4&gt;You use temporary security credentials, and want greater control over state&lt;/h4&gt;&lt;p&gt;They are typically cached for some period of time, and you might want to manage state, especially state relating to security, very particularly. Or you might not even want to cache the temporary security credentials at all. [Note: I&#39;m not sure if there will be some rate limiting issues here if you hit endpoints to retrieve the temporary credentials too frequently]&lt;/p&gt;&lt;h3&gt;Is this battle tested?&lt;/h3&gt;&lt;p&gt;No, but I have used it [or at least very similar code] in a few projects: communicating with S3, ECS, Elasticsearch, and IAM.&lt;/p&gt;&lt;h3&gt;Any gotchas?&lt;/h3&gt;&lt;p&gt;The AWS APIs are not completely consistent with each other. Some use JSON, some XML, some are more REST-ful than others, some have their actions specified in a query string, or some in a HTTP header. However, the documentation appears thorough for each API, and the APIs are quite good in terms of HTTP status codes, which means often you don&#39;t care about exactly what&#39;s returned. other than the status code.&lt;/p&gt;&lt;p&gt;The actual name of the service, passed in as the &lt;code class=inline&gt;service&lt;/code&gt; parameter to to &lt;code class=inline&gt;aws_sig_v4_headers&lt;/code&gt;, seems to require an educated guess. For the cases I&#39;ve tried it seems to match the hostname used in the &lt;a href=https://docs.aws.amazon.com/general/latest/gr/rande.html&gt;AWS API endpoints&lt;/a&gt;. For example, for a call to the Elasticsearch endpoint of &lt;code class=inline&gt;es.us-east-1.amazonaws.com&lt;/code&gt;, then the service would be &lt;code class=inline&gt;es&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;When &lt;em&gt;should&lt;/em&gt; I use Boto 3?&lt;/h3&gt;&lt;p&gt;If you decide that the part of it that you&#39;re using really does add value &lt;em&gt;on top&lt;/em&gt; of the AWS API, and that value is worth not having the upsides listed above.&lt;/p&gt;&lt;h3&gt;Should this be factored out to a shared library?&lt;/h3&gt;&lt;p&gt;Maybe. However, I have opted to not do this for my cases so far, to ensure each is a flexible as possible with only the complexity it needs. For example, this approach has allowed me change the code in a single project, which required incremental hashing of payload, without affecting others.&lt;/p&gt;&lt;h3 id=design-descisions-and-limitations&gt;Design decisions and limitations&lt;/h3&gt;&lt;p&gt;It&#39;s an API exposing a single function, but still had some thought. This was designed for my use cases: you may have others, and so may need a different function [or functions].&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Dictionaries of string -&gt; string are used for the headers and queries, This is concise, flexible in terms of manipulation I require in constructing API requests, all the HTTP libraries I&#39;ve worked with support this, and no extra dependencies are needed. However, this means that duplicate header and query keys are &lt;em&gt;not&lt;/em&gt; supported. However, I don&#39;t have a use case for duplicate header or query keys.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Payload must be passed in as b-string/bytes instance in all cases, including the empty b-string for GET requests without a body. There are no assumptions made on what HTTP methods can have payloads, and no automagical conversion, for flexibility.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The &lt;code class=inline&gt;x-amz-content-sha256&lt;/code&gt; header is only needed for S3 [from what I can tell], but doesn&#39;t seem to matter if you send it anyway to other APIs [also from what I can tell]. The hash of the payload is required to be calculated anyway, it&#39;s &lt;em&gt;sent&lt;/em&gt; anyway as part of the Authorization header, and for my cases, this bit of extra work and bytes sent is an acceptable trade off for having a simpler and consistent signing process for different AWS APIs. If the day ever comes where this trade off is not acceptable, I have the power to change this.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; There is no automagical conversion of region + service to host name [or vice-versa]. Instead, there is explicitness, flexibility, and less dynamic behaviour in order to make things easier to reason about.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The path is not normalised in terms of removing duplicate slashes. For requests to S3, this shouldn&#39;t be done anyway, and for other APIs I&#39;m happy to just put the requirement of constructing normalised strings up the call stack in my code: I was doing this anyway so this is no extra work.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Requests to non-S3 APIs that have characters that need URL-encoding in the path apparently won&#39;t work: they should be &lt;a href=https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html&gt;URL-encoded twice&lt;/a&gt;, and this function encodes them once. To use this function in such cases, you would need to encode the path before it being passed to this function, or use a different function. I&#39;ve not needed to handle this case, so the function above doesn&#39;t handle it.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; There are a lot of arguments to the function. I considered alternatives, such as wrapping some up in data structures, or putting the onus on the caller to put together parts of the signature, but this made things more, rather than less, complex. Hiding complexity often gives you nothing but more complexity.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Internally, there are some functions defined that are technically unnecessary since they are called once. I felt it was more important to show the flow of data, and what calculations depend on what previous calculations, in order to be able to tweak it if necessary. You can of course change it to not have these if you prefer.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; It uses Python 3.6&#39;s f-strings, and so does not support earlier versions of Python. I have no use case for earlier versions of Python.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The function is not pure: calls &lt;code class=inline&gt;datetime.datetime.utcnow()&lt;/code&gt;. You could easily separate it into a pure function that takes in the current time if you prefer. I didn&#39;t have a use case for this, so I didn&#39;t do it. For testing, I&#39;m happy with tests that use &lt;a href=https://github.com/spulec/freezegun&gt;FreezeGun&lt;/a&gt;. However, with that exception, all the expressions inside the function are referentially transparent. [I would refer to this as an application of &lt;a href=https://charemza.name/blog/posts/programming/pure/pragmatic-purity/ &gt;pragmatic purity&lt;/a&gt;].&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Questions to ask yourself when handling exceptions</title>
    <link href="https://charemza.name/blog/posts/patterns/error-handling/questions-to-ask-yourself-when-handling-exceptions/" />
    <updated>2018-07-23T23:00:00Z</updated>
    <id>https://charemza.name/blog/posts/patterns/error-handling/questions-to-ask-yourself-when-handling-exceptions/</id>
    <content type="html">&lt;h3&gt;Can I think of any combination of input where the exception can be thrown?&lt;/h3&gt;&lt;p&gt;If there is no combination of input that you can determine that can cause the exception, then if &lt;em&gt;somehow&lt;/em&gt; it does get thrown, your assumptions on how the program behaves have been violated. Consider letting the error bubbling up, and defering to a general error handler. In a web context, returning a 500 would be a typical example of how a general error handler would behave. Wonderfully, this is the default behaviour for many web frameworks.&lt;/p&gt;&lt;h3&gt;Is exiting safest?&lt;/h3&gt;&lt;p&gt;In some situations, you may even determine that exiting is safest. For example a web-based application may try to access configuration on load, and raise an exception if it can&#39;t, which if unhandled, would [by default in many languages] cause the program to exit. In a blue-green deployment pipeline, it&#39;s &lt;em&gt;desirable&lt;/em&gt; for the application to exit on load if misconfigured, since then the deployment will fail, and the existing deployment will remain live.&lt;/p&gt;&lt;h3&gt;Am I avoiding a 500?&lt;/h3&gt;&lt;p&gt;500s can be helpful. If it&#39;s best to abort because your assumptions have been violated, 500s often get to the front of the queue in front of getting addressed. You&#39;re also not wasting your client&#39;s time, since the problem is on the server, not with the client as the 4XXs suggest.&lt;/p&gt;&lt;h3&gt;Am I handling this exception this because I don’t known the range of inputs to this bit of code?&lt;/h3&gt;&lt;p&gt;Find out what the range is. If it&#39;s hard to work out, you have just made it even harder to understand what bit of code runs under what conditions. This isn’t a &quot;code for the future&quot; argument, it’s making sure you know what the code does right now, for today’s behaviour [although this would also help many futures].&lt;/p&gt;&lt;p&gt;In some cases, it may be appropriate to iteratively refactor surrounding code to make it easier to reason about.&lt;/p&gt;&lt;p&gt;[This is also an argument for type safety as well, since often it&#39;s easier to be sure on ranges of inputs. However, it&#39;s not possible or realistic in many situations.]&lt;/p&gt;&lt;h3&gt;To test the handler have I had to mock an implementation detail?&lt;/h3&gt;&lt;p&gt;It might not be possible for the exception to be thrown in production based on input. Consider not handling the exception where it can be thrown, and instead letting it bubble up to a general handler.&lt;/p&gt;&lt;h3&gt;Does testing the handler feel unnecessary?&lt;/h3&gt;&lt;p&gt;You may already suspect the handler itself is unecessary. Consider removing the handler, and letting the exception bubble up to a general handler.&lt;/p&gt;&lt;p&gt;[Listening to instincts can be risky, but one that pushes you to have &lt;em&gt;less&lt;/em&gt; or &lt;em&gt;simpler&lt;/em&gt; code, I think is worthwhile to examine]&lt;/p&gt;&lt;h3&gt;Am I subtly introducing features?&lt;/h3&gt;&lt;p&gt;If you&#39;re catching an exception and then marching forward with a default, you have just added a feature. Make sure this is what you want: there is often a long term cost of this. Is there really a need for this feature? How have you decided the default? Often the default is chosen as the original behaviour before the change: is the best option for the current range of behaviour of the code?&lt;/p&gt;&lt;p&gt;Defaults may be [currently] dead code, or they may be introduce complexity. If you &lt;em&gt;do&lt;/em&gt; want defaults, be careful of littering them throughout your code: this makes it hard to reason about their behaviour now, and hard to change later. Better is to have a specific &lt;em&gt;normalization&lt;/em&gt; phase, where the input is converted to some standard form. If you do have checks on the data after this phase, defer to a general error handler if the data is not as it should be. However, be mindful that if you can&#39;t cause these checks to fail through any combination of input, you may have effectively dead-code.&lt;/p&gt;&lt;h3&gt;Am I writing exception handlers for a general library that is used on one case?&lt;/h3&gt;&lt;p&gt;If yes, &lt;a href=https://xkcd.com/974/ &gt;you may be wasting time&lt;/a&gt;. It may be better to just handle the case you need to handle.&lt;/p&gt;&lt;h3&gt;Can the case the exception handler is designed to handle, be handled earlier?&lt;/h3&gt;&lt;p&gt;If the exception &lt;em&gt;can&lt;/em&gt; happen though some combination of input, it might be better to refactor the code so the error case can&#39;t happen in the bowels of your algorithm/processing, but instead happens earlier. This is already hinted at in other questions, but a rough order of preference of when it&#39;s good to deal with such things:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Compilation&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Tests&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Start of the run of the program&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Input validation&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Input normalization&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Input processing&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;I&#39;m handling low-level exceptions by raising higher level/custom exceptions. Am I sure hiding the real cause is helpful?&lt;/h3&gt;&lt;p&gt;It&#39;s often tempting to provide a &quot;pure&quot; level of abstraction by hiding everything the code is actually doing. However, consider what someone will need to do to investiagte this exception. If they would need to look into the lower-level cause, you have just made extra work for them unnecessarily.&lt;/p&gt;&lt;p&gt;As a guideline, if a layer of abstraction helps you reason about &lt;em&gt;today&#39;s&lt;/em&gt; behaviour, feel free to add it. If it doesn&#39;t, or if you can only see how it&#39;s helpful in some future version or use of the system, be &lt;em&gt;very&lt;/em&gt; cautious.&lt;/p&gt;&lt;h3&gt;Am I increasing the risk of security holes?&lt;/h3&gt;&lt;p&gt;One of the most important aspects of secure code is your understanding of what it&#39;s doing. If your assumptions on how it behaves are violated, this is evidence that the code is not as secure as you thought. Be &lt;em&gt;very&lt;/em&gt; sure how you would like to handle this.&lt;/p&gt;&lt;p&gt;Keep security in mind if you are deciding to add features, which you may be doing by handling exceptions. You are increasing complexity, which makes it harder to understand the code, and again, &lt;em&gt;less&lt;/em&gt; secure.&lt;/p&gt;&lt;h3&gt;Am I lowering the chance of a negative consequence, by increasing the chance of a worse consequence?&lt;/h3&gt;&lt;p&gt;Exceptions are often handled for &quot;safety&quot;, under the assumption that letting it bubble up is &quot;unsafe&quot;. It&#39;s often not so trivial as this: you have to reason about each case and determine what is safest in that situation. There is no perfect or always-applicable way of doing this, but the below list is in decreasing order of &quot;safety&quot; for many situations.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Not having a feature&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A feature is broken by aborting&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A feature is broken by appearing to work, but it does something unexpected&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Leaking data&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Be &lt;em&gt;very&lt;/em&gt; cautious that you&#39;re not needlessly increasing the risk of items further down this list. A data leak can have extremely long term consequences, and &quot;I didn&#39;t understand the code, but I was avoiding breaking a feature for one of our customers&quot; will &lt;em&gt;not&lt;/em&gt; fly at the subsequent public inquiry. I&#39;m not even kidding.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Structured data in environment variables</title>
    <link href="https://charemza.name/blog/posts/software-engineering/devops/structured-data-in-environment-variables/" />
    <updated>2018-07-07T12:30:00Z</updated>
    <id>https://charemza.name/blog/posts/software-engineering/devops/structured-data-in-environment-variables/</id>
    <content type="html">&lt;p&gt;I recently wrote a small Python application that had to be configurable so it can run differently in different environments. As is often done, I used environment variables for this.&lt;/p&gt;&lt;p&gt;However, for various reasons beyond the scope of this post, it was helpful to have &lt;em&gt;structured&lt;/em&gt; data stored in the environment: lists, dictionaries, and even lists of dictionaries. So when the application runs, it should be able to extract this and get something that looks like:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;FOO&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;BAR&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;setting-1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;BAZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;setting-2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;BAR&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;setting-3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;QUE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;setting-4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;FIZZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;setting-5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;setting-6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;BILL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;setting-7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This could be done by encoding such a structure into a single string, perhaps using JSON, throwing it into a single environment variable, and decoding it in the application. However, this would be fairly painful to edit and difficult to debug in many situations.&lt;/p&gt;&lt;p&gt;So I came up with a simple format where each setting is in its own variable, but its&lt;en&gt;name defines where it is in the structure. Specifically each name is&lt;/en&gt;&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; a double-underscore separated list of path components;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; and where each level of components defines a dictionary unless all of them parse as integers, in which case the level defines a list.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For example, the above config could be defined in bash by:&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;export FOO__1__BAR=setting-1
export FOO__1__BAZ=setting-2
export FOO__2__BAR=setting-3
export FOO__2__QUE=setting-4
export FIZZ__1=setting-5
export FIZZ__2=setting-6
export BILL=setting-7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and to convert this list of environment variables to nested Python dictionaries and lists, you can use &lt;a href=https://gist.github.com/michalc/59efee4bde412d137367d44049df8924&gt;normalise_environment.py&lt;/a&gt;:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; os
config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; normalise_environment&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;environ&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This way of incorporating structure into environment variables has some nice properties.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The double underscore is likely to not cause issues because underscores are used in environment variables frequently.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; No (extra) escaping needed. You can set them easily on the command line, any old bash script, Travis, CircleCI, CloudFoundry, ECS task defintions.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You can then &lt;em&gt;read&lt;/em&gt; them really easily, which is good for debugging.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If you don&#39;t currently use any double underscores in environment variable names, you can put your entire environment through &lt;a href=https://gist.github.com/michalc/59efee4bde412d137367d44049df8924&gt;normalise_environment.py&lt;/a&gt;, and it will be unchanged. This helps in moving existing config to a more structured form in small steps.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Although the function &lt;a href=https://gist.github.com/michalc/59efee4bde412d137367d44049df8924&gt;normalise_environment.py&lt;/a&gt; is helpful in Python, it&#39;s by no means necessary. Any code that can read environment variables can access their contents, without extra steps or dependencies involved.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;What to call this&lt;/h3&gt;&lt;p&gt;I&#39;m not sure how best to refer to this technique (it&#39;s almost so trivial calling it a &quot;technique&quot; is a bit much...). It&#39;s not quite &lt;em&gt;flattened&lt;/em&gt; since the structure is preserved. Storing the variables &lt;em&gt;denormalised&lt;/em&gt; is the best I have, since it can be argued that the location of each variable in the structure is denormalised.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Programming design choices in the face of changing requirements</title>
    <link href="https://charemza.name/blog/posts/software-engineering/agile/programming-design-choices-in-the-face-of-changing-requirements/" />
    <updated>2018-02-25T12:30:00Z</updated>
    <id>https://charemza.name/blog/posts/software-engineering/agile/programming-design-choices-in-the-face-of-changing-requirements/</id>
    <content type="html">&lt;p&gt;In an Agile environment, you are likely keeping in mind the following 3 &lt;a href=https://www.agilealliance.org/agile101/12-principles-behind-the-agile-manifesto/ &gt;Agile principles&lt;/a&gt; when working.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Working software is the primary measure of progress.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So if asked to make a feature, say Feature A, you split the work up into smaller, working, and deliverable pieces. Keeping also in mind the simplicity principle,&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Simplicity--the art of maximizing the amount of work not done--is essential.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;you decide to split the work so you do the simple but useful things first:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Feature A&lt;sub&gt;1&lt;/sub&gt;: some subset of the final feature set that is useful but simple and quick to code up&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Feature A&lt;sub&gt;2&lt;/sub&gt;: an extension of A&lt;sub&gt;1&lt;/sub&gt; delivering all the required behaviour and complexity&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;After you&#39;ve done Feature A&lt;sub&gt;1&lt;/sub&gt;, keeping in mind the Agile principle&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Business people and developers must work together daily throughout the project.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;you demonstrate the functionality so far. Then comes the feedback&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;This is great! We can really see how this solves our problems. Feature A&lt;sub&gt;1&lt;/sub&gt; acheives 90% of what we need. The last 10% from Feature A&lt;sub&gt;2&lt;/sub&gt; is quite low priority now, and we&#39;re even talking about never doing it. Instead, can we make a start on Feature B?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Fortunately, when coding up Feature A&lt;sub&gt;1&lt;/sub&gt;, you also kept in mind to&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Welcome changing requirements&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;so you didn&#39;t make a start on the complexity for Feature A&lt;sub&gt;2&lt;/sub&gt; because you suspected the requirements would change after Feature A&lt;sub&gt;1&lt;/sub&gt; was seen by the business people. You also kept in mind&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Continuous attention to technical excellence and good design enhances agility.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;so you didn&#39;t make Feature A&lt;sub&gt;1&lt;/sub&gt; in any way a hack: it is safe, tested, what it does and why it does it is extremely clear, and there isn&#39;t any unnecessary code. You have spent no time working on something that isn&#39;t useful, and you could not have given the developer of the next feature a better gift.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Type simplicity</title>
    <link href="https://charemza.name/blog/posts/software-engineering/type-safety/type-simplicity/" />
    <updated>2018-01-04T20:00:00Z</updated>
    <id>https://charemza.name/blog/posts/software-engineering/type-safety/type-simplicity/</id>
    <content type="html">&lt;p&gt;There is a &quot;feature&quot; of type-safe language: it is often an effort to use &lt;a href=https://en.wikipedia.org/wiki/Union_type&gt;union types&lt;/a&gt;. This has the consequence that the developer is given a little push to avoid such types, and consider alternatives.&lt;/p&gt;&lt;p&gt;In this post I argue that the simpler, non-union, types and corresponding code are often easier to reason about, and less likely to have bugs. Therefore, even in a in a type-unsafe environment, you should give &lt;em&gt;yourself&lt;/em&gt; this push for simpler types.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;What are union types?&lt;/h3&gt;&lt;p&gt;They are types that have two (or more) cases. For example, in Haskell, you have to be explicit, via a bit of effort, as to &quot;which&quot; type is used. A basic situation is using &lt;code class=inline&gt;Either&lt;/code&gt;, which allows a &lt;code class=inline&gt;Left&lt;/code&gt; type and a &lt;code class=inline&gt;Right&lt;/code&gt; type:&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;condition&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Right&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, &lt;code class=inline&gt;a&lt;/code&gt; would have the type &lt;code class=inline&gt;Either Int String&lt;/code&gt;. [This is slightly inaccurate due to typeclasses, but this isn&#39;t relevant here.]&lt;/p&gt;&lt;p&gt;When in an type-unsafe environment, variables don&#39;t have types, just the data they refer to does. However, it is often useful to mentally note down the all the types of variable&#39;s data and construct &quot;what the type of the variable would be&quot; if the environment had the concept of variables having types.&lt;/p&gt;&lt;p&gt;For example, in Python, you can write:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the type of &lt;code class=inline&gt;a&lt;/code&gt; would be &lt;code class=inline&gt;Union[int,string]&lt;/code&gt; (using Python&#39;s type annotation syntax). The similar Javascript code:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;would result in the type of &lt;code class=inline&gt;a&lt;/code&gt; being the union type &lt;code class=inline&gt;number | string&lt;/code&gt; (using Flow&#39;s type annotation syntax).&lt;/p&gt;&lt;p&gt;A more complex, but more realistic example, would be an object with differerent keys:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; obj &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;key_1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value_1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;key_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;key_2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value_3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Slightly shockingly, this is a union of 8 types:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;key_2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;key_2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;key_3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;key_3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;key_3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;key_3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;[You can write a similar type more concisely in Flow. The types are written out here to make clear all the different cases.]&lt;/p&gt;&lt;h3&gt;Special mention: Maybe/Optional/None/null&lt;/h3&gt;&lt;p&gt;These are a common union type that crops up in code. In Haskell again you have to be explicit adding a &lt;code class=inline&gt;Just&lt;/code&gt; to wrap a value:&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;condition&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However in Python you can just set the values as desired,&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the type would be &lt;code class=inline&gt;Union[int, None]&lt;/code&gt; or more concisely &lt;code class=inline&gt;Optional[int]&lt;/code&gt;. Similarly you write in Javascript:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the Flow type annotation would be &lt;code class=inline&gt;?number&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Special mention: optional arguments with default of None&lt;/h3&gt;&lt;p&gt;It is common to use optional arguments to function that have a default of None:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should be conscious of the fact that, unless &lt;code class=inline&gt;None&lt;/code&gt; is the &lt;em&gt;only&lt;/em&gt; value ever passed, the arguments will be of a union type.&lt;/p&gt;&lt;h3&gt;Special mention: variable only sometimes defined&lt;/h3&gt;&lt;p&gt;In imperitive languages, it&#39;s often possible to only sometimes define a variable. For example &lt;code class=inline&gt;the_filter&lt;/code&gt; is only sometimes defined below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  the_filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_function&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In Python, it would causes a runtime error if you try to access the variable when it&#39;s not defined. However, it&#39;s useful to keep in mind that there are 2 cases, so the type of the variable can be usefully classed as a union, of the defined and not defined cases.&lt;/p&gt;&lt;h3&gt;When and why should they be avoided?&lt;/h3&gt;&lt;p&gt;&quot;Avoided&quot; is perhaps too strong. However, since they result in a number of different cases the code has to deal with, choosing an alternative that reduces the amount of code that has to deal with multiple cases may result in code that is easier to reason about, and even improve effectiveness of tests and manual QA.&lt;/p&gt;&lt;h3&gt;Alternative: Single simple type&lt;/h3&gt;&lt;p&gt;Often, types are simple in an initial version of the code. They are then transformed into union types when adding a feature, where the original case should behave as before. Wonderfully, it is often possible to refactor the old case to be a special case of the new.&lt;/p&gt;&lt;p&gt;For example, if you&#39;re adding a feature where an existing list is filtered by a filter based on some conditions, you may have written:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;selected_filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  selected_filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_function_1
&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  selected_filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_function_2

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; selected_filter &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  data_filtered &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selected_filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  data_filtered &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The type of &lt;code class=inline&gt;selected_filter&lt;/code&gt; would be &lt;code class=inline&gt;Union[function, None]&lt;/code&gt;. You can rewrite this to always set a filter, using a constant function for the original case:&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;selected_filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &#92;
  filter_function_1 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_1 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &#92;
  filter_function_2 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_2 &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &#92;
  &lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;

data_filtered &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selected_filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this version, the type of &lt;code class=inline&gt;selected_filter&lt;/code&gt; would just be &lt;code class=inline&gt;function&lt;/code&gt;. There are fewer cases in the code, all things being equal, this makes the code easier to reason about.&lt;/p&gt;&lt;p&gt;Also, the difference in what code is run between cases is extremely small: every single case will call the &lt;code class=inline&gt;filter&lt;/code&gt; function. Therefore tests written &lt;em&gt;before&lt;/em&gt; the filtering feature was added would still call &lt;code class=inline&gt;filter&lt;/code&gt;. If the tests pass, this is evidence that the &lt;em&gt;new&lt;/em&gt; behaviour will work just as expected in all cases.&lt;/p&gt;&lt;p&gt;Further still, calling &lt;code class=inline&gt;filter&lt;/code&gt; creates a new list. If there is code mutating lists somewhere, it is crucial to make sure the correct list is being mutated. &lt;em&gt;Always&lt;/em&gt; creating a new list rather than &lt;em&gt;sometimes&lt;/em&gt; creating a new list helps to avoid subtle bugs relating to this. Tests can&#39;t cover every combination of cases, but we can maximise their value by making sure differences between the cases they do test is minimal.&lt;/p&gt;&lt;p&gt;[There are arguments against using the ternary operator, especially the Python ternary operator due to the order of arguments. However it does lend itself to making sure that variables are always defined, and I find the above layout for the nested case fairly easy to parse to understand the different cases and values.]&lt;/p&gt;&lt;h3&gt;Alternative: Multiple simple types with separate code paths&lt;/h3&gt;&lt;p&gt;In some cases the behavior of the cases of the types are quite different, but for historical reasons are munged together. When processing the type, there could be runtime checks for something already known up the call stack / by the client. An alternative would be to split the code at the earlier point, using different types, with two entirely different code paths for the different types.&lt;/p&gt;&lt;p&gt;For example, a &quot;Send email&quot; button may have been written first, and a &quot;Save draft&quot; feature added later. The &quot;Safe draft&quot; button POSTs similar, but not the same, data to the original endpoint on a server. This is often done in the name of DRY, and to avoid touching existing code as much as possible. However, sending email and saving draft are now tightly coupled together and hard to reason about, so making changes are likely to be slow or introduce bugs.&lt;/p&gt;&lt;p&gt;Better would be to have a separate endpoint for drafts. Two data types would be in-play, an &quot;email to send&quot; type, and &quot;email to save&quot; type, and the server wouldn&#39;t need to dynamically determine which: it&#39;s known by the which endpoint the data was POSTed to. The two cases are separate from the point of hitting the buttons: each endpoint would only contain code relevant to that case, without duplicated runtime tests for things already known. Therefore each should be easier to reason about and easier to make futher changes to. There may be some duplication on the server, but this can be minimised by factoring out common code from the two endpoint handlers if desired.&lt;/p&gt;&lt;h3&gt;Related questions to ask yourself when coding&lt;/h3&gt;&lt;h4&gt;What would the type of this variable be in a type-safe environment?&lt;/h4&gt;&lt;p&gt;A good first step in envisaging how code could be different is to run a small &quot;in-head&quot; analysis going through the different possibilities of data that a variable can refer to.&lt;/p&gt;&lt;h4&gt;How can I make the type of this variable simpler?&lt;/h4&gt;&lt;p&gt;The overall code may be easier to reason about and safer if you do.&lt;/p&gt;&lt;h4&gt;What would the code have looked like if I wrote the features in the another order?&lt;/h4&gt;&lt;p&gt;If the answer is that the code would have a &lt;em&gt;different&lt;/em&gt; structure, there is a reasonable chance that the code can have a &lt;em&gt;better&lt;/em&gt; code structure. Specifically, any union types used may not be necessary, and the code would be better if it was restructured with simpler types.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Questions to ask yourself when writing tests</title>
    <link href="https://charemza.name/blog/posts/methodologies/testing/questions-to-ask-yourself-when-writing-tests/" />
    <updated>2018-01-01T20:00:00Z</updated>
    <id>https://charemza.name/blog/posts/methodologies/testing/questions-to-ask-yourself-when-writing-tests/</id>
    <content type="html">&lt;h3&gt;Am I confident the feature I wrote today works because of the tests and not because I loaded up the application?&lt;/h3&gt;&lt;p&gt;If no, consider instead writing higher level tests that each test more of the code.&lt;/p&gt;&lt;h3&gt;I&#39;ve tested a number of cases manually. Are these cases covered by tests?&lt;/h3&gt;&lt;p&gt;If no, write tests covering these cases. This may be some combination of higher and lower level tests. Don&#39;t worry if some code is tested multiple times. Often, testing glue code is worth the cost of this re-testing.&lt;/p&gt;&lt;h3&gt;What would the tests have looked like if I wrote them before I wrote the code?&lt;/h3&gt;&lt;p&gt;It&#39;s not always possible to envisage what the tests should be before writing the code: some tasks require a bit of exploratory work. However, if you&#39;re writing tests after the fact, considering what you &lt;em&gt;could&lt;/em&gt; have written beforehand may help writing better tests, since it may push you towards testing behaviour rather than implementation details.&lt;/p&gt;&lt;h3&gt;If there were no tests in the codebase at all, which ones would I write now to test my changes?&lt;/h3&gt;&lt;p&gt;It&#39;s easy to be affected by what&#39;s in the codebase already, especially if it was written by you. Try to avoid this bias by imagining a clean slate, and what a &quot;perfect&quot; test would be. There may be contraints so you can&#39;t acheive this: often time or language constraints, but you might be able to do something better than what there is already.&lt;/p&gt;&lt;h3&gt;Are the boundaries of the code under test, themselves tested?&lt;/h3&gt;&lt;p&gt;Each boundary introduces an assumption, which introduces risk, since it might be false. Consider higher level tests that each test more of the code. This may mean the same code may be tested from different levels, but this is a reasonable, since it means the risk of incorrect assumptions is lower.&lt;/p&gt;&lt;h3&gt;Have I just made something public in order to test it?&lt;/h3&gt;&lt;p&gt;If yes, consider instead writing higher level tests that each test more of the code.&lt;/p&gt;&lt;h3&gt;Am I testing something trivial?&lt;/h3&gt;&lt;p&gt;If yes, consider instead writing higher level tests that each test more of the code.&lt;/p&gt;&lt;h3&gt;Have I just mocked something that is fast and deterministic?&lt;/h3&gt;&lt;p&gt;If yes, consider not mocking it. Mocking introduces assumptions, which introduce risk. Code may be tested multiple times at multiple levels, but having fewer assumptions is often worth this cost.&lt;/p&gt;&lt;h3&gt;For every part of my code change, if I break the code, will a test fail?&lt;/h3&gt;&lt;p&gt;100% code coverage is not enough for this, since that does not ensure components work together. To avoid a high number of low-level tests, consider instead writing fewer higher level tests.&lt;/p&gt;&lt;h3&gt;Am I avoiding testing something because it&#39;s hard to test?&lt;/h3&gt;&lt;p&gt;If it&#39;s hard to test automatically, it is likely be hard to reason about or test manually. Thefore the risk is higher, and it&#39;s actually &lt;em&gt;more&lt;/em&gt; important to test such things.&lt;/p&gt;&lt;h3&gt;Is the None/null case tested?&lt;/h3&gt;&lt;p&gt;Often it&#39;s better to design the production code so there is no None/null case. However, if there is one, it should be tested.&lt;/p&gt;&lt;h3&gt;Are boundaries of the problem domain tested?&lt;/h3&gt;&lt;p&gt;The most common of these are off-by-one errors, so often good to check each side of a numerical boundary. Yes, some code will be re-tested, but the increase of confidence is worth the cost.&lt;/p&gt;&lt;h3&gt;What is QA about to do? Can I add automated tests for that?&lt;/h3&gt;&lt;p&gt;If you&#39;re about to hand over to QA with a list of things to test, consider writing automated tests for them.&lt;/p&gt;&lt;h3&gt;Have I just copied and pasted the code of the function into the test?&lt;/h3&gt;&lt;p&gt;If yes, then the test doesn&#39;t have much value. Consider instead a higher level test that asserts on more code.&lt;/p&gt;&lt;h3&gt;What situations would cause the test to fail?&lt;/h3&gt;&lt;p&gt;If the only realistic answer is that the developer deliberately made a change to some code and the behaviour of the software continues to be correct, then the test is likely testing implementation details. Consider writing a higher level test, covering more code.&lt;/p&gt;&lt;h3&gt;If I refactor implementation details, would the tests pass?&lt;/h3&gt;&lt;p&gt;If no, consider instead writing higher level tests that each test more of the code.&lt;/p&gt;&lt;p&gt;Defining &quot;implementation detail&quot; is partially an art. However glue code that just passes data about, that doesn&#39;t actually do the data processing or output that a feature requires, can often be usefully classed as an implementation detail.&lt;/p&gt;&lt;h3&gt;Can I add likely features with the tests still passing?&lt;/h3&gt;&lt;p&gt;If no, the tests are likely to assert on too much. For example, &quot;snapshot&quot; tests that assert on the entire state of the DOM, or maybe an entire PDF.&lt;/p&gt;&lt;p&gt;Better are &quot;targeted high level tests&quot;. For example, instead of asserting on the entire state of the UI, just test certain parts of it, such as what is displayed in a drop down after a click on some element. [This is not an E2E test: remote services can still be mocked.]&lt;/p&gt;&lt;p&gt;Working out what a &quot;likely&quot; feature is partially an art, and benefits from experience and domain knowledge. This is a reason for developers to be quite close to client contact, be involved in design decisions or at least have as much contextual information as possible before starting to code. Often they are very business-logic related: adding or &quot;tweaking&quot; what data is allowed as input, stored, given as outputs, or associated UX changes to allow these. They are rarely low-level or infrastructure changes: changing database, data transfer formats, or code framework.&lt;/p&gt;&lt;h3&gt;What would a developer do if the test fails?&lt;/h3&gt;&lt;p&gt;If the answer is that the test is likely to be changed to pass with the current production code&#39;s behaviour, then the test doesn&#39;t add any value, and it either asserts on extremely trivial behaviour, or it asserts on too much, such as a snapshot of an entire DOM. Instead consider a &quot;targeted high level test&quot;.&lt;/p&gt;&lt;h3&gt;Are my tests helping me achieve my aims?&lt;/h3&gt;&lt;p&gt;If they don&#39;t, write different tests. Potentially, you might have to restructure the production code as well.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>The list monad&#39;s bind</title>
    <link href="https://charemza.name/blog/posts/haskell/monad/list-monad-bind/" />
    <updated>2017-06-10T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/haskell/monad/list-monad-bind/</id>
    <content type="html">&lt;p&gt;The word monad can be seen as scary, but you don&#39;t particularly need to worry about what it means in the general case in order to use the implementations of &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; (bind). For example, the list monad, where &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; is defined as below.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When evaluating &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, each element of &lt;code class=inline&gt;xs&lt;/code&gt; is passed to &lt;code class=inline&gt;k&lt;/code&gt;, which returns a list, and then the lists from each invocation of &lt;code class=inline&gt;k&lt;/code&gt; are concatanated back together for the final value. This means that &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; can be used as an alternative to &lt;code class=inline&gt;filter&lt;/code&gt;, &lt;code class=inline&gt;map&lt;/code&gt;, or be used for local transformations of the list, such as repeating each element.&lt;/p&gt;&lt;h3&gt;As a filter&lt;/h3&gt;&lt;p&gt;Often you would like to filter a list based on a predicate. This can be done with &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; as below.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;filtered&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;predicate&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is equivalent to the below use of &lt;code class=inline&gt;filter&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;filtered&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;predicate&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;list&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;As a map&lt;/h3&gt;&lt;p&gt;&lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; can also be used to map a function over the elements of a list, i.e. end up with a list of the same length, but each element has been passed through another function. An example of this is below.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;mapped&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;mapper&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is equivalent to just using &lt;code class=inline&gt;map&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;mapped&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;mapper&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;list&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;As a local transform&lt;/h3&gt;&lt;p&gt;The cases where &lt;code class=inline&gt;&gt;&amp;gt;&amp;gt;=&lt;/code&gt; shines are those that can&#39;t be achieved using a single higher-order function. For example, repeating each element twice in a list.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;repeated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Should I use &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;?&lt;/h3&gt;&lt;p&gt;My instinct is to use the least general code that solves the problem you&#39;re tackling, and solves it clearly. So while using &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; for when there isn&#39;t a single other function that can do the job is good, using it when &lt;code class=inline&gt;map&lt;/code&gt; or &lt;code class=inline&gt;filter&lt;/code&gt; would do, while interesting, I would probably avoid.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.&lt;/p&gt;&lt;cite&gt;Ian Malcom, Jurassic Park&lt;/cite&gt;&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <title>Hidden structure</title>
    <link href="https://charemza.name/blog/posts/haskell/functor/hidden-structure-in-haskell/" />
    <updated>2017-05-22T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/haskell/functor/hidden-structure-in-haskell/</id>
    <content type="html">&lt;p&gt;Trying to understand functors, I came accross the initially strange fact that functions are functors. Which means, roughly speaking, you can &quot;map&quot;, another function over it. So given a function&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and another function&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;you can &quot;map&quot; the second function over the first to get another function, which is defined as the composition of the two.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;g&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similarly, and more familiarly, you can take a list&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and a function&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and map the function over the list to get another list.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(I suspect this isn&#39;t how &lt;code class=inline&gt;fmap&lt;/code&gt; is defined on a list in the real source, but I find list comprehensions quite easy to understand.)&lt;/p&gt;&lt;p&gt;The suprising thing is that you can express two seemingly very different activities, mapping a function over a list, and composing a function with another function, in Haskell using the same function: &lt;code class=inline&gt;fmap&lt;/code&gt;. Here &quot;the same&quot; is defined as having the same type signature.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token builtin&quot;&gt;fmap&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Functor&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although yes, the implementation of &lt;code class=inline&gt;fmap&lt;/code&gt; for functions and lists are indeed different.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>The beauty and the horror of Haskell monads</title>
    <link href="https://charemza.name/blog/posts/haskell/monad/haskell-beauty-horror-monads/" />
    <updated>2017-05-06T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/haskell/monad/haskell-beauty-horror-monads/</id>
    <content type="html">&lt;p&gt;This post assumes some understanding of and familiarity with Haskell monads.&lt;/p&gt;&lt;h3&gt;The beauty&lt;/h3&gt;&lt;p&gt;There are a number of patterns that come up frequently in programming. Some of these are:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Combining IO actions, making the result of each available to later ones: &lt;em&gt;IO monad&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Building up, or reading from, a peusdo-mutable state or configuration: &lt;em&gt;Reader, Writer, and State monads&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Running a sequence of functions where the later are skipped if the previous doesn&#39;t return a meaningful result: &lt;em&gt;Maybe monad&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Running a function over all possible combined values of a number of lists: &lt;em&gt;List monad&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The beautiful thing is that problems that at face value are completely different actually share a common structure. They can be decomposed into their domain-specific components, and &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; (bind) and &lt;code class=inline&gt;return&lt;/code&gt;, where, although different for all of the above examples, adhere to certain laws. Once you are familiar with any given instance of &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and &lt;code class=inline&gt;return&lt;/code&gt;, then it&#39;s really quite amazing how much can be achieved, and communicated, with just a few lines of code.&lt;/p&gt;&lt;h3&gt;The horror&lt;/h3&gt;&lt;p&gt;The &quot;once you are familiar with any given instance of &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;&quot; hints at the horror. The &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and &lt;code class=inline&gt;return&lt;/code&gt; functions are (terribly?) overloaded. Each of the monads use the same notation, but they can all do radically different things. To know what any &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; actually does, you have to infer its type from the surrounding code, and look to its definition. Similarly a do-block&#39;s behaviour depends radially on the definition of &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;: and it might be even worse, because &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; isn&#39;t even present in the code.&lt;/p&gt;&lt;p&gt;Taking and modifying some examples from &lt;a href=http://dev.stephendiehl.com/hask/#readert&gt;What I Wish I Knew When Learning Haskell&lt;/a&gt;, we can see a use of the Maybe monad,&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;example&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;b&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and an example of the Reader monad.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token import-statement&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Control&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Monad&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Reader&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MyContext&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MyContext&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Int&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;deriving&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Show&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;putStrLn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runReader&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;computation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MyContext&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello&quot;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;token hvariable&quot;&gt;computation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Reader&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MyContext&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Maybe&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;computation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;asks&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;bar&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;asks&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;foo&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Nothing&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The monadic values &lt;code class=inline&gt;example&lt;/code&gt; and &lt;code class=inline&gt;compution&lt;/code&gt; definitions have similarities: do notation, &amp;lt;-, and return. However, these similarities are misleading. Take for example &lt;code class=inline&gt;return&lt;/code&gt; from the Maybe monad. Its definition is&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Just&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;while the Reader monad&#39;s definition is&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token builtin&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Reader&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similarly, because of the different implementations of &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, line breaks in the do-notations result in different code. Hence how monads are sometimes described as &lt;em&gt;programmable semicolons&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;There is a &lt;em&gt;lot&lt;/em&gt; of non-explicit behaviour going on. In code reviews, I often use the term &quot;magical&quot; if there is non-explicit behaviour, and I usually suggest it is to be avoided. Yes, &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and &lt;code class=inline&gt;return&lt;/code&gt; are likely to abide by the monad laws, and they certainly do in these examples, but I&#39;m unsure if this is enough to understand what&#39;s going on.&lt;/p&gt;&lt;p&gt;As a parallel, Mike Acton, in his talk on &lt;a href=&quot;https://www.youtube.com/watch?v=rX0ItVEVjHc&quot;&gt;data-oriented design&lt;/a&gt;, suggests only using C++ operator overloading that is &quot;super obvious&quot;, such as adding vectors. Uncle Bob also teaches us to be more explicit.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used.&lt;/p&gt;&lt;cite&gt;Robert C. Martin&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;There are reasonable arguments that monads in Haskell, by overloading &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt; and &lt;code class=inline&gt;return&lt;/code&gt;, break these guidlines. Of course, perhaps I will feel differently once I have been working with Haskell for longer. We will see!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Haskell do notation protects you from parentheses</title>
    <link href="https://charemza.name/blog/posts/haskell/monad/haskell-do-notation-parentheses/" />
    <updated>2017-04-21T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/haskell/monad/haskell-do-notation-parentheses/</id>
    <content type="html">&lt;p&gt;Starting in Haskell, I wanted to lean away from &lt;code class=inline&gt;do&lt;/code&gt; notation, to make sure I knew what was going on under the hood before taking syntactic shortcuts.&lt;/p&gt;&lt;p&gt;However, I have found a small stumping block in my quest for de-sugaring. Function application &lt;code class=inline&gt;$&lt;/code&gt; and nested &lt;code class=inline&gt;do&lt;/code&gt; notation results in quite clear imperative-style code. For example, E2E tests using &lt;a href=https://hackage.haskell.org/package/hspec-webdriver-1.2.0/docs/Test-Hspec-WebDriver.html&gt;Test.Hspec.Webdriver&lt;/a&gt;.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;hspec&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;E2E smoke test&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;

    &lt;span class=&quot;token hvariable&quot;&gt;sessionWith&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;integration&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;allBrowsers&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token hvariable&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;checks all text in p&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runWD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;openPage&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://web_test/test/files/index.html&quot;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;findElem&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ByCSS&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p&quot;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`shouldHaveText`&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Some HTML&quot;&lt;/span&gt;

      &lt;span class=&quot;token hvariable&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;checks all text in p strong&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runWD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;openPage&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://web_test/test/files/index.html&quot;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;findElem&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ByCSS&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p strong&quot;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`shouldHaveText`&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTML&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Desugaring isn&#39;t just a case of removing &lt;code class=inline&gt;do&lt;/code&gt; and changing the line breaks to &lt;code class=inline&gt;&amp;gt;&amp;gt;&lt;/code&gt; or &lt;code class=inline&gt;v &amp;lt;- expression&lt;/code&gt; to &lt;code class=inline&gt;expression &amp;gt;&amp;gt;= &#92;v -&amp;gt;&lt;/code&gt;. It turns out that&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; if there were nested do blocks, and multiple lines in the outer block, then you need parentheses around what was a line in the outer one;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; if there were usages of &lt;code class=inline&gt;$&lt;/code&gt;, then the expression to the right of &lt;code class=inline&gt;$&lt;/code&gt; will need to be wrapped in parentheses, and &lt;code class=inline&gt;$&lt;/code&gt; removed.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is due to the facts that&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the end of a &lt;code class=inline&gt;do&lt;/code&gt; block, and each newline in a &lt;code class=inline&gt;do&lt;/code&gt; block, essentially has a lower precendence than &lt;code class=inline&gt;$&lt;/code&gt;, which in turn has a lower precedence than &lt;code class=inline&gt;&amp;gt;&amp;gt;&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; explicit lambdas, which would come from desugaring &lt;code class=inline&gt;&amp;lt;-&lt;/code&gt;, take everything from &lt;code class=inline&gt;-&amp;gt;&lt;/code&gt; to the end of the expression as their body.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To explain: when in a &lt;code class=inline&gt;do&lt;/code&gt; block, the second argument of &lt;code class=inline&gt;$&lt;/code&gt; is from the &lt;code class=inline&gt;$&lt;/code&gt; to the end of the line. However, when not in a &lt;code class=inline&gt;do&lt;/code&gt; block, the second argument of &lt;code class=inline&gt;$&lt;/code&gt; goes beyond the end of the line, which is ignored, beyond any &lt;code class=inline&gt;&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code class=inline&gt;&amp;gt;&amp;gt;=&lt;/code&gt;, all the way to the end of the containing expression. Similar logic applies for the body of lambdas.&lt;/p&gt;&lt;p&gt;This means that the above E2E tests, but without &lt;code class=inline&gt;do&lt;/code&gt; notation, look like the following.&lt;/p&gt;&lt;pre class=language-haskell&gt;&lt;code class=language-haskell&gt;&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token hvariable&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;hspec&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;
  &lt;span class=&quot;token hvariable&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;E2E smoke test&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;

    &lt;span class=&quot;token hvariable&quot;&gt;sessionWith&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;integration&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;allBrowsers&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;checks all text in p&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runWD&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;openPage&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://web_test/test/files/index.html&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;findElem&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ByCSS&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`shouldHaveText`&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Some HTML&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;checks all text in p strong&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;token hvariable&quot;&gt;runWD&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;openPage&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://web_test/test/files/index.html&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;findElem&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ByCSS&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;p strong&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&#92;&lt;/span&gt;&lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token hvariable&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;`shouldHaveText`&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTML&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Not the end of the world of course, but certainly a point in the &lt;code class=inline&gt;do&lt;/code&gt;-notation column for clarity, and certainly conciseness.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Long files are not the enemy</title>
    <link href="https://charemza.name/blog/posts/programming/refactoring/long-files-are-not-the-enemy/" />
    <updated>2017-04-02T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/programming/refactoring/long-files-are-not-the-enemy/</id>
    <content type="html">&lt;p&gt;I have seen multiple developers leap to the conclusion that long files of source code are automatically bad, leading them to separate the code, virtually as-is, into separate files. This post suggests that this view is too simplistic, and other things should be considered before moving code about.&lt;/p&gt;&lt;h3&gt;So why do developers think long files are bad?&lt;/h3&gt;&lt;p&gt;My suspicion is that upon seeing a long file, there is often an assumption that it&#39;s a &lt;em&gt;moving part&lt;/em&gt;. Any working with it means you have to reason about it as a whole, this whole is too big to reason about, and therefore you should split it up to make it possible to reason about each of them separately. So firstly...&lt;/p&gt;&lt;h3&gt;A file is not necessarily a moving part&lt;/h3&gt;&lt;p&gt;I don&#39;t have a strict definition of what a code &lt;em&gt;moving part&lt;/em&gt; is, but roughly it&#39;s something that you have to reason about as a whole, and that interacts with other code or the outside world via some interface. Examples include&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; pure function,&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; group of functions that call each other or communicate via some state,&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; script that is run in response to a web request,&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; class, especially if its instances maintain an internal state,&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Angular directive or a React component.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can have one of these in a file, multiple in a file, or even one spread across multiple files.&lt;/p&gt;&lt;h3&gt;If there&#39;s a problem, you&#39;re just moving it about...&lt;/h3&gt;&lt;p&gt;Consider a 1000 line file that has 40 functions in it. These functions might not call each other, read or change state, and they don&#39;t have any side effects beyond those they advertise, such as touching a database. Each of these functions I would class as a moving part, and each of these function might have problems. In another file, these problems would be exactly the same.&lt;/p&gt;&lt;h3&gt;... and maybe making it even worse&lt;/h3&gt;&lt;p&gt;Consider if those 40 functions each change and read state, call each other in a complex web of booleans and optional arguments, none of them having a clearly separate purpose, and the behaviour of any part of the code is very brittle with respect to changes in other parts. This makes the 40 functions into a single moving part, and splitting these functions, as they are, into separate files actually spreads this moving part about. I suspect it is likely that this makes it harder, and not easier, to reason about.&lt;/p&gt;&lt;h3&gt;... and makes it harder to see its history&lt;/h3&gt;&lt;p&gt;Once you have moved code about, it makes finding the history of it just that little bit harder. If there &lt;em&gt;are&lt;/em&gt; problems with the code, the history of the lines may help work out why things are the way they are, and so guide you in the choices you make when making further changes. It&#39;s actually with the worst code that the version control history is the most valuable.&lt;/p&gt;&lt;h3&gt;So what &lt;em&gt;is&lt;/em&gt; the enemy?&lt;/h3&gt;&lt;p&gt;Smells/rot in the moving parts themselves. Maybe each moving part has too much responsibility, blurry responsibility, or acheives its goal(s) using too much state or crazy overcomplicated logic. Any one of the tens/hundreds of possible problems code might have that aren&#39;t that it happens to be near another moving part in the same file.&lt;/p&gt;&lt;h3&gt;What &lt;em&gt;should&lt;/em&gt; I do about it?&lt;/h3&gt;&lt;p&gt;Refactor as you would, but keep in mind that moving code as-is, especially bad code, has consquences that might not all be positive.&lt;/p&gt;&lt;h3&gt;Final semi-stolen quote&lt;/h3&gt;&lt;p&gt;To steal/adapt &lt;a href=https://blog.komand.com/microservices-please-dont&gt;Sean Kelly&lt;/a&gt;&#39;s point on microservices...&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;You don’t need to introduce another file as an excuse to write better code.&lt;/p&gt;&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <title>Avoid stateful variables</title>
    <link href="https://charemza.name/blog/posts/programming/pure/how-i-gently-prod-myself-to-write-purer-code/" />
    <updated>2017-02-12T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/programming/pure/how-i-gently-prod-myself-to-write-purer-code/</id>
    <content type="html">&lt;p&gt;Coming from an imperative programming background, or working in an imperative code base, it can be tricky to write purer code. However, there is one guideline I try to follow that gently prods me in the &quot;right&quot; direction.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Avoid stateful variables&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Following this guideline leads to a number of things that I think makes the code &quot;better&quot;.&lt;/p&gt;&lt;h3&gt;Stateful variables&lt;/h3&gt;&lt;p&gt;What I mean by stateful variable is a variable whose value changes once set. This include simple re-assignment,&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but it also includes calls that change the internal state of an object after it has been created.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MyClass&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;setFoo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;bar&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both of these mean there is a state that changes over time in the code. It might be short-lived, just in a single function, but it can still make the code harder to reason about. There is no, easily determined, single expression that can replace a stateful variable wherever it is used. You have to think about the entire history of the variable, and what caused it to change. Using a more technical term, stateful variables cannot be used in a referentially transparent way.&lt;/p&gt;&lt;p&gt;Once I have identified a stateful variable in code I am about to write or change, I consider alternatives.&lt;/p&gt;&lt;h3&gt;Alternative 1: Declare more stateless variables&lt;/h3&gt;&lt;p&gt;A way to avoid state&lt;em&gt;ful&lt;/em&gt; variables is to declare more state&lt;em&gt;less&lt;/em&gt; variables. These are variables that don&#39;t change once set. For example,&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;could become as below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This might be a bit more complex if you have branching involved.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This above could become as below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or, if you can change &lt;code class=inline&gt;g&lt;/code&gt;, it might make sense for it to handle a boolean,&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or even for it to call a function that returns a boolean.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Alternative 2: Declare fewer variables by inlining&lt;/h3&gt;&lt;p&gt;A simple technique is just to not use as many variables. The code&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;could just be as below.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A more horrible example is if you have a stateful variable that depends on another stateful variable.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;condition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; condition_1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  condition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; condition_3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This abomination is equivalent to the below, assuming all functions have no side-effects.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; condition_3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Yes, there is a little bit of duplication. but I wouldn&#39;t fear this, especially for such a tiny amount of duplication. It&#39;s case-dependent, but it may well be worth seeing exactly the cases certain code is run, and this might mean a little bit of duplication.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;duplication is far cheaper than the wrong abstraction&lt;/p&gt;&lt;cite&gt;Sandi Metz&lt;/cite&gt;&lt;/blockquote&gt;&lt;h3&gt;Alternative 3: Create objects as needed rather than changing them&lt;/h3&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MyClass&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;setFoo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mary&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MyClass&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;foo&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;mary&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; test&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code might not be strictly equivalent, but I would put in the effort to make sure MyClass works with &lt;code class=inline&gt;foo&lt;/code&gt; being &lt;code class=inline&gt;None&lt;/code&gt;.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;As a sidebar, the &lt;code class=inline&gt;None&lt;/code&gt; case above makes &lt;code class=inline&gt;foo&lt;/code&gt; look look it might be an optional argument, which isn&#39;t great, for the reasons outlined in the post about &lt;a href=https://charemza.name/blog/posts/programming/smells/say-no-to-more-optional-arguments/ &gt;optional arguments&lt;/a&gt;. Ideally, you would be able to factor out the code from &lt;code class=inline&gt;MyClass&lt;/code&gt; so that it doesn&#39;t need to treat &lt;code class=inline&gt;None&lt;/code&gt; as a special ase.&lt;/p&gt;&lt;h3&gt;Alternative 4: Use higher order functions&lt;/h3&gt;&lt;p&gt;In some cases you have a &quot;pipeline&quot; where a value is repeatedly modified for various reasons. For example a list of filters that are each applied conditionally.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_1&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_3&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_4&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filter_4&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

filtered &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case, you can construct a structure of functions, and run them using a reduce.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;conditional_filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition_filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; condition_filter&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;filter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; condition_filter&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; value

condition_filters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; condition_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;filter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; filter_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; condition_2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;filter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; filter_2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; condition_3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;filter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; filter_3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;condition&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; condition_4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;filter&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; filter_4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

filtered &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;conditional_filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; condition_filters&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Going overboard&lt;/h3&gt;&lt;p&gt;I don&#39;t follow the above alternatives in all cases. There are times when making stateless code would be less clear, would be too much of a project, or would make the code too rigid.&lt;/p&gt;&lt;p&gt;For example, in the case of Alternative 4 above, there are reasons why this final pure code is &lt;em&gt;not&lt;/em&gt; better than the original. It&#39;s remove some state, and added the ability that it&#39;s really easy to make the list of conditions and filters dynamic, but at the cost of making it harder to do something different/hacky in the middle of the filtering process. Say, save a file or make an API request. This would of course make the code slightly horrible, but in a real-world situation with time constraints and other priorities, this might be the best option.&lt;/p&gt;&lt;p&gt;Also, you should consider who else will be working on this code, and their familiarity with working with higher order functions like reduce. Of course, this &lt;em&gt;should&lt;/em&gt; be covered in programming 101, but for me at least, it really wasn&#39;t.&lt;/p&gt;&lt;p&gt;In cases where a stateful variable is to be used, I usually try to make sure its lifetime is as limited as possible, make it so it is modified in consitent ways, and it is modified for consistent reasons.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;As everything, it&#39;s a trade-off.&lt;/p&gt;&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <title>Non atomic deployments</title>
    <link href="https://charemza.name/blog/posts/devops/aws/non-atomic-deployments/" />
    <updated>2017-02-06T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/devops/aws/non-atomic-deployments/</id>
    <content type="html">&lt;p&gt;When designing a deployment strategy for your web application or site, keep in mind that browsers do not request a site atomically. They ask for the HTML, and then, some time later, ask for the resources such as scripts and stylesheets. If a deployment is fully atomic, as in only one version of a site is accessible at any given time, this time period can introduce a race condition:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A build/deployment is started.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A browser requests a HTML page, and the server supplies it.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A deployment is completed. Old versions of static resources such as stylesheets and scripts are no longer accessible.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The browser requests the static resources from the original HTML. The browser either gets 404s or scripts or stylesheets that don&#39;t match the CSS, resulting in broken site.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are a number of ways of avoiding this.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Inlining everything in the HTML. Not a crazy idea for extremely small sites, but once you get fairly heavyweight scripts or images, this makes time to view the page quite high.&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Use versioned or hashed file names for resources, and don&#39;t make versions from previous deployments inaccessible until some time after the deployment.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The second way is the method used for this site, with file names with the hash of the file contents in to avoid having to store version numbers anywhere. This was originally setup for cache busting, but it has this wonderful benefit of supporting multiple versions of assets at the same time.&lt;/p&gt;&lt;h3&gt;Cleaning up&lt;/h3&gt;&lt;p&gt;A problem is eventually cleaning up the old versions of files. However, because online storage is so cheap, it can often be a viable option to just never clean up the obsolete resources. If you&#39;re spending an extra £O.O1 per month, my suspicion is that as long as the files don&#39;t contain anything sensitive or have a restrictive license, it&#39;s just not worth the time to setup, and maintain, anything to do it. An argument against this however, is that lots of dead files can make it harder to debug issues.&lt;/p&gt;&lt;p&gt;Also up until recently, I didn&#39;t know/couldn&#39;t think of a way to delay deletion of such files without too much infrastructure, such as a server running cron, Jenkins, or scheduled Lambda function. This would have to be tied to the build system so it knows what to delete. This can all get a bit complex, especially when there must be some mechanism to abort the delete in case you go back to a previous version with the same hashed filename. All a bit much to setup / maintain / monitor just to delete a few files.&lt;/p&gt;&lt;p&gt;However, if you serve static assets from an S3 bucket, there are two features that make this really easy that require very little additional infrastructure.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Object tagging. You can individually tag each object with a user-defined tag.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Lifecycle management. You can setup rules that delete all object that have a tag, some specified time after they were last modified.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Using these, you can do the following.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Setup a lifecycle configuration rule that deletes objects in the bucket that have a certain tag, a certain amount of time after they were last modified.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Before each the deployment, fetch a list of all current objects in the bucket.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; When deploying the static resources, make sure each has a versioned / hashed file name, and make sure to clear any tag that would have resulted in its deletion.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; For all existing resources that weren&#39;t overridden and that didn&#39;t already have the tag, copy the resources to themselves, adding the tag. The copy, while a bit hacky, is the only way I can see of updating the last modified time. This avoids objects being deleted sooner than the minimum time after they become unreferenced that you feel is appropriate.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Following the above strategy means that once a resource is obsolete, it will remain in the bucket until some time after the deployment, when S3 will automatically delete it. If you update the site again, and the same resource becomes un-obsolete and re-published, removal of the tag means S3 won&#39;t delete it.&lt;/p&gt;&lt;p&gt;That&#39;s it! A low-infrastructure mechanism of cleaning up after non atomic deployments.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The best infrastructure is the one that doesn&#39;t exist&lt;/p&gt;&lt;cite&gt;Jeff Nunn&lt;/cite&gt;&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <title>Overriding methods is spaghetti in disguise</title>
    <link href="https://charemza.name/blog/posts/oop/patterns/overriding-methods-is-branching-in-diguise/" />
    <updated>2017-01-09T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/oop/patterns/overriding-methods-is-branching-in-diguise/</id>
    <content type="html">&lt;p&gt;A common pattern I have seen is having some default behaviour in a base class, that is sometimes overwritten in subclasses, and sometimes not.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;red&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;green&quot;&lt;/span&gt;

a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassA&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;red&quot;&lt;/span&gt;

b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassB&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;green&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The usual reason for this is that the Base case was written first, and then new behaviour was needed that didn&#39;t quite match up with the original.&lt;/p&gt;&lt;h3&gt;Why not do this?&lt;/h3&gt;&lt;p&gt;The simple case above isn&#39;t too bad since it&#39;s, well, simple. A more complex case however, is when you have more subclasses, more methods calling each other, and each subclass overriding a different subset of the base methods.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;red&quot;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;medium&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;green&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassC&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;small&quot;&lt;/span&gt;

a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassA&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;red&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;#  &quot;medium&quot;&lt;/span&gt;

b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassB&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;green&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;#  &quot;medium&quot;&lt;/span&gt;

c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassC&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;red&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;#  &quot;small&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or, a similar pattern, but utilizing the fact that &lt;a href=http://inspirated.com/2009/05/03/all-methods-in-python-are-effectively-virtual&gt;all methods in Python are effectively virtual&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;red&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;green&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassC&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;_colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;blue&quot;&lt;/span&gt;

a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassA&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;red&quot;&lt;/span&gt;

b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassB&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;green&quot;&lt;/span&gt;

c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ClassC&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;#  &quot;blue&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first glance, the code doesn&#39;t look like traditional spaghetti: there are no if statements, no booleans being passed around, no optional arguments, and no global variables. It all &lt;em&gt;looks&lt;/em&gt; quite clean.&lt;/p&gt;&lt;p&gt;In spite of these, I judge this code to have problems: hidden inconsistency, hidden coupling, historical bias, poor separation of responsibilities, and poor abstraction.&lt;/p&gt;&lt;h3&gt;Hidden inconsistency&lt;/h3&gt;&lt;p&gt;When calling any method on an instance of the subclasses, some objects will call Base class code, and some not, depending on what is defined in the subclass. Each subclass now has unique properties and a unique data flow that must be reasoned about. This might be unavoidable, each case must in some way be different, but my suspicion is that that having this inconsistency &quot;hidden&quot; in the inheritance heirachy tree by nature of some methods being overridden and some not, means more time will need to be spent later when adding/changing behaviour.&lt;/p&gt;&lt;h3&gt;Hidden coupling&lt;/h3&gt;&lt;p&gt;Perhaps a problem with code re-use via inheriance in general, it&#39;s difficult to change code in the base class without affecting the subclasses. This is however especially true when each subclass uses a different subset of the base class methods. The ones that &lt;em&gt;do&lt;/em&gt; use a Base methods are actually the ones that &lt;em&gt;don&#39;t&lt;/em&gt; override them. Hence it&#39;s more accurate to term this &lt;em&gt;hidden&lt;/em&gt; coupling.&lt;/p&gt;&lt;h3&gt;Historical bias&lt;/h3&gt;&lt;p&gt;The code in the base class is most likely only there because it was written first. Very obvious and reasonable when you&#39;re writing it, but come to look at the code in 2 years, it&#39;s not immediately clear why the code is the way it is. Trying to untangle spaghetti is tricky, often trying to work out the reasons the original programmer wrote what they wrote in order to reduce the risk when changing it. Having the extra reason of &quot;that&#39;s what I did first&quot; is making the future&#39;s job harder.&lt;/p&gt;&lt;h3&gt;Poor separation of reponsibilities&lt;/h3&gt;&lt;p&gt;The code in the base class controls certain aspects of the application. Except in the cases where this is overridden. This suggests that responsibility has not been separated well.&lt;/p&gt;&lt;h3&gt;Poor abstraction&lt;/h3&gt;&lt;p&gt;Although I think it&#39;s often unhelpful to think in such terms, overriding Base methods results in the statement that an object &quot;is a&quot; Base becoming a bit meaningless, and therefore unhelpful. The &quot;stuff the object does&quot;, as defined in the base class code, only holds for some of the instances of the subclasses.&lt;/p&gt;&lt;h3&gt;Should I put in an intermediate class?&lt;/h3&gt;&lt;p&gt;It&#39;s tempting to try to model the problem using more &quot;is a&quot; relationships and break the tree down further to factor out common behaviour. My suspicion is that you&#39;re just making things less clear and harder to change later, because you have increased the number of layers in the system and the contracts between them.&lt;/p&gt;&lt;h3&gt;So what &lt;em&gt;are&lt;/em&gt; the alternatives?&lt;/h3&gt;&lt;p&gt;They depend on the code in question, but they all involve moving the code out from the base class, so that each subclass &lt;em&gt;explicitly&lt;/em&gt; states what it uses. For example the code could just be in pure functions not associated with any particular class...&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;medium&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; red&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; medium&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; blue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; medium&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... or if they do need to be part of a class, they could be composed at import time...&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;medium&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  _color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; red
  _size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; medium

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  _color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; green
  _size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; medium&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... or without any inheritance involved...&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;medium&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassA&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  red &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; red
  medium &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; medium

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;medium&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClassB&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  blue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; blue
  medium &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; medium

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blue

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;medium&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... or even with just a single class that is wired up at runtime.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colour&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_colour &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; colour
    self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; size

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_colour&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_size&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Class&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colour&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;red&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;blue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The examples above all &quot;wire up&quot; functions to the classes/instances. However, you can use objects if you want or need to.&lt;/p&gt;&lt;h3&gt;What about type safety?&lt;/h3&gt;&lt;p&gt;One thing that some of the alternatives above have lost is type information, even though they deliberately share the same public API.&lt;/p&gt;&lt;p&gt;In Python, you might not need to want to worry this too much. However, you might want/need a stricter type system, for example for&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; type hints to check before runtime, say using mypy;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; checking types at runtime using &lt;code class=inline&gt;isinstance&lt;/code&gt; or similar;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; run time protection against forgetting to implement a required method.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If so, you have an option: deriving from one or multiple abstract base classes.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; abc &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; ABCMeta&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; abstractmethod

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  __metaclass__ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ABCMeta

  &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@abstractmethod&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  __metaclass__ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ABCMeta

  &lt;span class=&quot;token decorator annotation punctuation&quot;&gt;@abstractmethod&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Colour&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Any of the options above&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;C++ has something similar: you can define a class with only pure virtual functions.&lt;/p&gt;&lt;pre class=language-cpp&gt;&lt;code class=language-cpp&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Colour&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Size&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token base-clause&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Size&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Java, although often encouraging of code reuse using inheritance, has quite nicely got pure abstract base classes built right into the language as interfaces.&lt;/p&gt;&lt;pre class=language-java&gt;&lt;code class=language-java&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Colour&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Size&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Class&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Size&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;colour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&#39;s it!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>E2E Tests: Test as a user would</title>
    <link href="https://charemza.name/blog/posts/angularjs/e2e/test-as-a-user/" />
    <updated>2016-12-25T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/e2e/test-as-a-user/</id>
    <content type="html">&lt;p&gt;This post contains a few recommendations on how to write certain aspects Protractor E2E tests. Specifically how to depend less on the internals of the page. You can&#39;t entirely not depend on internals: they all depend some amount of HTML, and currently you have to choose and interact with the elements of the page &lt;em&gt;somehow&lt;/em&gt;. However, some internals are better than others.&lt;/p&gt;&lt;h3&gt;The point of E2E tests&lt;/h3&gt;&lt;p&gt;First a quick recap on a/the purpose of E2E tests. They ensure that aspects of the application work as expected even if there are later changes: they protect against regressions as you&#39;re developing the application. Essentially they &lt;em&gt;should&lt;/em&gt; fail if some aspect of a user-facing feature changes in an undesirable way.&lt;/p&gt;&lt;p&gt;However, they &lt;em&gt;should not&lt;/em&gt; fail if some internal of the pages changes that doesn&#39;t break a user-facing feature. This doesn&#39;t necessarily directly affect the primary purpose of the tests: they can still protect against regressions. However, failing E2E tests when there is no breakage of a user-facing feature can be a horrible time-sink. With a bit of thought, the risk of this can me minimised, or at least reduced.&lt;sup&gt;&lt;a href=https://charemza.name/blog/posts/angularjs/e2e/test-as-a-user/#footnote-1&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;To this end, there are a few features of Protractor that I think should &lt;em&gt;not&lt;/em&gt; be used.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.&lt;/p&gt;&lt;cite&gt;Ian Malcom, Jurassic Park&lt;/cite&gt;&lt;/blockquote&gt;&lt;h3&gt;Don&#39;t depend on ng-repeat or ng-model: instead, select elements as a user would&lt;/h3&gt;&lt;p&gt;The Protractor documentation suggests selecting HTML elements by &lt;code class=inline&gt;ng-repeat&lt;/code&gt; or &lt;code class=inline&gt;ng-model&lt;/code&gt; attribute contents. This means if someone comes along and does a bit of refactoring, or uses something other than &lt;code class=inline&gt;ng-repeat&lt;/code&gt; or &lt;code class=inline&gt;ng-model&lt;/code&gt;, the E2E tests will fail, even though the behaviour, from the users&#39; points of view, is perfectly fine. I treat this similarly to the test depending on a variable name or process on the server. It seems quite silly for the test to be fragile with respect to that!&lt;/p&gt;&lt;p&gt;Instead, consider using minimal CSS or XPath selectors to pick elements as close as possible to how a user would, that would survive internal refactorings. For example, the first &lt;code class=inline&gt;table&lt;/code&gt; after a &lt;code class=inline&gt;h2&lt;/code&gt; element with text content &quot;Section 1&quot;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;table &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;xpath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;//h2[text()=&quot;Section 1&quot;]/following::table[1]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or, if you have used a custom element for your UI widget directives, the first &lt;code class=inline&gt;&amp;lt;my-widget&amp;gt;&amp;lt;/my-widget&amp;gt;&lt;/code&gt; in the first &lt;code class=inline&gt;&amp;lt;nav&amp;gt;&amp;lt;/nav&amp;gt;&lt;/code&gt; of the page.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;widget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;xpath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;//nav[1]//my-widget[1]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Consider how specific you want the selectors to be. If you have only one &lt;code class=inline&gt;my-widget&lt;/code&gt; in the page, you can be more minimal in the selector.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;widget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;xpath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;//my-widget&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This makes the test less fragile to moving the element around the page. If it&#39;s crucial to test where this is in the page, you could always have an explicit assertion for that, perhaps in a separate test.&lt;/p&gt;&lt;p&gt;Another technique is to choose elements using ARIA roles.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;dialog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[role=&quot;dialog&quot;]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This has the handy benefit of gently pushing you to add accessiblity attributes.&lt;/p&gt;&lt;p&gt;Another technique is selecting elements using &lt;code class=inline&gt;cssContainingText&lt;/code&gt;, say to find &lt;code class=inline&gt;button&lt;/code&gt; that also has the text &quot;Go to stage 2&quot;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cssContainingText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;button&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Go to stage 2&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And as a last, but perhaps still common, resort, using a plain class.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;.message&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If using classes I recommend considering that they are as semantic as possible. This isn&#39;t just to make the HTML &quot;nice&quot;: it&#39;s so that the tests continue to pass as long as the element behaves as it should, independent of any changes or internal refactoring or renaming of non-sematic (with respect to the UI) elements on the page.&lt;/p&gt;&lt;p&gt;I don&#39;t think it&#39;s a perfect solution: you might want to tweak the semantic names for custom elements and classes, and in such cases the tests would still fail, but I suspect it&#39;s better for a lot of cases that depend on &lt;code class=inline&gt;ng-repeat&lt;/code&gt; or &lt;code class=inline&gt;ng-model&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Don&#39;t wait for Angular: instead, wait for the interface as a user would&lt;/h3&gt;&lt;p&gt;If you&#39;re using Protractor, consider setting set &lt;code class=inline&gt;browser.ignoreSynchronization = true&lt;/code&gt; for all tests. Yes, really. The magic Protractor gives you for the simple cases just isn&#39;t worth it, because the cases of having some sort of polling, or non-Angular asynchronous code running, just makes you have multiple sorts of tests.&lt;/p&gt;&lt;p&gt;Instead, wait for changes in the page elements to appear on the screen. You can do this explicitly in your first few tests, but then you might want to factor the waiting out once you are clear what you&#39;re waiting for and commonality between the cases is clear. Your tests will be less flakey to changes you might make in the application. Even, if you eventually decide to swap out Angular!&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ignoreSynchronization &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;[role=&quot;dialog&quot;]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isPresent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, if you&#39;re not using what Protractor builds on top of Selenium, then I would seriously consider just using plain Selenium, or a different framework like &lt;a href=http://webdriver.io/ &gt;WebdriverIO&lt;/a&gt;.&lt;/p&gt;&lt;hr&gt;&lt;p id=footnote-1&gt;&lt;sup&gt;1&lt;/sup&gt; I realise I don&#39;t have quantitative data to back this claim up.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Reasons to not use page objects in E2E tests</title>
    <link href="https://charemza.name/blog/posts/angularjs/e2e/consider-not-using-page-objects-in-e2e-tests/" />
    <updated>2016-12-18T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/e2e/consider-not-using-page-objects-in-e2e-tests/</id>
    <content type="html">&lt;p&gt;Page objects seem to have gained a bit of traction in AngularJS E2E testing, especially since they seem to be &lt;a href=https://github.com/angular/protractor/blob/7b371fcd9e47904dd6e3a226edc70292f08a2547/docs/page-objects.md&gt;officially recommended&lt;/a&gt;. In this post I offer a few reasons &lt;em&gt;not&lt;/em&gt; to use them.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.&lt;/p&gt;&lt;cite&gt;Ian Malcom, Jurassic Park&lt;/cite&gt;&lt;/blockquote&gt;&lt;h3&gt;Reason 1: They obscure behaviour&lt;/h3&gt;&lt;p&gt;Consider the &lt;a href=https://github.com/angular/protractor/blob/7b371fcd9e47904dd6e3a226edc70292f08a2547/docs/page-objects.md&gt;official example&lt;/a&gt; below.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;AngularHomepage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; nameInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;yourName&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; greeting &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;binding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;yourName&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;http://www.angularjs.org&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;setName&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    nameInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;getGreeting&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because of the behaviour of &lt;code class=inline&gt;ElementFinder&lt;/code&gt;, the elements are actually only retrieved when you call &lt;code class=inline&gt;setName&lt;/code&gt; or &lt;code class=inline&gt;getGreeting&lt;/code&gt;. Of course you know this, since you know how Protractor behaves, and can see the code of the page object. But you could have this information much closer to the test rather than elsewhere. When you have more complex page behaviour, with elements appearing and disappearing due to non-trivial behaviour, in order to keep the tests maintainable, it is important to make sure that they are doing what you think they&#39;re doing.&lt;/p&gt;&lt;p&gt;I think the behaviour of &lt;code class=inline&gt;ElementFinder&lt;/code&gt; that attempts to retrieve the element from the page when the element is first interacted with is good for simple cases, but slightly too magical for testing more complex UIs. Hiding this behind your own layer makes this situation even worse.&lt;/p&gt;&lt;h3&gt;Reason 2: They obscure state&lt;/h3&gt;&lt;p&gt;By nature of being objects, they promote keeping an internal state, exposed by an interface. You might not be able to get away from having some state in your tests: they last for some &quot;real&quot; period of time. However, you should be able to keep it all in the main body of the test, keeping only the state you need for that particular test.&lt;/p&gt;&lt;p&gt;Consider the example above. As mentioned, the elements are actually found on the page when you call &lt;code class=inline&gt;setName&lt;/code&gt; or &lt;code class=inline&gt;getGreeting&lt;/code&gt;, but you are offered no way to &quot;refind&quot; an element, say if the application removes them and new ones are added to the DOM. Of course, you can create a new instance of that page object, or add a method to do it,&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;refindNameInput&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  nameInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;yourName&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but doing this means that you are completely leaking how the page object handles state internally. Encapsulation has offered little but another layer of code between the test and what it&#39;s doing.&lt;/p&gt;&lt;h3&gt;Reason 3: They obscure the interactions with the UI&lt;/h3&gt;&lt;p&gt;&lt;a href=https://github.com/angular/protractor/blob/7b371fcd9e47904dd6e3a226edc70292f08a2547/docs/page-objects.md&gt;The page object example in the documentation&lt;a&gt; suggests wrapping the non-semantic UI actions such as typing in an input and getting text from an element...&lt;/a&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;nameInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
greeting&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... with functions with semantic names.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;setName&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  nameInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;getGreeting&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main problems is that it&#39;s needlessly hiding how the object is interacting with the elements on the page and where the object gets its data. This means it&#39;s less clear what the test is testing.&lt;/p&gt;&lt;p&gt;As the application grows, and you have more elements and ways of interacting with them, combinations of key presses, mouse movements, and different and more complex ways of giving output, this can lead to your page objects exposing a lot of what you meant to hide in the first place.&lt;/p&gt;&lt;h3&gt;Reason 4: You are spending time coding for a case of many E2E tests that should never happen&lt;/h3&gt;&lt;p&gt;It is usually recommended to &lt;a href=https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html&gt;&lt;em&gt;not&lt;/em&gt; have that many E2E tests&lt;/a&gt;. If you have a very small amount of E2E tests for each part of your application, then spending time for some future &quot;what if we do this 100s of times&quot; cases is effort expended that has the primary effect of making it harder to reason about each test that you do have.&lt;/p&gt;&lt;h3&gt;Reason 5: They might not be the right abstraction for your cases&lt;/h3&gt;&lt;p&gt;A &quot;page&quot;, at least by name, may not be the right abstraction for finding or interacting with elements in an application. You might have a widget to test in a left menu panel, but it can also appear on the right, accessible from a different selector. Or it might appear at different times. It might also behave slightly differently depending on where it is or when it appears. Or you might even have different browser instances in play, say to test a login/registration flow, and need to control different ones, having them all in-play at once.&lt;/p&gt;&lt;p&gt;Just like optimization, premature refactoring, also known as speculative generalization, can be bad. Instead, I suggest doing continous/&lt;a href=http://martinfowler.com/bliki/OpportunisticRefactoring.html&gt;opportunistic refactoring&lt;/a&gt;. Until you have 3 tests or more, you might not really be able to see what is common to them, and you might get yourself stuck in multiple layers of asynchronous test code and related page objects that aren&#39;t particularly suited to your case.&lt;/p&gt;&lt;p&gt;Keep in mind: there might not even be a &quot;right&quot; abstraction for all your tests, and that&#39;s ok!&lt;/p&gt;&lt;p&gt;Of course, not planning up front has its criticisms.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I find that weeks of coding and testing can save me hours of planning.&lt;/p&gt;&lt;cite&gt;Someone&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;However, I think using page objects just to have encapsulation and because others do it doesn&#39;t quite meet the definition of what I think is planning. At least good planning!&lt;/p&gt;&lt;h3&gt;What to do instead of page objects?&lt;/h3&gt;&lt;p&gt;Always keep in mind what you&#39;re trying to do in the tests.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Finding element(s)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Interacting with element(s)&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Asserting something about element(s)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you have a few tests of a repeated non-trivial group of actions, like a login, or maybe a drag and drop action between one part of a page and another, then factor them out to functions, not objects, that group them. I would really consider not factoring out much more than that.&lt;/p&gt;&lt;p&gt;For example, consider the following test.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;my homepage&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;should greet the named user&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;http://mypage.com&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;xpath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;//label[text()=&quot;Name&quot;]/following::input[1]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    input&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendKeys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Julie&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    greeting &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;xpath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;//label[text()=&quot;Greeting&quot;]/following::p[1]&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Hello Julie!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see, right here in these few lines of code, what the test is doing: how the elements are being found and how Protractor is interacting with them. I think each test of your suite should be this clear. This does mean they will be some repeat calls to &lt;code class=inline&gt;ElementFinder&lt;/code&gt; functions, or maybe some repeated locators, but so be it!&lt;/p&gt;&lt;h3&gt;This doesn&#39;t sound very DRY... what if/when I need to change something?&lt;/h3&gt;&lt;p&gt;Consider the reasons for changing/adding test code.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Changing something trivial in the UI, like text or where an element is on a page&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Changing something non-trivial in the UI, like how a non-trivial group of widgets work together&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Adding a new test&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Fixing an existing test, for example if it is flaky/occasionally fails&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If your main concern is the first case, and you&#39;re worrying that you might have to do a bit of a search-replace in your tests, then my suspicion is that you&#39;re focusing on the wrong thing. At most it&#39;s a few minutes of something a bit boring. I think it&#39;s &lt;em&gt;much&lt;/em&gt; more important to make the tests easier to deal with if your doing something less-trivial, which are the other 3 cases. In those cases, clarity of what the tests are doing is paramount.&lt;/p&gt;&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Say no to more optional arguments</title>
    <link href="https://charemza.name/blog/posts/programming/smells/say-no-to-more-optional-arguments/" />
    <updated>2016-12-10T16:00:00Z</updated>
    <id>https://charemza.name/blog/posts/programming/smells/say-no-to-more-optional-arguments/</id>
    <content type="html">&lt;p&gt;Often you want to pass in an extra variable to an existing function&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;so it supports a new use. You usually want the old use to remain the same, so you add a optional argument with a default value. Often, in Python at least, this default is &lt;code class=inline&gt;None&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So after adding this, you would have two (or more) call sites.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token comment&quot;&gt;# Original call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_original&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# New call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_new_1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_new_2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and quite likely inside the function there will be at least one new block of code that modifies its behaviour in the new case.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; b &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a run-time check, even though you know, at write-time, that the case you want this to run is in the new call site. Having write-time knowledge that you convert to a run-time check is often needlessly increasing number of branches in the code&lt;sup&gt;&lt;a href=https://charemza.name/blog/posts/programming/smells/say-no-to-more-optional-arguments/#footnote-1&gt;1&lt;/a&gt;&lt;/sup&gt;. I suspect it is a response to personal bias against touching existing code, and it biases the code itself: the original use case is clearer than than the new one. All this, I suspect, is likely to make further changes to the code more difficult.&lt;/p&gt;&lt;p&gt;One small improvement is to not have a default value in the parameter list, so the function looks like&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;my_func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; b &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and change the original call site to explicitly pass &lt;code class=inline&gt;None&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token comment&quot;&gt;# Original call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, exactly because you can pass &lt;code class=inline&gt;None&lt;/code&gt;, and the function handles this case separately, &lt;code class=inline&gt;b&lt;/code&gt; is still a &lt;a href=http://mypy.readthedocs.io/en/latest/kinds_of_types.html#the-type-of-none-and-optional-types&gt;de-facto optional argument&lt;/a&gt; to the function.&lt;/p&gt;&lt;p&gt;What to do about this depends on the actual code in question. However, often there is code in the function that can be factored out to functions called from outside of the function in question, ideally each returning meaningful values.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token comment&quot;&gt;# Original call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# New call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_new&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;bar&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;so the code of &lt;code class=inline&gt;my_func&lt;/code&gt; no longer has a special case of handling &lt;code class=inline&gt;b&lt;/code&gt; being &lt;code class=inline&gt;None&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In some cases, if you&#39;re working in a language that allows lambda functions, it might be clearer to extract out a lambda function that you pass in.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token comment&quot;&gt;# Original call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; foo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# New call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_new&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;lambda&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; bar&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And of course, if you&#39;re working in an object oriented language, it might be appropriate to go the whole hog and pass in an object.&lt;/p&gt;&lt;pre class=language-python&gt;&lt;code class=language-python&gt;&lt;span class=&quot;token comment&quot;&gt;# Original call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;new Foo&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# New call site&lt;/span&gt;
my_func&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;arg_new&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;new Bar&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These changes have benefits that they keeps the reponsibility of the original function small, chances are it has limited the number of branches, and it does not bias the code base: the new call site is as clear and deliberate as the original call site.&lt;/p&gt;&lt;hr&gt;&lt;p id=footnote-1&gt;&lt;sup&gt;1&lt;/sup&gt; This statement only has relevance if number of branches is seen as something to be deliberatly avoided, a view which may be oversimplisitc, and in some cases, counter-productive. I am wary of following it too strictly.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Pragmatic Purity</title>
    <link href="https://charemza.name/blog/posts/programming/pure/pragmatic-purity/" />
    <updated>2016-12-09T16:00:00Z</updated>
    <id>https://charemza.name/blog/posts/programming/pure/pragmatic-purity/</id>
    <content type="html">&lt;p&gt;The code below follows a common pattern in impure code.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;doFooImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;doBarImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you can extract out common logic from &lt;code class=inline&gt;doFooImpurely&lt;/code&gt; and &lt;code class=inline&gt;doBarImpurely&lt;/code&gt; into a meaningful intermediate variable that can be calculated purely, so the code is of the following form&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; intermediateValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; condition &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getFooValuePurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBarValuePurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;doImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;intermediateValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then I would recommend considering it. Even if the total cycomatic complexity of the code is equal to what it was, I usually judge the latter to be better because&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; the pure and impure parts of the code are separate, and so better due to the standard separation of concerns arguments;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; depending on what is inside &lt;code class=inline&gt;doImpurely&lt;/code&gt;, there are likely to be fewer impure code paths: this is often better since there are fewer ways state can change or side effects can happen.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The benefit is greater in more complex cases.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;doFooImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCondition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;doBarImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;doQuxImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you can extract out the pure logic, the code can then take the below form.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; intermediateValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
   condition        &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getFooValuePurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;anotherCondition &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getQuxValuePurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBarValuePurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;doImpurely&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;intermediateValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you&#39;re not a fan of the nested ternary operator, you can easily restructure the pure part of the code: make it a series of if statements, extract out to another function, etc. A really nice benefit of pure code is that you can really easily move code about, and have confidence that it doesn&#39;t negatively affect the code that &quot;does stuff&quot;, i.e. the impure code.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Blue-Green Deployment of Static Site on S3</title>
    <link href="https://charemza.name/blog/posts/devops/aws/blue-green-deployment-static-site-s3/" />
    <updated>2016-10-30T16:00:00Z</updated>
    <id>https://charemza.name/blog/posts/devops/aws/blue-green-deployment-static-site-s3/</id>
    <content type="html">&lt;p&gt;This post contains the high level steps for the site architecture and deployment strategy for &lt;a href=http://martinfowler.com/bliki/BlueGreenDeployment.html&gt;blue-green deployment&lt;/a&gt; for a static site hosted on &lt;a href=https://aws.amazon.com/s3/ &gt;S3&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There are a few things that are required for a reasonable blue-green strategy.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; No downtime between releases.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Atomic deployment. A visitor sees a whole working version from before or after the deployment. This can be tricky because a user doesn&#39;t request a site atomically, i.e. first the HTML is requested, and then some time later all the static resources.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; E2E tests run on a certification environment that has the bare minimum of changes between it and production.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To acheive this, you can place the entire site behind an &lt;a href=https://aws.amazon.com/api-gateway/ &gt;API Gateway&lt;/a&gt;. Although the documentation and marketing material hints that it is only suitable for APIs to be consumed programatically, there is nothing stopping it being used for an API to be consumed by people, i.e. a site made up of HTML (and indirectly, CSS, JavaScript, images and fonts). A few features of API Gateway make this possible.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; API gateway has the concept of &lt;a href=http://docs.aws.amazon.com/apigateway/latest/developerguide/stages.html&gt;stages&lt;/a&gt;, where you deploy and API to a stage, and then, later, atomically update another stage to that deployment.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; API gateway can &lt;a href=http://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-s3.html&gt;proxy requests to S3&lt;/a&gt;, so the entire HTML of the site can placed behind the API gateway.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; API gateway supports &lt;a href=http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html&gt;custom domains&lt;/a&gt; and the ability to &lt;a href=http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html#how-to-custom-domains-mapping-basePath-examples&gt;map paths&lt;/a&gt; to specific stages.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With these features in mind, the overal architecture of the site can be as follows.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You have all the HTML pages of the site defined as an API, with appropriate resources defined. A &lt;a href=http://docs.aws.amazon.com/apigateway/latest/developerguide/create-api-using-import-export-api.html&gt;Swagger definition file&lt;/a&gt; is a reasonable choice for this.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; 2 stages setup for the API, each with a custom domain. The public domain of the site has an API mapping from the root path to the production stage; and another domain, which is used for certification, has an API mapping from the root path to the certification stage.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; A single S3 bucket for the assets, i.e. everything except the HTML. These must have versioned file names, such as having a fragment of the md5 hash of the contents. This S3 bucket can be behind a Cloudfront distribution if you would like.&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Two S3 buckets for the html. One for production and one for certification.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A strategy to deploy using this is below.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Deploy static assets to the asset bucket, making sure that each is has a file name that is versioned with an MD5 of its contents, and existing assets are not deleted.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Determine which bucket is in production. One choice is to actually embed this as a mock route in the Swagger definition file, and download this in the build script, so you have an up to date file.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Upload all HTML to the bucket that isn&#39;t in production: the certification bucket.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Modify the Swagger definition file so requests for HTML are proxied to the certification bucket. You could use your favourite template language for this.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Deploy the API, as defined by the modified Swagger definition file, to the certification stage. Take note of the deploymentId.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Run E2E tests.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; If they all pass, update the production stage so its deploymentId is set to the certification stage.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;At every stage above, a visitor to the public site will fetch either the pre-release HTML, or the post-release HTML. In both cases, all the assets will load correctly.&lt;/p&gt;&lt;p&gt;Note: To keep this post brief, not part of this strategy is removal of assets that are no longer used.&lt;/p&gt;&lt;p&gt;That&#39;s it!&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Defer node stream processing</title>
    <link href="https://charemza.name/blog/posts/node/streams/defer-stream-until-promise-resolved/" />
    <updated>2015-12-31T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/node/streams/defer-stream-until-promise-resolved/</id>
    <content type="html">&lt;p&gt;There might be times when you have a chain of piped streams where you want to delay a part of the chain until a promise is resolved. You can do this with a function that returns a simple Transform stream.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; stream&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;objectMode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; enc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; self &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You would need to pipe to and from the return value of the above function, and it will effectively delay the downstream piping until the passed promise is resolved. This can be useful in a gulp task where you don&#39;t want to split it up into sub-tasks, but still want one part of a stream to be processed after another.&lt;/p&gt;&lt;p&gt;As a example, taking part of the gulpfile for this blog, I defer publishing html files until images and stylesheets have been uploaded, so any visitors mid-update don&#39;t see a broken site.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;gulp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;blog/**/*.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BUILD_DIR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BUILD_DIR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;awspublish&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gzip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;binaryResourcesDone&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; textResourcesDone&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;publish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string-property property&quot;&gt;&#39;Cache-Control&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;max-age=&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;, no-transform, public&#39;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
  </entry>
  <entry>
    <title>Animating elements moving between lists</title>
    <link href="https://charemza.name/blog/posts/angularjs/animation/angularjs-animate-elements-between-lists/" />
    <updated>2015-07-19T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/animation/angularjs-animate-elements-between-lists/</id>
    <content type="html">&lt;p&gt;Animating elements between parts of an application can be tricky. The beauty of &lt;code class=inline&gt;ng-repeat&lt;/code&gt; means we can declare that a list, such as a &lt;code class=inline&gt;ul&lt;/code&gt;, should represent a data model, such as an &lt;code class=inline&gt;Array&lt;/code&gt; of data, and the list keeps up to date with whatever changes we make to the underlying model. The tricky bit comes when we want to view not just current state of the model, but transitions between states, such as&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; removal of an item from a list,&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; addition of an item to a list, or&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; moving an item from one list to another.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Pre-Angular 1.4, it was fairly straightforward to animate addition or removal of items from an &lt;code class=inline&gt;ng-repeat&lt;/code&gt; powered list using &lt;code class=inline&gt;.ng-enter&lt;/code&gt; and &lt;code class=inline&gt;.ng-leave&lt;/code&gt; transitions. With 1.4, we can now animate moving a peice of data from one list to another.&lt;/p&gt;&lt;p&gt;The key to this is the &lt;code class=inline&gt;ng-animate-ref&lt;/code&gt; attribute. If the ref-value on an &lt;em&gt;outgoing&lt;/em&gt; element matches an element on an &lt;em&gt;incoming&lt;/em&gt; element, then Angular clones the outgoing element, inserts the clone positioned absolutely on the page, and using CSS transitions moves it from the position of the outgoing to the position of the incoming.&lt;/p&gt;&lt;p&gt;What &lt;em&gt;outgoing&lt;/em&gt; and &lt;em&gt;incoming&lt;/em&gt; mean is that their addition to and removal from the DOM are subject to &lt;code class=inline&gt;.ng-enter&lt;/code&gt; and &lt;code class=inline&gt;.ng-leave&lt;/code&gt; transitions, either on themselves, or on a parent element. For example, we can animate the heights of elements to or from 0 when they are added or removed from a list:&lt;/p&gt;&lt;pre class=language-html&gt;&lt;code class=language-html&gt;}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-repeat&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item in listA&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-click&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;toB(item)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    Item: &#92;{{ item.id }}
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-repeat&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item in listB&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-click&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;toA(item)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    Item: &#92;{{ item.id }}
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with CSS transitions defined as:&lt;/p&gt;&lt;pre class=language-css&gt;&lt;code class=language-css&gt;&lt;span class=&quot;token comment&quot;&gt;/* New element set to 0 height after addition to DOM... */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.item.ng-enter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.1s linear all&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* ...then transitioned to 30px */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.item.ng-enter.ng-enter-active&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* Existing element set to 30px height just before removal... */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.item.ng-leave&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.1s linear all&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/* ... then transitioned to 0 */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.item.ng-leave.ng-leave-active&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above rules work because at the appropriate points in the addition and removal of elements from &lt;code class=inline&gt;ng-repeat&lt;/code&gt; lists, Angular adds the classes on the elements and allows the browser to perform the CSS transitions.&lt;/p&gt;&lt;p&gt;Once the list elements are subject to &lt;code class=inline&gt;.ng-enter&lt;/code&gt; and &lt;code class=inline&gt;.ng-leave&lt;/code&gt; transitions, we add a wrapper &lt;code class=inline&gt;span&lt;/code&gt; to each element, with an &lt;code class=inline&gt;ng-animate-ref&lt;/code&gt; attribute containing the ID of the item, so Angular can match each element leaving the DOM with one entering.&lt;/p&gt;&lt;pre class=language-html&gt;&lt;code class=language-html&gt;}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;List A&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-repeat&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item in listA&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-click&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;toB(item)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item-contents&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-animate-ref&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&#92;{{ item.id }}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Item: &#92;{{ item.id }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;List B&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-repeat&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item in listB&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-click&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;toA(item)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;item-contents&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-animate-ref&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&#92;{{ item.id }}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Item: &#92;{{ item.id }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that depending on the transitions we want, we might not need the extra wrapping &lt;code class=inline&gt;span&lt;/code&gt;, but it keeps the code as flexible as possible, and avoids any ambiguity about what transitions are happening on what elements: the enter and leave transitions take place on the &lt;code class=inline&gt;.item&lt;/code&gt; elements, and the animations between the lists happen on the &lt;code class=inline&gt;.item-contents&lt;/code&gt; elements.&lt;/p&gt;&lt;p&gt;We can control the CSS transition with a single style rule on the &lt;code class=inline&gt;.ng-anchor-in&lt;/code&gt; class that Angular adds to the cloned element.&lt;/p&gt;&lt;pre class=language-css&gt;&lt;code class=language-css&gt;&lt;span class=&quot;token selector&quot;&gt;.item-contents.ng-anchor-in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.2s linear all&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can have a more complex transition if you want by also having a transition on &lt;code class=inline&gt;.ng-anchor-out&lt;/code&gt;, but this is not necessary for this case. You can see the &lt;a href=https://docs.angularjs.org/api/ngAnimate&gt;docs for ngAnimate&lt;/a&gt; for more information.&lt;/p&gt;&lt;p&gt;You can see this in-action, together with the the rest of the boilerplate Javascript and CSS, in the below Plunker. Each item cam be moved by clicking on it.&lt;/p&gt;&lt;iframe src=http://embed.plnkr.co/L0XJS3vEZOACgKqtnqF3/preview&gt;&lt;/iframe&gt;&lt;p&gt;That&#39;s it! There isn&#39;t really much to it.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Throttled variable changes</title>
    <link href="https://charemza.name/blog/posts/angularjs/templates/angularjs-throttled-variable-changes/" />
    <updated>2014-12-20T10:00:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/templates/angularjs-throttled-variable-changes/</id>
    <content type="html">&lt;p&gt;Usually shadowing introduced by prototypical inheritance of &lt;code class=inline&gt;$scope&lt;/code&gt; is something to be avoided, often the source of bugs cause by &lt;a href=&quot;https://www.youtube.com/watch?v=ZhfUv0spHCY&amp;amp;feature=youtu.be&amp;amp;t=32m51s&quot;&gt;not having a dot in models&lt;/a&gt;. However, there is a way it can be used to throttle variable changes in templates.&lt;/p&gt;&lt;p&gt;Thottling variable changes is something you might want to do to avoid flickering of fast changing variables, so the user has a chance to see each state of the interface for a reasonable length of time. A &quot;loading&quot; message or spinner is quite typical, but if it ends up being shown for an extremely short amount of time, say 10ms due to a request having been cached, it can suggest something is a bit broken, or at least not give the user a great experience as it could be.&lt;/p&gt;&lt;p&gt;A small directive can do this, using throttle from &lt;a href=https://lodash.com/ &gt;Lo-dash&lt;/a&gt; or &lt;a href=http://underscorejs.org/ &gt;Underscore&lt;/a&gt;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;throttle&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;WAIT_TIME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;750&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attrs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;throttle&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Shadow the value in the child scope&lt;/span&gt;
        scope&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// The leading edge of the _.throttle callback&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// is called within a digest, but later ones are not&lt;/span&gt;
        scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$$phase &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$watch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throttle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;setValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;WAIT_TIME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which can be used as follows.&lt;/p&gt;&lt;pre class=language-html&gt;&lt;code class=language-html&gt;}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;throttle&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-if&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;state == &#39;loading&#39;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Loading...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-if&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;state == &#39;loaded&#39;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;[Loaded template]&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then in the parent controller you can set the throttled variable, &lt;code class=inline&gt;state&lt;/code&gt; in the above case, as often as you like, and you can be confident that the effect won&#39;t be seen in the template more often than every 750ms.&lt;/p&gt;&lt;p&gt;Benefits of this technique over some others are given below.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The same name of variable is used throughout the template as in the controller that sets the variable. So you can really easily introduce this to existing templates, or remove it if you want to later.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The logic is purely in the template. The controller and factories/services don&#39;t need any code to throttle the variable changes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Limitations or drawbacks of this method are below.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You can only use this for variables &lt;em&gt;without&lt;/em&gt; a dot in them. However, my use case is for simple state variables that just contain a string representing the current state of the interface, which don&#39;t need to be set anywhere but in the parent controller, so they don&#39;t need a dot.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The private variable &lt;code class=inline&gt;$$phase&lt;/code&gt; is used to create a safeApply equivalent. This could be worked-around, but most likely by re-implementing &lt;code class=inline&gt;_.throttle&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Same-domain iframe communication</title>
    <link href="https://charemza.name/blog/posts/angularjs/iframe/same-domain-iframe-communication/" />
    <updated>2014-07-27T09:19:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/iframe/same-domain-iframe-communication/</id>
    <content type="html">&lt;p&gt;It&#39;s possible for Angular apps to communicate, where one is running in an iframe of a parent, using standard scope events. This means you can treat an iframe much like a custom directive, responding to &lt;code class=inline&gt;$broadcast&lt;/code&gt;-ed events, or &lt;code class=inline&gt;$emit&lt;/code&gt;-ting its own.&lt;/p&gt;&lt;p&gt;This technique relies on the child app being able to access the &lt;code class=inline&gt;$scope&lt;/code&gt; of the iframe element in the parent app. This is possible by using &lt;code class=inline&gt;$window.frameElement&lt;/code&gt; to access the iframe element from within the child window, and the &lt;code class=inline&gt;angular.element&lt;/code&gt; &lt;code class=inline&gt;scope&lt;/code&gt; function to get its &lt;code class=inline&gt;$scope&lt;/code&gt;. The child app can then call the parent app&#39;s &lt;code class=inline&gt;$on&lt;/code&gt; and &lt;code class=inline&gt;$emit&lt;/code&gt; functions.&lt;/p&gt;&lt;p&gt;For simplicity, I&#39;ve opted to create a small factory in the child app that returns the scope of the iframe in the parent app. This way, it can be used in a very similar way to &lt;code class=inline&gt;$rootScope&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;appInIframe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;$parentScope&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$window&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;$window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;frameElement&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then in any controller in the child app that wants to communicate with the parent, you can use these functions as per the following example.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;appInIframe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ChildController&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $parentScope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $parentScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;from-iframe&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Sent from iframe&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    $parentScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  $parentScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;from-parent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The only thing you should remember is that you need to trigger a digest manually in each app.&lt;/p&gt;&lt;p&gt;The controller in the parent app can then use standard &lt;code class=inline&gt;$broadcast&lt;/code&gt; and &lt;code class=inline&gt;$on&lt;/code&gt; to commnicate to the iframe.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;appInParentWindow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;ParentController&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;from-iframe&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;from-parent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Sent from parent&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see an &lt;a href=&quot;http://plnkr.co/edit/q7h8nU?p=preview&quot;&gt;example of this technique in a plunker&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Benefits of this technique over some others are given below.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; No additional global functions added to either the parent or the iframe window. Although yes, it does depend on &lt;code class=inline&gt;angular&lt;/code&gt; being global in the parent window.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; The parent controller is ignorant of the fact that events go into an iframe.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; IDs are not used by parent or child. Because the parent uses the standard &lt;code class=inline&gt;$broadcast&lt;/code&gt; and &lt;code class=inline&gt;$on&lt;/code&gt; functions, targeting a specific iframe from the parent controller uses exactly the same techniques you might use to target a custom directive.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>AngularJS Transclude</title>
    <link href="https://charemza.name/blog/posts/angularjs/transclude/angularjs-transclude/" />
    <updated>2014-07-27T09:19:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/transclude/angularjs-transclude/</id>
    <content type="html">&lt;p&gt;Transclusion allows a directive to move clone(s) of the contents of a directive to an arbitrary place in the DOM. Usually this is at the original location of the directive, wrapped in some extra elements, but it doesn&#39;t have to be. So why move the element? You might want components to still have access to the original scope, with any models and methods, but for page-layout or CSS reasons be elsewhere.&lt;/p&gt;&lt;pre class=language-html&gt;&lt;code class=language-html&gt;}
&#92;{{model.variable}}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;move&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  Contents bound to local scope &#92;{{model.variable}}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;move&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Example components that use this could be&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Context menu&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Dialog box&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Sidebar&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Alert box or notification area.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;One thing to keep in mind is that you&#39;ll have to make sure you remove the element from the DOM when the original scope is destroyed. The high-level code would look like the following.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;move&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;restrict&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;E&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;transclude&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;element&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;link&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; controller&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Inject the element somewhere in the page&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;$destroy&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Remove the element from the DOM&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a few techniques that can be used to communicate the clone of the element to the new location.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Directly walk the DOM to inject the clone, jQuery-style.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Use &lt;code class=inline&gt;require&lt;/code&gt; to pass the clone to another directive by calling its controller directive&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Fire off the clone using an Angular event &lt;code class=inline&gt;$emit&lt;/code&gt; or &lt;code class=inline&gt;$broadcast&lt;/code&gt;. Another directive would be listening to this event and inject the clone.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I should admit, I&#39;ve not used this technique for anything but a few tests, so there could be some consequences about this that I haven&#39;t encountered.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>AngularJS Promises</title>
    <link href="https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/" />
    <updated>2014-04-12T09:19:00Z</updated>
    <id>https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/</id>
    <content type="html">&lt;p&gt;AngularJS promises are an extremely powerful tool. They allow you to make a multi-layered and complex system based on asynchronous functions, with error and in-progress notification handling, all without getting into callback hell.&lt;/p&gt;&lt;p&gt;This post attempts to explain both creating and using AngularJS promises. It assumes some familiariy with AngularJS, specifically defining and injecting services and using controllers.&lt;/p&gt;&lt;nav&gt;&lt;h3&gt;Contents&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#what-are-promises&gt;What are promises&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#using-promises&gt;Using promises&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#chaining-promises&gt;Chaining promises&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#resolving-a-derived-promise-immediately&gt;Resolving a derived promise immediately&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#rejecting-a-derived-promise-immediately&gt;Rejecting a derived promise immediately&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#deferring-a-derived-promise&gt;Deferring a derived promise&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#rejection-error-handling-in-promise-chains&gt;Rejection/error handling in promise chains&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#layered-apis&gt;Layered APIs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#creating-promises&gt;Creating Promises&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; &lt;a href=https://charemza.name/blog/posts/angularjs/promises/angularjs-promises/#exceptions-thrown-in-callbacks&gt;Exceptions thrown in callbacks&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/nav&gt;&lt;h3 id=what-are-promises&gt;What are AngularJS promises?&lt;/h3&gt;&lt;p&gt;At the most low-level, a promise is an plain old Javascript object (POJO) with &lt;code class=inline&gt;then&lt;/code&gt; and &lt;code class=inline&gt;finally&lt;/code&gt; functions:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;then&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;successCallback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorCallback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; notifyCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Black box code&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;finally&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;finallyCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Black box code&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and they are returned from functions whose meaningful result will be found or calculated later, i.e. asynchronously. The function will choose which of the callbacks to call, depending on success or failure of the asynchronous action. In case of success, the successCallback is called, and the promise is said to be &lt;em&gt;resolved&lt;/em&gt; with a result. In case of failure, the error is called, and the promise is said to have been &lt;em&gt;rejected&lt;/em&gt; with an error.&lt;/p&gt;&lt;p&gt;You should note:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; You won&#39;t need to construct a promise yourself using object notation. As will be discussed, they will be created via function calls.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt; Angular promises have other functions, but they just shortcuts, so are ommited for this post.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=using-promises&gt;Using promises&lt;/h3&gt;&lt;p&gt;A good first step in understanding promises is to use ones that are created by an existing service. A common use of a promise in AngularJS, are ones created by the &lt;code class=inline&gt;$http&lt;/code&gt; service.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; promise &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the results of the GET request&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the preceeding example, the success of the GET request will cause the &lt;code class=inline&gt;$http&lt;/code&gt; service to &lt;em&gt;resolve&lt;/em&gt; the promise with the result of the GET request. This will then call the successCallback passing this resolved value as the first parameter.&lt;/p&gt;&lt;p&gt;It&#39;s quite common to not assign promises to an intermediate variable. The following is equivalent to the preceding example.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the results of the GET request&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the above examples, only the &lt;code class=inline&gt;successCallback&lt;/code&gt; is used from the promise. If we want to handle a failure then&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url-that-might-fail&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the result of the GET request if it succeeds&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the error if it fails&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although not currently possible, if &lt;code class=inline&gt;$http&lt;/code&gt; ever ends up being modified to give in-progress notfications, then this could be used as&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the results of the GET request&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the error&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the update&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you want to perform some action after the &lt;code class=inline&gt;$http&lt;/code&gt; request has completed, whether it succeeded or failed, then you can use the &lt;code class=inline&gt;finally&lt;/code&gt; function.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something after either success or failure&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The success, failure, notify callbacks can all be ommited, or passed &lt;code class=inline&gt;null&lt;/code&gt; if you have no action to be performed&lt;/p&gt;&lt;h3 id=chaining-promises&gt;Chaining Promises&lt;/h3&gt;&lt;p&gt;The real power from promises comes from chaining. The first key to understanding this is&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The &lt;code class=inline&gt;then&lt;/code&gt; and &lt;code class=inline&gt;finally&lt;/code&gt; functions each return a new promise, known as a &lt;em&gt;derived&lt;/em&gt; promise.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;An example of using derived promises:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; promiseA &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; promiseB &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; promiseA&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the results of the GET request&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
promiseB&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the resolved result of promiseB&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As with the case of a single promise, it is quite common to not assign the derived promises to intermediate variables. The following is equivalent to the preceeding example:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the result of the GET request&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Do something with the resolved result of promiseB&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second key to understanding chains are:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Derived promises are resolved/rejected with the returned resolved/rejected value of the callback that was run.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In practice, this means there are 3 possible ways of controlling the derived promise. It can be resolved immediately, it can be rejected immediately, or its own resolution/rejection can be deferred further until a 3rd promise has been resolved/rejected, in which case the derived promise is resolved/rejected with the 3rd promise&#39;s resolved/rejected value.&lt;/p&gt;&lt;h3 id=resolving-a-derived-promise-immediately&gt;Resolving a derived promise immediately&lt;/h3&gt;&lt;p&gt;If you return anything but a promise from the callback that is run, the derived promise will be resolved immediately with that returned value&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;my-immediate-value&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results === &#39;my-immediate-value&#39;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Be aware that not explicty returning a value means that you have returned &lt;code class=inline&gt;undefined&lt;/code&gt;, and the derived promise will be resolved with &lt;code class=inline&gt;undefined&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Not returning a value.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results === undefined&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above applies to both the success and the error callbacks. Returning any non-promise value from the error callback means that the derived promise will be &lt;em&gt;resolved&lt;/em&gt;, and not rejected:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url-that-does-not-exist&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;my-immediate-value&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results === &#39;my-immediate-value&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As with the success callback, not returning a value from the error callback means the derived promise will be resolved with &lt;code class=inline&gt;undefined&lt;/code&gt;&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url-that-does-not-exist&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Not returning a value.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results === undefined&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I&#39;ve done the above accidentally: it derives a resolved promise from a rejected one, which might be be desirable.&lt;/p&gt;&lt;h3 id=rejecting-a-derived-promise-immediately&gt;Rejecting a derived promise immediately&lt;/h3&gt;&lt;p&gt;You may want to &lt;em&gt;reject&lt;/em&gt; a derived promise, even if the original promise was resolved. This is done by returning the result of &lt;code class=inline&gt;$q.reject()&lt;/code&gt;.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;my-failure-reason&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The code never gets here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// error === &#39;my-failure-reason&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you want to then fail the derived promise from an error callback, then you can do the same thing in it:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url-that does not exist&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The code never gets here if the GET was unsuccessfull&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;my-failure-reason&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The code never gets here if the GET was unsuccessfull&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// error === &#39;my-failure-reason&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=deferring-a-derived-promise&gt;Deferring a derived promise&lt;/h3&gt;&lt;p&gt;A powerful aspect of derived promises is that their resolution/rejection can be deferred until another promise has been resolved/rejected. This is done by returning a promise from the success or error callback. For example, if you want to run &lt;code class=inline&gt;$http.get&lt;/code&gt; calls sequentially, and then do something after the final is successful, you can do this by returning the result of &lt;code class=inline&gt;$http.get&lt;/code&gt; from the callback:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-first-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-second-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results here are the results of the GET to /my-second-url &lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because each &lt;code class=inline&gt;then&lt;/code&gt; call again returns a promise, you can easily add to this chain:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-first-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-second-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-third-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results here are the results of the GET to /my-third-url &lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=rejection-error-handling-in-promise-chains&gt;Rejection/error handling in promise chains&lt;/h3&gt;&lt;p&gt;If a promise is rejected, then every subsequent promise in the chain will be rejected, until one is reached with an error callback.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-first-url-that-fails&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Never called&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-second-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Never called&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-third-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// results here are the results of the GET to /my-third-url &lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Error callback called&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When specifying an error callback, be careful what you return. If you return a non-promise value, which includes &lt;code class=inline&gt;undefined&lt;/code&gt; by not specifying a return value, then the derived promise for that callback will be &lt;em&gt;resolved&lt;/em&gt;, and not rejected.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-first-url-that-fails&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Never called&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-second-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Error callback called&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// This *is* called, because the previous&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// callback returned undefined&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-third-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=layered-apis&gt;Layered APIs&lt;/h3&gt;&lt;p&gt;A common use of promises is chaining them via layered APIs. A typical pattern in AngularJS is to have calls to &lt;code class=inline&gt;$http&lt;/code&gt; functions in a service, so controllers are not aware that &lt;code class=inline&gt;$http&lt;/code&gt; is used.&lt;/p&gt;&lt;pre&gt;&lt;code class=block&gt;MyController -&gt; MyService -&gt; $http&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can do this using a structure like:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token comment&quot;&gt;// In MyService&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fetchResults&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// In MyController&lt;/span&gt;
$scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fetchResults&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  MyService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchResults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Do something with results&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, this means that the controller will be exposed to HTTP headers and statuses. To hide this lower-level detail, you can add post-processing in the service via a derived promises:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fetchResults&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Just return the HTTP body&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also include some of your own error handling, so in the case of a failed request, the controller can be ignorant of any details of HTTP:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token comment&quot;&gt;// In MyService&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fetchResults&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Just return the http body&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Oh no!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// In MyController&lt;/span&gt;
$scope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fetchResults&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  MyService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchResults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Do something with results&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Do something with error if it occurs&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// which would be &#39;Oh no!&#39;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=creating-promises&gt;Creating Promises&lt;/h3&gt;&lt;p&gt;If you&#39;re not chaining onto an existing promise, you might need to create a new, non-derived, promise. You can do this by calling &lt;code class=inline&gt;$q.defer()&lt;/code&gt;. This returns a &lt;em&gt;deferred&lt;/em&gt; object:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; deferred &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The deferred object contains a promise, and methods to call to control that promise:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;resolve&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Black box code&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;reject&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Black box code&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;notify&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Black box code&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string-property property&quot;&gt;&#39;promise&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Promise as described above&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you want to resolve the promise, you can call the &lt;code class=inline&gt;resolve&lt;/code&gt; function. Similarly for the &lt;code class=inline&gt;reject&lt;/code&gt; and &lt;code class=inline&gt;notify&lt;/code&gt; functions.&lt;/p&gt;&lt;p&gt;Using this, a simple timer (ignoring the existence of &lt;code class=inline&gt;$timeout&lt;/code&gt;) can be written as&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;simpleTimeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; deferred &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  $window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Done!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;promise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which could be used as:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token function&quot;&gt;simpleTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Code gets here after 1 second, and&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// result === &#39;Done!&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You could also have a timer that sends a notification:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;simpleTimeout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; deferred &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  $window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Done!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;$

  $window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Half way there!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;promise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which could be use as:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token function&quot;&gt;simpleTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Code gets here after 1 second, and&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// result === &#39;Done!&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// After 1/2 second, code gets here&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// and update === &#39;Half way there!&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=exceptions-thrown-in-callbacks&gt;Exceptions thrown in callbacks&lt;/h3&gt;&lt;p&gt;A not very documented feature of Angular promises is that when exceptions are thrown in the callbacks, via &lt;code class=inline&gt;throw&lt;/code&gt;, then the derived promise will be rejected with that thrown value.&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;$http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/my-url&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;my-failure-reason&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The code never gets here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// error === &#39;my-failure-reason&#39;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will also trigger Angular&#39;s registered exception handler, so it&#39;s not quite equivalent to using &lt;code class=inline&gt;$q.reject()&lt;/code&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ECONNRESET Errors in node.js</title>
    <link href="https://charemza.name/blog/posts/node.js/socket.io/nodejs-socketio-express-econnreset-same-port/" />
    <updated>2013-08-14T19:00:00Z</updated>
    <id>https://charemza.name/blog/posts/node.js/socket.io/nodejs-socketio-express-econnreset-same-port/</id>
    <content type="html">&lt;h3&gt;The Problem&lt;/h3&gt;&lt;p&gt;Running a basic node.js + express + socket.io setup, I would occasionally get ECONNRESET errors. After a bit of trial and error, I found that this seems to have been caused by running socket.io and express on the same port, port 80.&lt;/p&gt;&lt;h3&gt;Solution&lt;/h3&gt;&lt;p&gt;I opened up port 81 on the server, and ran socket.io through port 81. My code to set things up now looks like:&lt;/p&gt;&lt;pre class=language-js&gt;&lt;code class=language-js&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; httpPort &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; socketIOPort &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;81&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; express &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;express&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;httpPort&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; socketIO &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;socket.io&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; io &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; socketIO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;socketIOPort&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I then had to update the client-side socket.io Javascript to connect on port 81, and so far I&#39;ve never had these errors since. For reference I&#39;m running node.js v0.10.0, Express v3.3.4 and socket.io v0.9.16.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Dependency-Based Cache Invalidation</title>
    <link href="https://charemza.name/blog/posts/php/caching/dependency-based-cache-invalidation/" />
    <updated>2013-07-25T09:00:00Z</updated>
    <id>https://charemza.name/blog/posts/php/caching/dependency-based-cache-invalidation/</id>
    <content type="html">&lt;h2&gt;The problem&lt;/h2&gt;&lt;p&gt;With an ever-increased user and code-base, with ever increasing amounts of data, we are approaching limits of what any single relational database can handle over at &lt;a href=http://www.intelligentgolf.co.uk/ &gt;intelligentgolf&lt;/a&gt;. Caching output of database queries and/or generated HTML must be part of any solution, as it&#39;s clearly innefficient to be re-calculating the same things again and again on every page load. While caching things for a set amount of time is easy, the problem is that users demand to see their updates as soon as new data is in the system, for all but a few cases. So the cache must be invalidated. To pull out the obligatory quote:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;&lt;cite&gt;Phil Karlton&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;So, liking a challenge, I set out to design a caching system, for PHP, with the following desired qualities:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Users never see out of date content.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Not to tightly couple the cache code to any other logic.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Not to have to maintain any function that invalidates the cache when a model / database rows is/are updated.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Avoid long processes on update of data.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Any caching code that explains a dependency to the caching system must be next to the code that uses this dependency.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Be flexible enough to cache HTML or arrays of data. Therefore the system can be used to both cache either expensive database calls, or expensive operations in the front-end webserver.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Be able to address the slowest / most frequent accessed pages, or parts of pages, first, without a rewrite of the entire code-base.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Be suitable for non-trivial cases, where cached content can depend on other potentially cached results and results of other functions. HTML pages often depend on data from multiple tables, expensive database queries and/or post-database processing. This is what I understand Russian doll caching to be.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Be suitable for a distributed architecture on virtual servers, such as a load-balanced front-end web servers on AWS.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;The cache is a single key =&amp;gt; value store, where the only access for data is by its primary key, such as Memcached&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Ultimately, the dream is that entire HTML pages could be loaded without calls to the underlying database.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;What I do think are acceptable trade-offs:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;A slight slowdown of code on generation of a result when there is a cache-miss, to accomodate the caching system. The cache could be primed if this is too long.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Cached results can, in some circumstances, be needlessly recalculated, as long as the chance of this quickly decreases with time.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Key-Based Invalidation&lt;/h2&gt;&lt;p&gt;The above requirements seem to lead to the option of &lt;em&gt;key-based&lt;/em&gt; cache invalidation. This is where items are never expired from the cache. Instead, before fetching an object from a cache, the key that identifies the cached object, is itself amended with a date, version, md5, or some unique modifier, that will change whenever there is a change in the underlying data that the cached object itself depends on.&lt;/p&gt;&lt;p&gt;This can work well for dependencies that are known, or can be appropraitely assumed, before any cached result is started to be calculated. For example, the current time or date, any query string parameters, configuration options, or MD5 of code or template files. However, there can be dependencies that are only determined by querying the underlying database, which is precisely what is to be avoided.&lt;/p&gt;&lt;p&gt;An example of this is a list of pages created by a given user, found by the following SQL.&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;SELECT id, pagename FROM pages WHERE pages.created_by = 1234&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What pages those are are only known after the SQL is run.&lt;/p&gt;&lt;h2&gt;Dependency-Based Invalidation&lt;/h2&gt;&lt;p&gt;To address this issue, for any new result that is cached, stored with it is a list of &lt;em&gt;dependency identifiers&lt;/em&gt;, each with a &lt;em&gt;version identifier&lt;/em&gt;, specifying the version at which the dependency was when the cached resulted was computed. Stored separately, is a list of current versions of all the dependencies, which is a) kept updated with the latest version of any dependency, and b) checked before accepting any cached data as a cache hit.&lt;/p&gt;&lt;p&gt;All far so good, but still things needs to be designed.&lt;/p&gt;&lt;h2&gt;Dependency Version Identifiers&lt;/h2&gt;&lt;p&gt;How to identify the current version of any dependency needed some thought. I considered MD5 of any dependent data, version numbers, and using a plain-old last-updated time. I decided that last-updated time was the best option. It has certain properties that make it suitable:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Although it can&#39;t be regenerated from the data if lost, it can be safely assumed to be the current time, which expires any dependant cached results. Version numbers can&#39;t be safely assumed to start from 0, and therefore must be stored permanently.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;It doesn&#39;t depend on the actual data, like MD5, so it can be used for any source, including &quot;abstract&quot; or remote sources that don&#39;t really have anything suitable to take an MD5 of.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;When a cache-miss occurs, checking the last-updated time for any dependency can often only occur after the dependency has been accessed. This means there is race-condition between these, when a second process could have updated the dependency, along with its last-updated time, and potentially causing the first process to store a cached result with an incorrect dependency last-updated time. In order to avoid this, the time at the beginning of the cache-miss can be compared with the last-update time of any dependencies. If any dependency has been updated since the start of the miss, then the result found can be used in the rest of the flow of the page, but not cached. This wouldn&#39;t be possible with version numbers or MD5s.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;However, there are a few drawbacks.&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;Updating last-update time as an atomic operation would be a bit more complicated than incrementing a version number, but still possible using Memcached&#39;s CAS tokens.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-caret-right&quot;&gt;&lt;/i&gt;A cluster of virtual servers can&#39;t be guaranteed to be running at precisily the same time. However, if we can assume a maximum difference in times, say, 2 seconds, then in the case of a cache-miss, the new results will only be stored if all of the dependencies were last updated more the 2 seconds before the start of the miss.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Dependency Idenfitiers&lt;/h2&gt;&lt;p&gt;The structure of a dependency identifier is also cruicial. The code that updates a depedency must use the same identifier that code that uses it. If identifing data by its unique primary key, this is fairly easy. It could be of the form&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt; [table-name]:[primary-key-value]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For example, &quot;users:1234&quot; could be the identifer for a row in the users table.&lt;/p&gt;&lt;p&gt;However, it gets complicated when accessing data by any other means where accessing data by a non-unique key. For example, if wanting to generate a list of pages created by given user in a CMS, this list could be ultimately generated by a SQL like&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt;SELECT id, pagename FROM pages WHERE pages.created_by = 1234&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then not only would the dependency list have to include all these pages, but because the list of pages can be increased, or items removed from it, there must be some dependency on the &quot;WHERE&quot; clause. So my design is to have the identifiers in the following format.&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt; [table-name]:[column-name]:[column-value]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I must then ensure that whenever a row is added or removed from the database, then, for every possible column that could be used as a foreign-key, or in a where-clause, then that dependency has to be treated as updated. For example, marking page with id 2145 as deleted would need 2 dependencies updated:&lt;/p&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;code class=block&gt; pages:id:2145
 pages:created_by:1234
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I was hoping to avoid having anything but one update of a last-update time for any given dependency, to make data updates fast, but I&#39;ve not worked out a way around this. At least, I suspect the maximum number of updates to last-update time would be equal to the number of columns of the table being updated, so it shouldn&#39;t increase with the amount of dependent cached items increased.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Coming in part 2 are some implementation details, along with, hopefully the code.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>About This Site</title>
    <link href="https://charemza.name/blog/posts/aws/hosting/about-this-site/" />
    <updated>2013-07-14T09:00:00Z</updated>
    <id>https://charemza.name/blog/posts/aws/hosting/about-this-site/</id>
    <content type="html">&lt;p&gt;A few technical details about this site.&lt;/p&gt;&lt;h3&gt;Front End&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-font&quot;&gt;&lt;/i&gt;A couple of fonts are included from &lt;a href=https://typekit.com/ &gt;Typekit&lt;/a&gt;. and a few &lt;a href=http://fortawesome.github.io/Font-Awesome/ &gt;Fontawesome&lt;/a&gt; icons are used as well.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-comments&quot;&gt;&lt;/i&gt;&lt;a href=http://disqus.com/ &gt;Disqus&lt;/a&gt; for comments, as below.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-tablet&quot;&gt;&lt;/i&gt;Repsonsive by way of a single @media query to change the position of the content relative to its title.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-html5&quot;&gt;&lt;/i&gt;At the moment, no HTML5 tags other than the DOCTYPE. It&#39;s on the todo list. HTML is also a bit too complicated as in a previous version there was some over-complicated Javascript to show all posts on a single page&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Generation&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-code&quot;&gt;&lt;/i&gt;Uses &lt;a href=http://lesscss.org/ &gt;LESS&lt;/a&gt; for more consistent CSS and easier writing.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-file-text-alt&quot;&gt;&lt;/i&gt;Generated by &lt;a href=http://jekyllrb.com/ &gt;Jekyll&lt;/a&gt; as static files.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-suitcase&quot;&gt;&lt;/i&gt;Assets are concatanated, minified, and md5s added to filenames, to allow far-future expires / age headers on assets, by &lt;a href=https://github.com/ixti/jekyll-assets&gt;Jekyll Assets&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Hosting&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-cloud-upload&quot;&gt;&lt;/i&gt;Hosted on &lt;a href=http://aws.amazon.com/s3/ &gt;Amazon S3&lt;/a&gt; in Ireland, uploaded by &lt;a href=https://github.com/laurilehmijoki/s3_website&gt;s3_website&lt;/a&gt;, gzipping as much content as possible.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-sitemap&quot;&gt;&lt;/i&gt;Uses &lt;a href=http://aws.amazon.com/cloudfront/ &gt;AWS Cloudfront&lt;/a&gt; as CDN, just in case this is ever popular far from Ireland :-). This includes serving the HTML through the CDN, whose filenames don&#39;t change and so I&#39;m invalidating any changed HTML on uploade automatically using &lt;a href=https://github.com/laurilehmijoki/s3_website&gt;s3_website&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-globe&quot;&gt;&lt;/i&gt;The DNS for &lt;a href=http://charemza.name&gt;charemza.name&lt;/a&gt; is hosted by &lt;a href=http://aws.amazon.com/route53/ &gt;Amazon Route 53&lt;/a&gt;. Their ALIAS records allow the content on the root domain &lt;a href=http://charemza.name&gt;charemza.name&lt;/a&gt;, without the &lt;i&gt;www&lt;/i&gt;, to be fronted by the CloudFront CDN.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-envelope-alt&quot;&gt;&lt;/i&gt;My email for &lt;a href=mailto:michal@charemza.name&gt;michal@charemza.name&lt;/a&gt; is hosted by &lt;a href=http://www.google.com/intx/en_uk/enterprise/apps/business/ &gt;Google Apps for Business&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Version Control&lt;/h3&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-github&quot;&gt;&lt;/i&gt;Git, available at &lt;a href=https://github.com/michalc/blog&gt;https://github.com/michalc/blog&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Performance&lt;/h3&gt;&lt;p&gt;Running a &lt;a href=http://loadimpact.com/test/view/1413358&gt;simple test from LoadImpact&lt;/a&gt;, from Singapore, shows:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-play&quot;&gt;&lt;/i&gt;The first loads are quite slow, at 2 seconds. I assume the local CloudFront location is empty.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-fast-forward&quot;&gt;&lt;/i&gt;The later requests hover at 20ms. Not too shabby.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>JQuery UI Datepicker Incorrect Century</title>
    <link href="https://charemza.name/blog/posts/jquery/datepicker/jquery-ui-datepicker-incorrect-century/" />
    <updated>2013-01-27T07:55:30Z</updated>
    <id>https://charemza.name/blog/posts/jquery/datepicker/jquery-ui-datepicker-incorrect-century/</id>
    <content type="html">&lt;p&gt;This is a known bug &lt;a href=http://bugs.jqueryui.com/ticket/8873&gt;bugs.jqueryui.com/ticket/8873&lt;/a&gt;, but I couldn&#39;t find it on a search, so it might be helpful to post here.&lt;/p&gt;&lt;p&gt;I was creating a datepicker for a date of birth field, with no default value, and with a yearRange of &quot;c-100:c-1&quot;. However, the year dropdown kept on jumping to 100 years before the actually selected year. I changed the yearRange option to &quot;c-100:c&quot; and it then worked fine.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Thinking Fast and Slow</title>
    <link href="https://charemza.name/blog/posts/books/psychology/thinking-fast-and-slow/" />
    <updated>2013-01-20T07:55:30Z</updated>
    <id>https://charemza.name/blog/posts/books/psychology/thinking-fast-and-slow/</id>
    <content type="html">&lt;p&gt;Thinking Fast and Slow is a pop psychology book, but one that leans on the academic side, detailing psychological experiments and applications of their consequences. Its main theme is how the assumptions of traditional Behavioural Economics, the main one of which is that people are rational, are flawed, and it gives many examples of results that show this. Here the use of the word rational specifically means that people will decide to do the thing that will give them a best chance of increase their &lt;em&gt;utility&lt;/em&gt;, which from my understanding roughly means a measure of happiness. Often this behaviour is attributed to how &lt;em&gt;System 1&lt;/em&gt; and &lt;em&gt;System 2&lt;/em&gt; processes in the mind behave, which roughly mean &quot;instinctual and instant&quot; and &quot;slow and conscious&quot; respectively. &lt;em&gt;System 1&lt;/em&gt; is subject to a number of biases, and a number of experiments that reveal them are explained and discussed.&lt;/p&gt;&lt;p&gt;It&#39;s an extremely rich book, and one that I found quite eye opening. I thought I was fairly self-aware of the reasons why I do things, and that I am fairly rational. However, many times when reading I realised that I am guilty of the same irrational behaviour that everyone else seems to be. One the more self-help side, it gives suggestions on how to combat such &lt;em&gt;System1&lt;/em&gt; processes.&lt;/p&gt;&lt;p&gt;As a possible criticism, I&#39;m unsure about the separation of all thoughts into 2 distinct categories. Perhaps in the future that will be revealed to be an over-simplification.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>AWS Load Balancer</title>
    <link href="https://charemza.name/blog/posts/aws/load-balancer/long-posts-duplicated/" />
    <updated>2013-01-19T07:55:30Z</updated>
    <id>https://charemza.name/blog/posts/aws/load-balancer/long-posts-duplicated/</id>
    <content type="html">&lt;p&gt;A word of warning to those who use &lt;a href=http://aws.amazon.com/elasticloadbalancing/ &gt;AWS Elastic Load Balancing&lt;/a&gt;. The default configuration is that any request that hasn&#39;t had any data sent from the web server for 60 records, results in the balancer resending the request. The reason for this, presumably, is so that if a server has dies mid-way through a request, the user still would get their request processed by, potentially, another server.&lt;/p&gt;&lt;p&gt;However, at &lt;a href=http://www.intelligentgolf.co.uk&gt;intelligentgolf&lt;/a&gt;, we do some processing that can result in requests that quite naturally last longer than 60 seconds: sending mass email, or interfacing with external systems, which require 100s or 1000s of external connections to interface with 3rd party legacy systems. In some of these cases, we found that duplications were happening, even though we were sure that the form wasn&#39;t being submitted twice.&lt;/p&gt;&lt;p&gt;So, what we do in a lot of cases now:&lt;/p&gt;&lt;ul class=fa-ul&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-check&quot;&gt;&lt;/i&gt;Use a method on the server to detect if a submit button was pressed twice, and effectively ignore the second. This is a good practice in any case, AWS load balancing or not. Javascript checking is not enough here, as the duplications happen due to behaviour of the load balancer, the browser is completely unaware of the duplicate request.&lt;/li&gt;&lt;li&gt;&lt;i class=&quot;fa-li fa fa-check&quot;&gt;&lt;/i&gt;Do the batch processing in the background, using a cron job, or other similar method.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
</feed>