<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Pending Technical]]></title><description><![CDATA[A Programmers Life]]></description><link>https://pendingtechnical.com/</link><image><url>https://pendingtechnical.com/favicon.png</url><title>Pending Technical</title><link>https://pendingtechnical.com/</link></image><generator>Ghost 2.19</generator><lastBuildDate>Fri, 17 Apr 2026 06:25:35 GMT</lastBuildDate><atom:link href="https://pendingtechnical.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Learning Observability]]></title><description><![CDATA[<p>Over the last few years, something I've been hearing more and more about is the term "Observability" for the systems that we build. I came across this term after following <a href="https://twitter.com/mipsytipsy">Charity Majors</a> on Twitter, with her forays into Honeycomb.io and the hard lessons she's learned over the years and</p>]]></description><link>https://pendingtechnical.com/learning-observability/</link><guid isPermaLink="false">602f7955bb445f56f0fcbfe9</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Fri, 19 Feb 2021 09:09:40 GMT</pubDate><content:encoded><![CDATA[<p>Over the last few years, something I've been hearing more and more about is the term "Observability" for the systems that we build. I came across this term after following <a href="https://twitter.com/mipsytipsy">Charity Majors</a> on Twitter, with her forays into Honeycomb.io and the hard lessons she's learned over the years and how much things suck for complex distributed systems. And, as is usually the case, I'm a bit late to the party.</p><p>To my admittedly barebones knowledge, observability is defined as:</p><blockquote>The ability to ask your system a question, any question. Even questions you didn't know you need to ask. And you don't need to ship code to do it.</blockquote><p>Ok cool, so this is where my brain starts to melt. I really struggle to understand the level of abstraction required in your instrumentation to be able to achieve this. This is part of what I'm planning on diving into. I see tools like Application Insights, Splunk and even Seq, and I'm thinking "ok, this sort of sounds like what they're talking about... maybe...". The level of granularity and flexibility these tools allow is incredible and seriously shifted my perspective on how useful and flexible logging can actually be. Tools like <a href="https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/">KQL</a> and Seq's own <a href="https://docs.datalust.co/docs/query-syntax">internal query language</a> are really incredible, and worth exploring on their own merits.</p><p>Is "observability" just another term for "structured logging" (ala Seq)? I don't know. Am I just using a different term for the same thing (and God only knows how many times that type of things bites us as developers!)? I don't know. I'm starting to feel like the meme where someone is trying to budget but has no idea and I'm here like <a href="https://knowyourmeme.com/memes/someone-who-is-good-at-the-economy-please-help-me">'omg help I don't know how to run a logging tool'</a>.</p><p>Another thing I'm planning on looking at is how do you take a system that is heavily embedded in a non-observability style of monitoring or logging, and make it observable? Are these things contradictory?</p><p>After mulling this around again recently when I thought I had some PD coming up, I did what all good developers do... I gathered a bunch of links, chucked them into a OneNote page with the intent of never looking at them again!</p><p>And then, for some reason, today at about 4.45pm on a bloody Friday, my brain was like 'hey Adam would you like some MOTIVATION', and then I really didn't have a choice and here we are. So I'm going to list a bunch of links I've come across, with the intent (lol) of doing some reading over the weekend. Then I'll do another blog post.</p><p>Hopefully.</p><p>A neat little podcast I just stumbled across on Twitter, called <a href="https://www.heavybit.com/library/podcasts/o11ycast/">O11ycast</a>. I listened to the first episode this afternoon, and it was pretty neat.</p><p><a href="https://www.dynatrace.com/news/blog/what-is-observability/">What is Observability</a>, from the folks at Dynatrace.</p><p><a href="https://docs.honeycomb.io/learning-about-observability/intro-to-observability/">Intro to Observability</a>, from the folks at Honeycomb.</p><p><a href="https://logz.io/learn/complete-guide-elk-stack/">Learn the Elk Stack</a>, whatever that is, from the folks at Logz.io.</p><p><a href="https://logz.io/blog/grafana-vs-kibana/">Grafana vs Kibana</a>, whatever those are lol, also from the folks at Logz.io.</p><p>Pray for me dear reader! </p><p>But that's it for now! It's time for some long overdue CSGO.</p>]]></content:encoded></item><item><title><![CDATA[Thoughts and Feelpinions on my ADHD]]></title><description><![CDATA[<p>So, fun fact, I was diagnosed with <a href="https://www.psychology.org.au/for-the-public/Psychology-topics/ADHD-in-adults">ADHD</a> recently.</p><p>Its been something of a wild ride to get to this place, so I thought I'd write this post as a form of catharsis, as it hasn't been an easy journey. It also serves as a message to anyone out there</p>]]></description><link>https://pendingtechnical.com/thoughts-and-feelpinions-of-my-adhd/</link><guid isPermaLink="false">5f969a6fbb445f56f0fcbebd</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Tue, 27 Oct 2020 04:23:38 GMT</pubDate><content:encoded><![CDATA[<p>So, fun fact, I was diagnosed with <a href="https://www.psychology.org.au/for-the-public/Psychology-topics/ADHD-in-adults">ADHD</a> recently.</p><p>Its been something of a wild ride to get to this place, so I thought I'd write this post as a form of catharsis, as it hasn't been an easy journey. It also serves as a message to anyone out there that needs to hear it, and that if they relate to some or all of the things I talk about, it might be a good idea to go chat to your GP/psychologist/psychiatrist.</p><p>Things may get heavy at times, so I'd consider this a trigger warning for discussion of general mental health issues, suicidal ideation and self-harm.</p><h1 id="the-diagnosening-part-1-">The Diagnosening™, part 1.</h1><p>I was browsing Twitter one day, and came across these <a href="https://twitter.com/danidonovan">comics</a> by Dani Donovan. I started poking around, and was initially like 'haha #relatable amirite', but the more comics I read the more I was like 'holy shitsnacks, I think there's something here'. So, so, <em>so</em> many of my behaviours, which I'd assumed were Just Me™ were listed, along with all the destructive side effects of said behaviours all of which I've experienced first-hand. General hyperactivity, struggling to maintain focus, difficulty dealing with overstimulation to just name a few of the core symptoms.</p><p>I started digging in and doing some research (with a healthy dose of skepticism going in, because I know what Dr. Google can be like), and came to the end of <em>that</em>  and was like:</p><p>'... well, <em>shit</em>...'</p><p>Maybe there is something there. I even encountered a term I'd never heard before, that seems to go hand-in-hand with ADHD; <a href="https://www.additudemag.com/rejection-sensitive-dysphoria-and-adhd/">'rejection sensitive dysphoria'</a>. That shit <em>clicked </em>(and writing this has reminded me I still need to confirm this aspect though). I've struggled with suicidal ideation for many years, and when viewed in the context of this and ADHD in general it made a lot of sense. </p><p>My original diagnosis (pre-ADHD) was high functioning borderline personality disorder due to the incredible amount of emotional spikes I would experience and be unable to control (among other things). However the one aspect where my presentation differed from the general rule of thumb with BPD was self-harm. I'd come close to that point several times in my life, and suicidal ideation I had in droves. But actual actions? That was one path I never really went down, and one aspect of the diagnosis of BPD I wasn't sure about. At the time however, given how many other aspects of BPD that did line up, I didn't think much of it. </p><p>The difference this time was it felt like ADHD fit me like a glove. It clicked in a way nothing had before, and I was excited to potentially, finally, have some answers as to how/why I felt like shit all the time. And one of the clear crossovers between BPD and ADHD is <em><a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4739390/">emotional dysregulation</a></em>, so I felt a misdiagnosis was a possibility.</p><p>So, next steps were to book a chat with my psychologist. I've been seeing her for quite a few years now (that 'not easy journey' I was talking about, which I'm not going to cover today), and she knows me pretty well.</p><p>Initially, she was doubtful. I'd never really talked about this sort of thing before, and from her perspective I'd never really presented in that fashion. From my perspective though, <em>so</em> many more things just made more sense, and I explained the vast list of things that led me to this question. She said 'well, lets dig in anyway and see where we go'. So she got me to do an intelligence test, specifically the WAIS-IV. Most of my areas were ok, except for two aspects, <a href="https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-79948-3_1076">Working Memory Index</a> and <a href="https://link.springer.com/referenceworkentry/10.1007%2F978-1-4419-1698-3_246">Processing Speed Index</a>. And as it turns out those two specific drops (when compared to the rest of the aspects of this test) were strongly correlated with people with ADHD! So that, combined with all of my own experiences I was describing to her, was my first diagnosis of ADHD. And, to make matters more interesting, with Generalised Anxiety Disorder thrown in on top. I then asked 'do you think medication would benefit me?' and she responded with 'hmm perhaps have a chat to your psychiatrist'.</p><h1 id="the-diagnosening-part-2-">The Diagnosening™, part 2.</h1><p>So I got another referral from my GP, and sent it off to my psychiatrist. I'd not seen them in a few years, meaning I was considered a 'new-old' patient. It took them two weeks <em>just to look at my referral</em>, because they were so swamped at the time. Gosh, I wonder why.  :: side-eye at the year ::</p><p>Eventually I got the green light (thankfully, as I really liked and trusted this guy), and the first thing they said was 'hey can you bring your academic records for basically all of time, and can you also have someone who knew you as a kid come along (or be available via phone) for an interview'.</p><p>And I was like 'holy shit'. Do they not believe me? Do I really have to go through this entire assessment thing again (because the WAIS is fucking exhausting tbh). Am I going to have the <em>one</em> thing that has helped me order things in my brain and provide an explanation for how I generally felt stripped away? I really started stressing, and my anxiety went through the roof. And I needed to have someone available for an interview, either in-person, or phone, who knew me as a child. So it felt pretty overwhelming, and very serious business™.</p><p>I managed to hunt down most of my high school grades and reports (primary school is lost to the mists of time). And amusingly, <em>hilariously</em>, I see the comments on the report cards. 'You really need to spend more time preparing'. 'You tend to get quite distracted in class'. 'You are usually attentive in this class'. 'You are often "off task"'. The other thing I noticed was that my grades gradually decreased over time. By the end of grade 12, I'd barely passed my subjects. Pretty much straight Cs. People with ADHD <em>suuuuuck</em> at studying stuff they don't give a shit about, and I very clearly remember how much I used to struggle with certain things. Not that I hated studying as such, but more if I was studying something I was passionate about (hello software development!) I was fine. Anything else, and I was a useless wreck.</p><p>So the day (finally) came for the appointment with the psychiatrist. I tell him whats going on, and what my psychologist (clinical psychologist, and this distinction is important as only clinical psychs and psychiatrists are able to diagnose someone with ADHD) has said I've got, and what I think I've got. And his first words were pretty much 'hmm you don't really present as having ADHD'. Haha 🙃. We start the interview with Mum (thanks Mum!), and he's asking a bunch of very specific questions and she's giving a bunch of specific answers. I was <em>extremely</em> hyperactive as a kid as it turns out. To the point where the teachers would be exhausted with me at the end of each term lol. Not that I misbehaved as such, but more would bounce from one desk to another talking to anyone and everyone. I'd always get my work done fairly quickly, but then would distract <em>everyone else</em>. And in grade 1 I'd also get bored very quickly and ask for the grade 2 and grade 3 work. Good times. Poor teachers lol.</p><p>We finished the interview with Mum and I give him a few more bits and pieces, and he says the words™:</p><p>'Yep, ok, you've definitely got ADHD, both inattentive and hyperactive'.</p><p>Cool.</p><h1 id="how-i-felt-">How I felt.</h1><p>Wew. Ok. There are some complicated feelings™ to go through here, so bear with me. It may (will) get sweary.</p><p>Firstly a clear, sharp sense of relief and joy. Because all the years I struggled with crippling self-esteem issues - 'why the fuck am I so lazy, why cant I push through X, why cant I focus, why does everyone else seem to manage better than me?' - were explained with reasonable, twice-validated diagnoses. My brain was wired differently than most people. Cool. Cool cool cool. I've spent a few years in therapy unravelling those self-esteem issues (with varying degrees of success), pre-diagnosis, which is great, but it was wonderful to have a logical explanation for some of the overarching frustrations of my life.</p><p>Ive started to understand certain aspects of myself and my personality. Why I like to work from home, for instance. As it turns out, it's a known thing with people with ADHD that some of them have trouble with <a href="https://www.healthline.com/health/adhd/adhd-trigger-symptoms#Stress">external stimuli</a>, leading to them feeling extremely overwhelmed. Our office gets <em>super</em> busy (and loud) and I struggle to stay on task when I'm there, but if I'm working from home, I don't have that stimuli to overwhelm and drain me, and I can get so much more done. And I feel in general much calmer and happier.</p><p>Next, and this may be familiar to anyone that knows me personally, I think I finally understand why I'm so fucking exhausted all the time. Having that hyperactive aspect of ADHD, means <em>everything</em> is dialled up to 11 in terms of energy input. Someone merged a PR for me? T<em>hey are the greatest person to have ever lived</em>. Someone did something that makes my life difficult? <em>I am angry beyond reason</em>. I fucked up somewhere? <em>I am the worst person to have ever lived, don't look at me I'm fucking hideous</em>. So when you have that level of emotional intensity across <em>all</em> aspects of your life, I think I finally understand why I'm so exhausted. I'll still need to validate this over the next few months as I adjust to my medication (which I'll get to in a sec), but I think there's a strong case for an explanation here.</p><p>Those are just two examples of the newfound understanding I have for my brain, but I'll save the rest for another day. I already suspect this will be a long post.</p><p>After the relief and joy faded I got hit with a wave of overwhelming sadness, frustration and rage (remember the emotional dysregulation I was talking about earlier? Yeah...). How the fuck did it take over <em>30 fucking years</em> to get this point, and no-one thought to mention this as a possibility to me!? I started crying after I left the psychiatrist because the pain of what I've dealt with, untreated and unmedicated all these years has been excruciating, and I've felt completely alone for most of it. The amount of times I've had people come up to be and say 'you're looking so well!' and I smile and nod, but internally I'm just thinking 'What the fuck are you talking about, its absolute fucking chaos in my mind, <em>why cant anyone see this?!</em> I don't understand.'. </p><p>As it turns out, my psychiatrist explained that the reason it went undiagnosed for so long was due to my general intelligence being able to <em>compensate</em> (at least to the external eye) for some of the shitty parts of ADHD. How delightful.</p><p>I've lost count of the amount of times I've seen my close friends, colleagues or family, be just so fucking calm™ no matter what life throws their way. Then I get frustrated with myself, because I simply couldn't be that calm. I remember so many times thinking to myself 'what the fuck is wrong with me, why cant I be like that, what am I doing wrong?!'. No matter how many times I tried, no matter the many, <em>many</em> techniques learned from years of therapy (shout out to <a href="https://www.sane.org/information-stories/facts-and-guides/dialectical-behaviour-therapy-dbt">Dialectical Behavioural Therapy</a> for having the most positive effects on my life!), it just never stuck.</p><p>So it was a wild, wild ride that first 40 mins after the psychiatrist appointment. A maelstrom of intense emotion.</p><h1 id="the-medication-">The Medication.</h1><p>Now this is where things get interesting. I've started taking Ritalin, the brand name of a chemical called Methylphenidate. This is a stimulant, and tends to be the first port of call when treating ADHD. I've gone on a dose that tapers up, and specifically the short-acting (where each tablet lasts 4-6 hours) form for the time being. According to my psychiatrist, this gives me control around the peaks and troughs of its effects throughout the day, and will serve to help figure out the correct dose going forward, at which point he'll put me on the long-acting one (where each tablet lasts 10-12 hours).</p><p>The first time I had Ritalin, it was fucking world changing. But not in the way you probably think, reading that sentence.</p><p>I took a small dose after breakfast, and went for a walk with my wife to see how things went. We walked to our local-ish <a href="https://www.steamlabcoffeetea.com.au/">tea place</a> and sat down for some tea. I started to feel pretty good. Not good as in euphoric, but good as in just... calm? It's so hard to articulate the difference it made. Think about it this way. Imagine you're in a room, with 15-20 kids, all just being kids. Screaming (and you know that particular high-pitched scream kids are great at), yelling, just being kids™, and the place <em>echoes</em> like crazy. And you cant escape, or cover your ears, or actually do anything about it. That's what its like inside my brain normally.</p><p>For the first time in my entire life (and I'm not being hyperbolic there, at all), I was able to step out of the room and into the peace and quiet of the scenery outside.</p><p>It was such a profound difference that I started to suspect a placebo effect may be in play, so I googled it. 'How long does Ritalin take to work'. And the first result I found was <a href="https://www.verywellmind.com/how-long-does-it-take-for-adhd-medication-to-work-4140394">this</a>. I'm going to take a portion of it out, and quote it here, because it blew my (and my wife's) minds:</p><p><em>Some people notice improvements in their ADHD symptoms on the first day of taking their medication. They wonder if their medication could really be working that quickly or whether the difference they felt was a placebo effect.</em></p><p>So, not a placebo effect it seems. Holy shitsnacks.</p><p>I was able to sit with my wife for about 45mins and just talk. Thats it. Just <em>talk</em>, and <em>sit still</em>. I was in no hurry to go anywhere else, wasn't hyperactively drinking tea until I could burst (I normally do this and will go through about 3 or 4 pots in a single sitting lol). I was just calm and talking and we were both having a wonderful time... The difference made us both pretty emotional.</p><p>See what I mean? <em>World changing</em>...</p><p>At the time, I could also feel the emotional spikes doing their thing. I was intensely happy I could be so calm, but I was able to (for the first time ever) stay in control of that intensity and not let it overtake me. And then I'd recognise <em>that</em> ability, and start to feel really happy again and then be able to control <em>that</em> intensity and it kinda got into a loop for a good 20mins. But through it all, I could control it. For the first time in my life I was able to get a better handle on my emotions. And then I realised something...</p><p>This is how normal people feel...</p><p>It kinda blew my mind. I could finally understand how those friends, colleagues and family could still be calm despite what gets thrown at them... because they had a level of actual control over their emotions that I never did. I could understand how people would sit through a 3 hour meeting and not want to rake their eyes out because it feels like you're wanting to crawl out of your skin because its so hard to stay still and focused on whatever crap (that likely could've been an email) they're talking about.</p><p>Going into this, I was initially worried about two things; losing my personality, and losing my sense of humour. Thankfully I can report those are both very intact, and if I could describe it, I'd say its more refined. I still laugh at things, enjoy things, but I don't get overwhelmed or lost in things. It's incredible. THIS IS HOW NORMAL PEOPLE FEEL. Fucking hell.</p><p>Im also more focused. My brain has slowed down, and with it comes the ability to easier articulate my thoughts to those around me. Its strange, but also wonderful.</p><h1 id="so-what-now">So, What Now?</h1><p>Well, now I keep going with my medication. Experimenting (with the support of, and at the direction of, my psychiatrist) until I get my dose right, and then starting from there with a newfound lease on life.</p><p>For the first time in a very, very, very long time I've got something I haven't had in a while. It's cliché as fuck, but it's 'hope'. A while back, I saw a pretty bleak, but accurate, description of how I've felt the last 20 years or so, and it was: 'It's not that I want to kill myself, but it's that I don't want to live anymore'. This has actually, fundamentally <em>changed</em> with getting diagnosed and treated for ADHD. There's <em>hope</em> for me, for treating the chaos inside, and being a stable, functional human being.</p><p>I think a big part of the reason I'm still here, and have been able to function to this point, is due in large part to my wife. She gets me™, and is extremely accommodating with the various quirks of my personality. She proactively gives me space when I need it (hell, she bought me some pyjamas that had Marvin the Martian on it and read: 'Need my space' lol), and has helped me through the various emotional spikes, and general ups and downs that comes with someone with ADHD. And this is <em>pre-diagnosis</em>. Fucking hell.</p><p>She's fucking incredible ❤️</p><p>This feeling of hope is probably the main reason I wrote this post, aside from my own catharsis of rage, frustration and sadness. </p><p>Hopefully someone out there reads this, and gets the help that they need, and gets to the point where <em>they</em> can feel like they've got hope again. I know you're feeling pretty fucked at the moment (and probably have for a long, long time), but it can get better. Reach out to those you can, and talk to the professionals™. It may take time, but it <em>can</em> get better. </p><p>Peace out ✌️.</p><p></p><p>Some links, for the folks that need it ❤️</p><p><a href="https://www.beyondblue.org.au/">Beyond Blue</a> - A great place for those needing support across a variety of mental health issues.</p><p><a href="https://www.adhdaustralia.org.au/about-adhd/">ADHD Australia</a> - A good place to start if you want to dig around about ADHD.</p><p><a href="https://www.borderlinepersonalitydisorder.org/what-is-bpd/bpd-overview/">National Education Alliance for BPD</a> - A good place to start if you want to learn about BPD. And a special mention to <a href="https://www.amazon.com.au/gp/product/B07MMQ95VG/">The Dialectical Behavior Therapy Skills Workbook</a> (not a sponsored link, just something I really liked). I honestly think the techniques in this book could benefit <em>everyone</em>, irrespective of a diagnosis of BPD, ADHD or otherwise.<br><br><a href="https://www.cci.health.wa.gov.au/Resources/Looking-After-Yourself">Center for Clinical Interventions</a> - A place with so, <em>so</em> many good resources on a variety of conditions, providing coping mechanisms, worksheets, exercises and connections to other helpful resources. There are also <a href="https://www.cci.health.wa.gov.au/Resources/Looking-After-Others">resources</a> for those who <em>care</em> for those with mental health conditions. Huge fucking shoutout to all of you out there ❤️ You're awesome.</p><p><a href="https://www.adhddd.com/comics/">ADHD Comics</a> - The comics that started it all for me, by Dani Donovan.</p>]]></content:encoded></item><item><title><![CDATA[Fetching and React Hooks]]></title><description><![CDATA[<p>I'm about 3 weeks into my #100DaysOfCode challenge, and the last two 'days', I've been wrestling with React, async and promises, as well as useEffect and its shenanigans. Today I made some <a href="https://twitter.com/arggrande/status/1302038526737805317">progress</a> which was nice, but I wanted to quickly document the things I've done/learned in a short</p>]]></description><link>https://pendingtechnical.com/fetching-and-react-hooks/</link><guid isPermaLink="false">5f52d210bb445f56f0fcbe65</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Sat, 05 Sep 2020 00:33:21 GMT</pubDate><content:encoded><![CDATA[<p>I'm about 3 weeks into my #100DaysOfCode challenge, and the last two 'days', I've been wrestling with React, async and promises, as well as useEffect and its shenanigans. Today I made some <a href="https://twitter.com/arggrande/status/1302038526737805317">progress</a> which was nice, but I wanted to quickly document the things I've done/learned in a short blog post for Future Adam™ because he's a bit of an idiot sometimes and will likely forget this.</p><p>Fetching for an initial render from within the <code>useEffect</code> hook, can be done like so:</p><!--kg-card-begin: code--><pre><code>  useEffect(() =&gt; {
    const fetchData = async() =&gt; {
      const data = await getAllPosts();
      setPosts(data);
    }
    fetchData();
  }, []);
</code></pre><!--kg-card-end: code--><p>Note a few things:</p><ol><li>We need to wrap an async function <em>within</em> <code>useEffect</code>, as it doesn't support the <code>async</code> keyword on the call to <code>useEffect</code>. If you try, it'll start complaining about <code>Promise&lt;void&gt;</code> resolutions because it doesn't know what you're trying to do.</li><li>We can then call the inline function within <code>useEffect</code> directly, and this gives us the output we want. I don't know <em>why</em> <code>useEffect</code> doesn't support async as part of the call, but here we are. I really don't like having to do this, I'd prefer to use a separate hook called <code>useEffectAsync</code> or something, that'd be nice. I'm sure there's a valid reason™ why it wont let us do it OOTB though.</li><li>Note the <em>empty </em>array of dependencies being passed into <code>useEffect</code>. This tells React 'only run this on first post-render please'. If you find yourself passing dependencies of anything other than basic props, you may be in for a bad time with infinite re-renders due to how React can treat underlying dependencies with what <em>it</em> considers a 'change' (and thus a re-render). This is the part I'm still a bit fuzzy on tbh. I may dig into this a little deeper in a separate post.</li></ol><p>If you want to do something with some basic props:</p><!--kg-card-begin: code--><pre><code>  useEffect(() =&gt; {
    const fetchData = async() =&gt; {
      const data = await getPost(props.titleKey);
      setPost(data);
    }
    fetchData();
  }, [props.titleKey]);
</code></pre><!--kg-card-end: code--><p>I still get a bit tricked up with async code in Javascript/Typescript. If you're like me and need to do some further reading, here are some good resources I've found that have got me to this point (and which I still need to spend some time staring at):</p><p>React Hooks &amp; Fetching Data: <a href="https://www.robinwieruch.de/react-hooks-fetch-data">https://www.robinwieruch.de/react-hooks-fetch-data</a></p><p>Async/Await in TypeScript: <a href="https://blog.logrocket.com/async-await-in-typescript/">https://blog.logrocket.com/async-await-in-typescript/</a></p>]]></content:encoded></item><item><title><![CDATA[100 Days of Code]]></title><description><![CDATA[<p>Recently, I've found myself wanting to get my hands dirty with code. Really dirty. My roles the last few years have resulted in me taking a bit of a step back from coding for the most part, which has had an impact on a few things;</p><ol><li>My confidence in my</li></ol>]]></description><link>https://pendingtechnical.com/100-days-of-code/</link><guid isPermaLink="false">5f4b1fa9bb445f56f0fcbdd5</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Sun, 30 Aug 2020 04:25:41 GMT</pubDate><content:encoded><![CDATA[<p>Recently, I've found myself wanting to get my hands dirty with code. Really dirty. My roles the last few years have resulted in me taking a bit of a step back from coding for the most part, which has had an impact on a few things;</p><ol><li>My confidence in my technical abilities dropped even further.</li><li>My actual technical abilities have dropped off (this is more an objective view, than #1 which is a feelings-centered view)</li></ol><p>It's a bit of a meme at this point, but people that delve into leadership-style positions (whether thats delivery managers, team leads, or [insert another leadership role here]), tend to step away from the code and focus on other things. Stakeholder management, putting out fires, making decisions™, helping others and the other million bits and pieces that make us get to the end of the week and be like 'wait... what have I actually <em>done</em> this week?'. Timesheets are the worst.</p><p>So if you combine the shtick of 'wait what have I <em>produced</em>' this week, with the insecurities that come with stepping away from the code a bit, all of a sudden several years have passed and you realise 'holy shit I am so out of touch'. I think Charity Majors articulated it the best, when she outlined <a href="https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/">"The Engineer/Manager Pendulum"</a>. I'd strongly recommend going and reading that, but the tl;dr I take from it is you'll likely swing back and forth between engineering and management, and that is completely ok. And should be encouraged! Do X until you've had enough and switch to Y, and back the other way. And that is completely ok.</p><p>So right now, I'm swinging pretty hard back to the engineering side of the pendulum. I still like the leadership-type stuff, but I have <em>really</em> missed doing things™.</p><p>Enter <a href="https://www.100daysofcode.com/">#100DaysOfCode</a>.</p><p>I stumbled on this delightful little initiative on Twitter recently, as some of the peeps I follow on Twitter were participating. The rules are really simple;</p><ul><li>Code for 1 hour a day, <em>every day</em>. Yes, even weekends.</li><li>Share your progress somewhere (ideally Twitter).</li></ul><p>An hour can feel like a long time, and I um-ed and ah-ed back and forth for a good week before deciding to commit. My rationale was 'if I can spent an hour binging an anime and YouTube nearly every night, I can find some time for code'.</p><p>My mission was fairly simple;</p><ul><li>My CSS and front-end skills in general suck, and I want to improve them.</li><li>Find out about this "Ayyyy Double-U Ess" thing everyone keeps talking about.</li><li>Grok TypeScript (and by extension Javascript) in a way where I don't need to constantly pester my mates every time TypeScript throws a tantrum.</li></ul><p>So I <a href="https://twitter.com/arggrande/status/1293686765300006913">committed</a>. That tweet is forming the entire timeline for my journey through this, so if you want to see where I'm at, you can use that tweet as a starting point, with the entire timeline as a giant thread!</p><p>My task, at this point at least, is building out a dummy blog engine, based heavily on the style and theming of my actual blog! You can view my code over <a href="https://github.com/arggrande/ptb-engine/">here</a>, as I'm pushing to GitHub as well as CodeCommit for transparency.</p><p>And I don't think I've ever had much this fun programming in my life. I feel so, <em>so </em>productive during that hour. I can already notice my front-end skills feeling considerably sharper (at least in terms of layouts and basic styling, a designer I ain't lol). I've poked around CodeCommit (I have mixed feelings on this, but thats for another post). And my grasp on Javascript and Typescript is getting steadily stronger. Hell, today I got hot-module replacement working on my API, in one shot. ONE SHOT. </p><p>I'm also starting to understand the benefit of tools like SCSS and SASS, because my styles are messy as heck and my inner programmer is internally screaming with how the styles currently sit, as it's basically CSS spaghetti all over the place. That's for Future Adam™ though.</p><p>I definitely <a href="https://twitter.com/arggrande/status/1296790351080914946">struggle</a> with motivation some days, and really need to push myself to get through those tougher days. I find what helps is to just start coding, without thinking about it. Like a robot, grab my laptop and literally just start typing something. Anything. It doesn't even have to be code. That's usually enough to get me going. I'm also making a point to do my hour of coding <em>before</em> work. I'm normally pretty bloody tired by the end of a normal workday, and I know my motivation will suck by that point, so I'm trying to work around my own limitations and gaps and figuring out what works for me.</p><p>I'd 10/10 recommend this initiative if you're someone who is in a similar situation to me, or even just starting out in software development. That regular, structured form of practice that 100 Days of Code provides will show clear benefits within a couple of weeks.</p><p>Good luck, and happy coding &lt;3</p>]]></content:encoded></item><item><title><![CDATA[Thoughts and Feelpinions on Public Speaking]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Recently I had the pleasure of being part of the Perth Visual Studio 2019 Launch Event! This was fairly nerve wracking as I'd never done any public speaking before, and was a deliberate choice on my part to break the ice. I'd signed up along with 6 of my colleagues</p>]]></description><link>https://pendingtechnical.com/thoughts-and-feelpinions-on-public-speaking/</link><guid isPermaLink="false">5cb1a21af4a648698ea0137e</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Mon, 08 Apr 2019 12:49:55 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Recently I had the pleasure of being part of the Perth Visual Studio 2019 Launch Event! This was fairly nerve wracking as I'd never done any public speaking before, and was a deliberate choice on my part to break the ice. I'd signed up along with 6 of my colleagues at <a href="https://readify.net/">Readify</a>, and we split the launch event into several discrete pieces, each of us taking on a separate high-level component of something that made VS2019 tick.</p>
<p>I took on, god help me, the Xamarin changes in VS2019. I have some <a href="http://pendingtechnical.com/react-native-vs-xamarin-forms/">complicated</a> feelings with regards to Xamarin but I have a great deal of respect for the underlying technology and what it accomplishes within the constraints set by the respective native platforms. And after glancing across the landscape of what VS2019 was changing I thought, 'stuff it, I'm doing this'.</p>
<p>I had an absolute <em>blast</em>.</p>
<p>However (and there's always a however lol), there were some things I didn't particularly enjoy. I also learnt a great deal, about public speaking and event planning in general which I thought I'd talk about in this blog post. This is a retrospective, of sorts, in which I'll talk about my experiences with this event - both good and bad - and the learnings I've taken out of it. Now, I tend to run my retros in a similar way across most of my engagements (whether or not this is a good idea is a debate for another day), so I'll break down like this:</p>
<ul>
<li>What went well?</li>
<li>What didn't go so well?</li>
<li>Are there any learnings/improvements for the future?</li>
</ul>
<p>Lets dive in!</p>
<h3 id="whatwentwell">What went well?</h3>
<p>To start with, my presentation. I felt very... <em>comfortable</em> with what I was doing and what I was presenting. I think this is essential if you're ever planning on public speaking. That's not to say must know every single thing about what you're talking about, but you definitely need to know enough that you can at least <em>find out</em> the answer if you get thrown a curveball question at the end... Which I guarantee will happen. My general vibe tends to be quite conversational when presenting (which is nicely in line with my blogging style, actually!), and I felt it flowed mostly well when it came down to it. Practice is also very important, unless you're a veteran and/or you know the content like the back of your hand. And even then, I'd still say you want to practice. You don't need spend hours and hours practicing (I think I probably spent an hour and half in total practicing my 20-ish minute presentation), but it helps from a flow perspective.</p>
<p>The event went by without any major technical problems, aside from a few times the <a href="https://twitter.com/Demo_God">Demo God</a> saw fit to smite some of the demos the team was presenting. That's very much a normal presentation &quot;thing&quot; as far as I'm aware so I don't think it's a thing we need to stress about.</p>
<p>The team worked really well together, and given the amount of people we had speaking, it was awesome to see everyone come together and give feedback where necessary. And this includes both good feedback as well as constructive criticism. Having someone/some people you can trust to provide solid, honest feedback is essential for public speaking. Especially for someone like me, who can go a little too off the deep end sometimes o.O</p>
<p>I got a few curveball questions during my presentation that threw me completely. To the point where internally I was thinking &quot;shit, how on earth did I not consider that?!&quot;. So I simply said &quot;I don't know.&quot; Better to say &quot;I don't know&quot;, and go have a chat to them afterwards and find the answer together than to try and bluff your way through it. Technical people can be pretty brutal so trying to bluff your way through something can be a recipe for disaster. Thankfully I avoided that pitfall.</p>
<h3 id="whatdidntgosowell">What didn't go so well?</h3>
<p>Initially I went way, <em>way</em> to deep for what was supposed to be a high-level, 20 minute presentation to an audience that potentially didn't care about Xamarin. I went <strong>compiler</strong> deep. Now, while the compiler changes were an essential part of what had changed under the hood in Xamarin for VS2019, the level to which I was explaining things was far too detailed for a session like this. The main learning I've taken out of that is to make <em>bloody</em> sure you figure out who your audience is and adjust your content accordingly. I took longer than I should've to get this through my head, but I got there. :)</p>
<p>Something I realised throughout this process was &quot;I don't like being constrained with the content of what I'm talking about.&quot; When I said above I went too deep, I really meant it... But holy shitsnacks I had such a <em>blast</em> on the way! And it made me really sad to have to cut content to fit the audience. The extra context-setting this information had, from a Xamarin perspective, was really fascinating. At least to me :) The next talk I plan to submit will definitely be on my own terms, and I'll let the people/selectors voting on talks decide if they care enough to hear more. Though the active choice of talking about what <strong>I</strong> want to talk about is really important. It washes away any fatigue you might having being up late trying to finish your presentation because the content is riveting.</p>
<p>The Demo Gods took a few potshots at some of my colleagues during their presentations. Now while this wasn't ideal, and even understandable, it still broke the flow of the presentations. There's actually a couple of learnings I took out of this;</p>
<ol>
<li>Demo's are fraught with danger. Coding is hard in a nice safe environment at your desk during your day-to-day work, let alone live-coding in front of an audience. Be very wary of this if you're choosing to do a Demo, and specifically a live-coding session. I actually decided to cut one of my demos at the 11th hour, due to some really, really, <em>really</em> frustrating shenanigans with Xamarin.Android that were simply not playing nice. I wasn't trying to do anything particularly tricky either, exacerbating the frustration I felt. I found that sometimes its a good idea to cut a demo if you feel it puts the general flow of your presentation at risk.</li>
<li>You should always have a backup if your demos go pear-shaped. This can take the form of extra slides that you can talk to, or perhaps even have a short video recorded in advance that you can fall back to. Then you simply speak to the demo, and you minimise the risk in throwing off the flow of your presentation.</li>
</ol>
<p>Another thing I didn't particularly enjoy was the anticipation in the lead-up to the presentation. Unfortunately I am in the habit of &quot;just wanting to get started/get it over with&quot; when it comes to getting stuff done, and this also applies to things in my personal life. This is something I'm actively working on, so hopefully this will get easier as time goes on.</p>
<p>We got made aware of this event with a little less notice than we'd usually like. As such this resulted in the team putting a few extra hours here and there. This isn't a massive deal, but very annoying. My main learning from this is if I'm submitting to do a talk I want to have the content and demos prepared <em>before</em> I submit. This takes away that time pressure, and gives me more time to refine and practice the talk.</p>
<h3 id="arethereanylearningsimprovementsforthefuture">Are there any learnings/improvements for the future?</h3>
<p>This section forms a neat summary of some of the learnings I've outlined above.</p>
<ul>
<li>Know your content well enough, and make some time to practice. By yourself, and with others.</li>
<li>Understand when to take constructive feedback, even if it kills you a little inside. Other people will have perspective you wont, and that can be very valuable.</li>
<li>Understand the audience you're presenting to, and make sure you tailor the content accordingly.</li>
<li>When putting your hand up to talk, pick content that you're passionate about.</li>
<li>Demos can go horribly wrong, so make sure you have a fallback you can rely on.</li>
<li>Don't be afraid to cut a demo if it feels too risky, or you can't get the code to behave when you're coding it by yourself.</li>
<li>It's ok to say &quot;I don't know&quot; to questions that throw you for a loop.</li>
<li>Ideally, have your content and talk planned out before you submit. This will take a good amount of pressure off and you'll be much more comfortable putting your hand up to talk at something.</li>
<li>Next time I'm going to record myself, even if its just audio. I know during practice I was using a lot of filler words like 'um' and 'so', and for the life of me I can't remember if I was doing that during the actual presentation lol. It went by so quickly I blinked and was sitting back down. I was annoyed I didn't think to do this, so its something I'll be addressing next time. This is so I can hear my presentation style for myself and make my own criticisms and improvements.</li>
<li>Buy a presentation clicker. These little gizmos are wonderful, and provide something useful for your hands to be doing, you can use it to emphasize a point, or actually point at things. Fun.</li>
</ul>
<p>And there we have it. I'll have a blog post covering the content I talked about come up in the next few days, but until then hit me up on <a href="https://twitter.com/arggrande">Twitter</a> if you want to chat some more about what I've talked about today :)</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[React-Native vs Xamarin (Forms)... Which should I choose?]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr: It's complicated.</p>
</blockquote>
<p>You didn't think it'd be that easy did you? :) I realise I'm being a little cheeky with that tl;dr, but it honestly <em>is</em> complicated.</p>
<p>There's a few things to talk about when making a choice between React-Native and Xamarin (Forms):</p>
<ol>
<li>The general philosophy in how</li></ol>]]></description><link>https://pendingtechnical.com/react-native-vs-xamarin-forms/</link><guid isPermaLink="false">5cb1a21af4a648698ea0136c</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Mon, 29 Oct 2018 05:14:03 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr: It's complicated.</p>
</blockquote>
<p>You didn't think it'd be that easy did you? :) I realise I'm being a little cheeky with that tl;dr, but it honestly <em>is</em> complicated.</p>
<p>There's a few things to talk about when making a choice between React-Native and Xamarin (Forms):</p>
<ol>
<li>The general philosophy in how the framework tackles cross-platform applications.</li>
<li>Language support</li>
<li>Platform support</li>
<li>The tooling and general developer experience.</li>
<li>Third-party ecosystem.</li>
<li>Feature development.</li>
<li>Continuous Integration and Deployment.</li>
<li>Supportability.</li>
</ol>
<h3 id="caveats">Caveats</h3>
<ul>
<li>You may be wondering why every time I write Xamarin, I'm writing Xamarin (Forms). This is because all of my experience with Xamarin has come hand-in-hand with <a href="https://docs.microsoft.com/en-us/xamarin/xamarin-forms/">Xamarin Forms</a>, so all of my writings here are coloured with that perception (or bias).</li>
</ul>
<p>Lets dig in!</p>
<hr>
<h3 id="generalphilosophy">General Philosophy</h3>
<p>This might be an odd thing to start with, but I think it's important for establishing context in how each framework seems to approach cross-platform development. I think if you can understand this, it's easier to understand the trade-offs involved in picking one framework over another.</p>
<h6 id="xamarinforms">Xamarin (Forms)</h6>
<p><a href="https://visualstudio.microsoft.com/xamarin/">Xamarin</a> is Microsoft's tool for developing cross-platform applications. I feel like Xamarin's approach to cross-platform development is this at its core:</p>
<blockquote>
<p>Abstract away as much of the native platforms as possible behind a .NET Layer</p>
</blockquote>
<p>The best thing about this is it lets developers who have <em>no experience</em> in the native mobile development landscapes, jump in and write an application that can be deployed to quite a few platforms (more on this later).</p>
<p>The drawback (in my Opinion™) with Xamarin is the feature development experience is less than ideal. It's like they've spent most of their energy focusing on the fact you will <em>never</em> need to dive down into Android or iOS with any depth, and they've done this really, really well. As per the caveat in the intro; I haven't done any of the &quot;native&quot; Xamarin development, creating Storyboards, or pure Android views and the like. My experience with Xamarin comes hand-in-hand with <a href="https://docs.microsoft.com/en-us/xamarin/xamarin-forms/">Xamarin Forms</a>, but I think the general point stands<sup>1</sup>.</p>
<h6 id="reactnative">React-Native</h6>
<p><a href="https://facebook.github.io/react-native/">React-Native</a> is Facebook's answer to cross-platform development. The approach to my mind by Facebook is:</p>
<blockquote>
<p>Let React make us lightning quick at writing new features</p>
</blockquote>
<p>And it really is lightning quick at features. More on this later.</p>
<p>The main drawback I've found with React-Native's approach is you're much closer (like, cheek-to-cheek) with the native platforms. You might not think this is a big deal initially, but if you're a .NET practice looking into React-Native, you may want to take a look at <a href="http://pendingtechnical.com/lessons-learned-on-a-react-native-project/">this post</a> I did after my first React-Native project, me being a .NET Dev primarily. If you're already experienced in the native space this may not be a big deal to you, and if so, wonderful!</p>
<p>The main native concerns you deal with in React-Native - specifically around build tools and external dependencies - are still fairly rough around the edges in my opinion. From differences in underlying SDK dependencies to build processes themselves differing between the React-Native CLI and the native IDEs (which you'll also need to spend some time in), to me I still think React-Native needs some more time to mature in this space.</p>
<hr>
<h3 id="languagesupport">Language Support</h3>
<h6 id="xamarin">Xamarin</h6>
<p>Out of the box, Xamarin supports C#, VB.NET and F#, using XAML for its for its views mostly (especially in the Xamarin Forms space). This gives you an incredible amount of flexibility in terms of how you build your application as each of these languages supports a huge variety of ways of working... Object Oriented Programming, Functional Programming, and all of the various well-established patterns that dwell within those disciplines.</p>
<h6 id="reactnative">React-Native</h6>
<p>On the surface React-Native is mainly a JavaScript platform, with TypeScript if you really like type safety (and you should, imo). It uses React-like syntax for defining its views (RN likes the term &quot;Component&quot;). It has a few quirks of difference between &quot;normal&quot; React and React-Native, but they're quite similar.</p>
<p>Under the hood is where things start to get interesting.</p>
<p>React-Native uses pre-built implementations of native projects, which means while on the surface you've got JavaScript, underneath its actually running Java (for Android) and ObjectiveC (for iOS). This means any quirks with those languages you end up inheriting as part of the project. This is the same with any language, to be honest, but unlike Xamarin where it's mostly one variant of a language you'll be using, React-Native becomes more complex in that you need to worry about JavaScript, ObjectiveC and Java. And if you're doing something complex with your app, you'll definitely need to delve into those last two at some point.</p>
<hr>
<h3 id="platformsupport">Platform Support</h3>
<h6 id="xamarin">Xamarin</h6>
<p>Xamarin supports Android, iOS, and UWP, right from when you go <code>File -&gt; New Project</code>.</p>
<h6 id="reactnative">React-Native</h6>
<p>&quot;Vanilla&quot; React-Native supports Android and iOS out of the box. There's no native (ha) support for UWP, however if you take a look at <a href="https://github.com/Microsoft/react-native-windows">react-native-windows</a>, run by the folks at Microsoft, they've made a pretty good start there. I haven't looked at this, so I'm not sure how stable it is.</p>
<hr>
<h3 id="thetoolingandgeneraldeveloperexperience">The tooling and general developer experience</h3>
<h6 id="xamarin">Xamarin</h6>
<p>Xamarin development is done primarily through Visual Studio (and Visual Studio for Mac on MacOS). Visual Studio on Windows is great, however Visual Studio for Mac still has a <em>long</em> way to go in my opinion before I'd consider using it on a full-time basis. I've encountered many bugs, performance issues, and general frustrations with how the IDE is laid out. Its fairly different to Windows' Visual Studio. Amusingly, it seems Xamarin is the <a href="http://pendingtechnical.com/the-react-native-dev-experience-is-designed-with-mac-in-mind-not-windows/">inverse</a> of my experience with React-Native on Windows as Xamarin is extremely Windows focused.</p>
<p>Thankfully Xamarin now allows you to connect to a remote simulator or device from your <em>Windows</em> PC. You still need the Mac, as it serves as the build agent for the iOS components of your solution and the host for the simulator, but aside from that it works <em>great</em>.</p>
<p>The main pain point with Xamarin though, can come from bugs during compilation time with Visual Studio. You'll likely encounter times where your builds don't seem to be coming through to your device/simulator correctly, or where builds fail where DLLs get locked. A few months back I also had some issues trying to upgrade a solution to .NET Standard, and hit some really nasty dependency resolution issues. These have apparently been fixed, but it's something to be wary of, especially if you plan on targeting .NET Standard (or even migrating an existing solution to .NET Standard).</p>
<p>Build times on Xamarin can also be pretty frustrating. It uses MSBuild under the hood to compile any PCL libraries, as well as the native Android components to IL, which is then packaged with <a href="https://www.mono-project.com/">Mono</a>. iOS code is compiled using MSBuild, straight to ARM Assembly (!), and Apple is fairly strict on where you can build its products (yay licensing) so you still need a Mac. If you want to read more (and I think you should as it's really fascinating), I'd check out <a href="https://docs.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/building-cross-platform-applications/understanding-the-xamarin-mobile-platform#compilation">this</a>, <a href="https://docs.microsoft.com/en-us/xamarin/ios/internals/architecture">this</a> and <a href="https://docs.microsoft.com/en-us/xamarin/android/internals/architecture">this</a> on the MS docs where it goes into far more detail.</p>
<h6 id="reactnative">React-Native</h6>
<p>React-Native has one <em>massive</em> point in its favour when it comes to the general developer experience, that of <a href="https://stackoverflow.com/a/41429055">hot reload/live reload</a> used closely in conjunction with the JavaScript you write. Honestly, this is life changing, especially if you're used to long build times like with Xamarin. However if you change anything in the <em>native</em> space, you'll need a full rebuild from the CLI/IDE.</p>
<p>IDE support for React-Native is anything that serves as a text editor, at least for the JavaScript components. My main tool of choice would be VSCode, as there are some fairly useful extensions out there specifically related to React-Native. It uses a Node process to package your JavaScript and send it on the fly to the device/simulator which comes with the usual caveats around Node. Its fairly quick, though I've noticed once it finds an exception sometimes it'll make the process unresponsive and you'll be scratching your head to try and figure out why nothing is working. A simple restart will fix this.</p>
<p>You'll also need to deal frequently with the native IDEs, XCode (for iOS) and Android Studio (for Android). These come with their own quirks and frustrations, and I'd recommend reading up on them before starting a React-Native project.</p>
<p>In addition to this, you're also going to be dealing with the <em>native</em> build tools, that being XCode (iOS) and Gradle (Android). There's a lot here, and it's completely different to how we build and manage JavaScript. It is also significantly more complex, so it's something to be wary of when making the choice of React-Native.</p>
<hr>
<h3 id="thirdpartyecosystem">Third-party ecosystem</h3>
<p>This section mainly focuses around the open-source aspect of each of the native ecosystems. You may have more luck (with both of these frameworks) using paid libraries, but most developers will focus on open-source libraries and components.</p>
<h6 id="xamarin">Xamarin</h6>
<p>The third-party ecosystem for Xamarin is <em>really</em> healthy, and is served mostly via <a href="https://www.nuget.org/">NuGet</a>. You'll come across the odd abandoned project, but for the most part they're normally very active. They're also (obviously) all .NET, so they'll pretty much always work in your project with a simple <code>dotnet add package [package-name]</code>. You may need to do some extra setup, but even that is normally done with .NET classes and methods (as opposed to having to delve into Java and ObjectiveC in React-Native), which is normally straightforward and well documented.</p>
<p>There's also a decent amount of variety, which is important as most packages in the OSS community come with tradeoffs, so you've got options if something doesn't quite fit the bill.</p>
<h6 id="reactnative">React-Native</h6>
<p>Hmmm. I have some <a href="http://pendingtechnical.com/the-react-native-ecosystem-varies-wildly-in-quality/">complicated</a>... <a href="http://pendingtechnical.com/underlying-dependencies-can-trip-you-up-and-probably-will/">feelings</a>... with regards to my thoughts on the React-Native ecosystem. This is one area that React-Native really suffers in my opinion, due to several factors:</p>
<ul>
<li>Abandoned projects</li>
<li>Complex linking processes between JavaScript and Native Code</li>
<li>Reliance on sometimes arbitrary native code, which wont always work/integrate the way you expect with other libraries (ie. Java and ObjectiveC)</li>
<li>Underlying dependency issues</li>
</ul>
<p>I'm not going to go too in-depth with this, as the two posts linked above cover it fairly well. To be fair: there are some really good, fully featured libraries out there in the React-Native space, but the added complexities some of those libraries introduce make it really painful, both from initial integration in your application and potential supportability later on in your application's life.</p>
<hr>
<h3 id="featuredevelopment">Feature Development</h3>
<h6 id="xamarin">Xamarin</h6>
<p>Here is where things can get a little tricky for Xamarin. Feature development in Xamarin is mainly driven by a combination of C# (for logic), and XAML (for Views).</p>
<p>The C# is completely fine, but XAML is a complicated beast. A few things to note;</p>
<ul>
<li>Styling XAML (and Xamarin in general tbh) can be <em>really</em> painful, especially if you want a consistent visual experience between the two main platforms, Android and iOS.</li>
<li>The variant of XAML that Xamarin uses is different to the variants used by UWP and WPF. This means you'll potentially hit some arbitrary limitations, or have to work around these if you're expecting the same level of power that you get in WPF XAML. Thankfully, there is <a href="https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/standard/index?tabs=windows">movement</a> towards a unified XAML implementation across the various technologies that use it, but as of writing this is in preview.</li>
</ul>
<h6 id="reactnative">React-Native</h6>
<p>I'm trying not to make this post a death-match between the two technologies, establishing a clear winner by the end of it. However, if you <em>were</em> making this post a competition, React-Native would win in this space. Provided all the relevant native concerns get out of the way feature development is a breeze. You've got;</p>
<ul>
<li>Live reload/hot reload</li>
<li>CSS-style syntax for layout and styling</li>
<li>A consistent visual experience between platforms</li>
<li>Easier code re-use</li>
</ul>
<p>React-Native's feature development is a different way of thinking (to my mind at least), than Xamarin. How you structure your components and how you re-use them is a slight shift in thinking compared to Xamarin XAML features. With Xamarin you're more likely to have large overall &quot;Pages&quot;, whereas React-Native seems to encourage you to think down a deeper level. This means you can get better code re-use. You can definitely apply this same way of thinking to Xamarin, but I feel like React-Native makes this style of UI design easier, in terms of how quickly you can import and use your components.</p>
<hr>
<h3 id="continuousintegrationanddeployment">Continuous Integration and Deployment</h3>
<h6 id="xamarin">Xamarin</h6>
<p>As Xamarin does such a good job of abstracting away the native dependencies, CI is straightforward. You'll set up your pipeline to build the respective platform's project and you'll use whatever task hooks into MSBuild. You'll still need to ensure whatever build agent you use has the respective Android and iOS SDKs, but its mostly pain-free, at least in my experience.</p>
<p>For deployments, your best bet is <a href="http://appcenter.ms">AppCenter</a><sup>2</sup>. This is Microsoft's attempt to be a one-stop shop for all your Mobile Development needs. It comes with a hosted pipeline for use to use for building the application, while providing a set of fairly powerful integrations with the relevant native platform App Stores, as well as <a href="https://www.microsoft.com/en-au/cloud-platform/microsoft-intune">Intune</a>, a business-focused device management tool that also manages corporate apps. So if this is high on your priority list, this is a good way to go. You can always upload apps to this <em>without</em> the use of AppCenter (VSTS, for example, has tasks that can push to Intune) but the integration provided is really clean and easy to set up.</p>
<h6 id="reactnative">React-Native</h6>
<p>CI is a little complicated in React-Native, as you've got a few steps to think of when building your application in your pipeline.</p>
<ul>
<li>Preparing the React-Native JavaScript bundle</li>
<li>Building the Gradle project, which generates the APK</li>
<li>Building the XCode project, which generates the IPA.</li>
</ul>
<p>As these are all hooking into very distinct, sometimes native concerns, it means you can run into quite a bit of trouble. You'll need to get used to understanding the build output of each of these components, and troubleshoot where necessary. Thankfully, these are all well-documented but if you're going in blind (like I <a href="http://pendingtechnical.com/lessons-learned-on-a-react-native-project/">was</a>) you may be in for a bad time.</p>
<p>In terms of deployment I'd look (again!) at AppCenter, which also covers React-Native! Most of the points with regards too AppCenter in the Xamarin section above stand here too, so I'm not going to rehash it.</p>
<p>I'm not sure how much support there is for Intune, when compared to Xamarin. Xamarin has dedicated libraries to integrate with Intune and is a first-class citizen. There <em>is</em> a React-Native <a href="https://github.com/Durgaprasad-Budhwani/react-native-ms-intune-mam">library</a> out there that looks like it may get you off to a good start, but it hasn't been touched in a while so it may be abandoned. This doesn't look like it's supported by Microsoft either. You may be able to get away with basic functionality, as Intune supports the upload of <em>any</em> APK or IPA.</p>
<hr>
<h3 id="supportability">Supportability</h3>
<p>To be clear, supportability in this context means the probable lifetime of the platform, and how easy/difficult it is to get assistance on issues that may arise during the development (or general support) of your application.</p>
<h6 id="xamarin">Xamarin</h6>
<p>Xamarin is supported by Microsoft, which to my mind is a big deal in the context of supportability. Microsoft made a decent amount of noise in bringing Xamarin into the fold in 2016, so you can bet this is a long term play by Microsoft to get a decent foothold in the cross-platform space. So I think Xamarin will be around for a <em>long</em> time. You can check out the Xamarin Forms Roadmap <a href="https://github.com/xamarin/Xamarin.Forms/wiki/Feature-Roadmap">here</a>. The only thing left in the &quot;core&quot; Xamarin space (as far as I'm aware) would be adding in more APIs that didn't make the cut initially and introducing any new APIs as the core native platforms introduce new functionality down the track.</p>
<p>You also get language support through the usages of F#, C#, VB.NET and XAML, so if you hit any weird and wonderful issues you're quite likely to be able to reach out directly to Microsoft for assistance. And failing that, you've got the usual resources like Stack Overflow, Twitter and the host of MS blogs that operate in this space, outlining things like direction, intention and current state of affairs.</p>
<h6 id="reactnative">React-Native</h6>
<p>React-Native is supported by Facebook, who were also the original creators of the platform. They've spent quite a bit of time and money investing in this platform (as well as React itself) and it doesn't look like they're slowing down any time soon. They're quite active on the React-Native GitHub <a href="https://github.com/facebook/react-native/issues">repository</a>. I couldn't find a proper roadmap as such for React-Native, as you're referred to the <a href="http://facebook.github.io/react-native/blog/">blog</a> for an idea of what they're thinking and where they're heading. It does look fairly active so that's a good sign.</p>
<p>From a language perspective, you're in JavaScript territory from a feature perspective, and then ObjectiveC and Java in the native space.</p>
<p>React-Native generates its native projects with ObjectiveC and Java, and given Kotlin and Swift have been around for a while it looks like <em>eventually</em> the project will get ported to the newer languages, but there's no guarantee. Until then, you're stuck with the quirks and complexity of each (especially ObjectiveC). Upgrading these projects would also potentially be problematic, due to the complexities around dependency management.</p>
<p>If you plan on starting a React-Native project, I would <em>strongly</em> recommend a stricter typing system than pure JavaScript, as this will help your project in the long term for maintainability. You've got a two main options;</p>
<ul>
<li><a href="https://www.typescriptlang.org/">TypeScript</a></li>
<li><a href="https://flow.org/">Flow</a></li>
</ul>
<p>Either one is good, but I prefer TypeScript as it's also supported by Microsoft, who actively add features on a regular basis. If you want more info on this you can check out <a href="http://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native">this</a> blog post on the React-Native blog.</p>
<h3 id="conclusion">Conclusion</h3>
<p>So you may be wondering... &quot;Which should I choose&quot;? And the answer is honestly &quot;it depends&quot;. This post was meant to highlight each of the benefits/trade-offs you may encounter when looking at each of these platforms so you can make an <em>informed</em> decision of which platform is best for your application/company in the long term.</p>
<p>However, if you were to give <em>me</em> no wiggle room, this is what I'd respond with:</p>
<blockquote>
<ol>
<li>If you've got no native mobile experience, and you're a .NET practice, building an app with reasonably tight deadlines, I'd go with Xamarin as it closely aligns with your existing skill-set. The learning curve for React-Native is steep, and unless you've got a safe environment to fail (because you might), React-Native is a huge risk.</li>
<li>If you've got a decent amount of native experience, I feel like React-Native is a better choice overall. General feature development is super quick, and provided you're willing to cop the tradeoffs above you're probably in a good space to get something shipped fairly quickly. The ecosystem is less of a big deal, provided you're willing to write your own native code where necessary.</li>
</ol>
</blockquote>
<p>The reason I didn't put these points in the tl;dr is because these sorts of decisions require <em>context</em> if you want to make the best decision possible. Knowing the tradeoffs for a decision like this is important because the <em>impact</em> of this decision can cause years of pain down the track (not to mention months of pain up front). Even knowing the context now, the points above may not be directly applicable and you may need to make a different choice based on a slightly different situation.</p>
<p>Obviously this is just my opinion, so take it with a grain of salt :)</p>
<p>Hopefully this has helped you make a decision (or at least better understand what you're potentially getting yourself into!) on choosing a cross-platform technology. As always reach out <a href="https://twitter.com/arggrande">Twitter</a> if there's anything you think I've missed or misunderstood.</p>
<sup>
1.  Feel free to yell at me politely on [Twitter](https://twitter.com/arggrande) if you disagree.
2.  While AppCenter is amazing, I'd avoid using it for testing with external users to your organisation. There are quite a few steps involved in the initial sign-up process (which can be scary for your potential users). Mobile browser support is fairly limited, so phones like the Samsung Galaxy range will have trouble, you'll actually need to download Chrome and use that instead of the Samsung browser. AppCenter is still in its early days too, so this will likely change over time.
</sup><!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Lessons Learned on a React-Native Project]]></title><description><![CDATA[Some hard lessons learned on my first react-native project.]]></description><link>https://pendingtechnical.com/lessons-learned-on-a-react-native-project/</link><guid isPermaLink="false">5cb1a21af4a648698ea0136e</guid><category><![CDATA[react-native]]></category><category><![CDATA[ios]]></category><category><![CDATA[android]]></category><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Thu, 25 Oct 2018 06:39:25 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Welcome to my post, dear reader, on my lessons learned on my first React-Native project.</p>
<p>I didn't expect this post to get so wordy, so I'm going to break down each of the above points into its own page, and link it to its respective lesson below. Hopefully that breaks it down into easily digestible chunks :) There, I'll delve into the details of why and how this lesson affected me and why it was important. I'll avoid code and in-depth technical lessons for the most part, as that isn't the focus of this post. Those will likely be separate posts, but linked back to this one.</p>
<p>If you want to take the &quot;I <em>really</em> like reading long posts&quot; path, head over <a href="http://pendingtechnical.com/lessons-learned-on-a-react-native-project-full/">here</a> to see the post in its original form. I prefer this form, as I think it reads a little nicer visually but I've been told I'm weird for liking super long blog posts.</p>
<blockquote>
<p><strong>tl;dr</strong></p>
</blockquote>
<blockquote>
<ol>
<li><a href="http://pendingtechnical.com/react-native-is-not-a-silver-bullet/">React-Native is not a silver bullet. No cross-platform framework is.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li><a href="http://pendingtechnical.com/react-native-does-not-shield-you-from-needing-to-know-about-the-native-aspects-of-the-project/">React-Native does not shield you from needing to know about the native aspects of the project.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="3">
<li><a href="http://pendingtechnical.com/understanding-the-underlying-build-tools-is-extremely-important-in-order-to-be-effective-in-troubleshooting-issue/">Understanding the underlying build tools is extremely important in order to be effective in troubleshooting issues.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="4">
<li><a href="http://pendingtechnical.com/your-debugging-experience-is-extremely-important-if-youre-just-doing-random-console-log-alerts-everywhere-youre-in-for-a-bad-time/">Your debugging experience is extremely important. If you're just doing random console.log/alerts everywhere you're in for a bad time.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="5">
<li><a href="http://pendingtechnical.com/feature-development-in-react-native-is-wonderful/">Feature development in React-Native is <em>amazingly</em> quick, but styling can be brittle at times.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="6">
<li><a href="http://pendingtechnical.com/the-react-native-ecosystem-varies-wildly-in-quality/">The React-Native ecosystem varies wildly in quality.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="7">
<li><a href="http://pendingtechnical.com/underlying-dependencies-can-trip-you-up-and-probably-will/">Underlying dependencies can trip you up, and probably will.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="8">
<li><a href="http://pendingtechnical.com/the-react-native-dev-experience-is-designed-with-mac-in-mind-not-windows/">The React-Native dev experience is designed with Mac in mind, not Windows.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="9">
<li><a href="http://pendingtechnical.com/read-the-documentation-all-of-it-react-native-react-fetch-gradle-and-xcode-all-of-it/">Read the documentation. <strong>All of it</strong>. React-Native, React, Fetch, Gradle and XCode. All of it.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="10">
<li><a href="http://pendingtechnical.com/i-have-no-idea-how-to-do-effective-testing-in-a-react-native-project/">I have no idea how to do effective testing in a React-Native project.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="11">
<li><a href="http://pendingtechnical.com/if-youve-got-native-dev-experience-youre-at-a-huge-advantage-coming-into-react-native/">If you've got native dev experience, you're at a huge advantage coming into React-Native.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="12">
<li><a href="http://pendingtechnical.com/you-probably-want-state-management-for-any-non-trivial-project-from-the-start/">You <em>probably</em> want state management for any non-trivial project, from the start.</a></li>
</ol>
</blockquote>
<blockquote>
<ol start="13">
<li><a href="http://pendingtechnical.com/react-native-lessons-conclusion/">Conclusion</a></li>
</ol>
</blockquote>
<p>Whew. That's a lot of lessons. Overall, this was a fairly difficult for project for me. Not having had any experience in mobile development that wasn't Xamarin, coming into a React-Native project I realized <em>very</em> quickly how out of my depth I was. So, if you're still reading, great! Come with me on a journey of <a href="https://twitter.com/arggrande/status/1011237170173001729"><s>death and destruction</s></a> exploration and discovery!</p>
<p>Before you start digging in though...</p>
<h4 id="caveats">Caveats</h4>
<ul>
<li><a href="https://i.kym-cdn.com/photos/images/original/000/234/765/b7e.jpg">I have no idea what I'm doing</a>. Seriously. Even now, with this blog post, I just have slightly <em>less</em> of no idea what I'm doing.</li>
<li>I'm probably wrong with a few things. I've likely made assumptions or statements that anyone with knowledge of React-Native (or the respective native platforms) will probably go &quot;uhhh... what?&quot;. If so, please yell at me politely on <a href="https://twitter.com/arggrande">Twitter</a>, and I'll add some updates where necessary.</li>
<li>Some of these issues were <em>greatly</em> exacerbated by my lack of any native mobile development knowledge coming in. Up until this project, most of my mobile development experience came in the form of Xamarin, which is the .NET variant of cross-platform mobile development.</li>
<li>I'm not covering <a href="https://expo.io/">Expo</a> as part of this post. The main issue with Expo was as soon as you need to hook into anything <em>not</em> covered by its libraries you need to <a href="https://docs.expo.io/versions/v30.0.0/expokit/eject">&quot;eject&quot;</a> from the Expo project and then you're in the wilderness of React-Native anyway.</li>
</ul>
<p><a href="https://media.giphy.com/media/145hX7QVWqyili/giphy.gif">Good luck!</a></p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[LINQ and their ES6 Equivalents]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>I've started working on a new client recently, where the tech stack on the front-end is React. This means I've started delving into the deep, dark world of JavaScript* (or ECMAScript, if you prefer).</p>
<p>A <a href="https://twitter.com/benjaminlowry">mate</a> at work flicked through a neat little table that outline common LINQ functions in</p>]]></description><link>https://pendingtechnical.com/linq-and-their-es6-equivalents/</link><guid isPermaLink="false">5cb1a21af4a648698ea01368</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Thu, 13 Jul 2017 13:31:38 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>I've started working on a new client recently, where the tech stack on the front-end is React. This means I've started delving into the deep, dark world of JavaScript* (or ECMAScript, if you prefer).</p>
<p>A <a href="https://twitter.com/benjaminlowry">mate</a> at work flicked through a neat little table that outline common LINQ functions in use throughout C#, and their ES6 equivalents. So I thought I'd take a second to blog (woooo, look at me all blogging and stuff!) about it, before I forget.</p>
<table border="1">
<tr>
<td><b>LINQ</b></td><td><b>ES6</b></td>
</tr>
<tr>
<td>Any</td><td><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some">some</a></td>
</tr>
<tr>
<td>All</td><td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every">every</a></td>
</tr>
<tr>
<td>Aggregate</td><td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce">reduce</a></td>
</tr>
<tr>
<td>Select</td><td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a></td>
</tr>
<tr>
<td>Where</td><td><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter</a></td>
</tr>
</table>
<p>This shiny little nugget of knowledge came about as I was kludging my way around a <code>for</code> loop in a function, iterating over an array of objects, checking if a value existed. A colleague informed me &quot;uhh why don't you just <code>some</code>&quot;. You can even invoke it using an arrow function:</p>
<blockquote>
<p><code>myArray.some(val =&gt; val === mySuperAwesomeValue)</code></p>
</blockquote>
<p><a href="https://media.giphy.com/media/l3q2K5jinAlChoCLS/200w.gif">My reaction...</a></p>
<p>Neat!</p>
<p>I found it interesting how in seeing these direct comparisons helped me demystify some of the language or terminology I've seen scattered around JavaScript, which in all honesty I'd found a bit intimidating so far.</p>
<p>This lead to some interesting discussions on LINQ and some of the lesser (to me, at least) known functions in JavaScript land, which led to Ben showing me this handy little table.</p>
<p>If you're interested in functional programming within the realm of JavaScript, I was also linked to this little <a href="https://github.com/stoeffel/awesome-fp-js">gem</a>, which is a great resource collating the various entries into functional programming that JavaScript has made. Thanks <a href="https://twitter.com/todthomson">Tod</a>!</p>
<p>Got another cool function I'm missing? Hit me up on the <a href="https://twitter.com/arggrande">twitters</a>!</p>
<p>Night all!</p>
<p><sup><sup>*In all seriousness, if you are doing a project that involves JavaScript, I'd recommend checking out <a href="https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=mt_paperback?_encoding=UTF8&amp;me=">JavaScript: The Good Parts</a>. This book gave me a new appreciation of the unexpected power of JavaScript and enabled me to hate it a little less :) </sup></sup></p>
<p>[Edit 14-Jul-2017]: I've just been informed these methods have actually been around since <em>ES5</em>. Just goes to show how long it's been since I've really done anything serious in JavaScript. Thanks <a href="https://twitter.com/slace">Aaron</a>!</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Automating repetitive tasks in SQL Server Management Studio]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>This post is going to be somewhat shorter than my usual post. My job tends to have me focusing on the Microsoft stack, and as a result I will spend large amounts of time using SQL Server, and working in SQL Server Management Studio.</p>
<p>In my opinion, SSMS is pretty</p>]]></description><link>https://pendingtechnical.com/repetitive-tasks-in-ssms/</link><guid isPermaLink="false">5cb1a21af4a648698ea01364</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Mon, 21 Nov 2016 06:23:30 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>This post is going to be somewhat shorter than my usual post. My job tends to have me focusing on the Microsoft stack, and as a result I will spend large amounts of time using SQL Server, and working in SQL Server Management Studio.</p>
<p>In my opinion, SSMS is pretty solid. Having used Toad/SQL Developer (of Oracle fame), I can confirm that SSMS is miles ahead of everything else I've seen elsewhere.</p>
<p>This post focuses on the idea of scripting out repetitive actions in SSMS. If you've ever done work with complex operations where a single action has multiple effects on the database, you've probably been in the situation where you want to test something repeatedly.</p>
<p>I will actually make a backup of the database when it's in a state that is <em>ready</em> for the operation I'm about to complete. I will execute the action, and observe the outcome, and then when I'm ready to re-test it again, restore that backup. This way I can get a clean, repeatable experience each time I test something.</p>
<p>The SSMS UI for restoring a database is fairly straight forward:</p>
<p>Right click on the <strong>'Databases'</strong> node -&gt; Restore Database -&gt; Select your source and backup file, adjust the relevant options, and click OK. See, that's not <em>too</em> bad. However... there's a better way!</p>
<p>Before you click OK, have a look at the top of that window:<br>
<img src="https://pendingtechnical.com/content/images/2016/11/SeriousDb.png" alt="Serious DB"></p>
<p>See that <strong>'Script'</strong> menu at the top of the DB restore screen? If you click that, and click <strong>'New Query Editor Window'</strong>, it will generate the SQL script that is used to execute the equivalent commands of everything you've just selected in that restore screen, and open it in a new window!<br>
<img src="https://pendingtechnical.com/content/images/2016/11/SeriousDbAutomated.png" alt=""></p>
<p>Now, each time you want the database back to that state, you simply switch back to this window, hit F5, and BAM. Restored Database, without all those annoying extra clicks.</p>
<blockquote>
<p>Be sure, in the <strong>Options</strong> screen before you script this out, that you check 'Close existing connections to the database' and/or 'Overwrite the existing database'. This makes the restore process much cleaner, and less prone to failing.</p>
</blockquote>
<p>Sure, it's a small thing in the scheme of things, but things like this make our lives so much easier in the long run :) You can do this sort of thing with pretty much <em>every</em> action in SSMS, so hopefully this post inspires you to automate All of The Things™.</p>
<p>Good luck!</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Thoughts and Feelpinions on helping organise a Conference]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>This post has been overdue (like so many of my posts on my mental backlog) for a few months now, but I'm finally getting around to putting down some thoughts and feelpinions on helping organise a conference. This year, I was asked if I wanted to help organise the <a href="https://dddperth.com">DDD</a></p>]]></description><link>https://pendingtechnical.com/thoughts-and-feelpinions-on-helping-organise-a-conference/</link><guid isPermaLink="false">5cb1a21af4a648698ea01363</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Tue, 08 Nov 2016 11:33:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>This post has been overdue (like so many of my posts on my mental backlog) for a few months now, but I'm finally getting around to putting down some thoughts and feelpinions on helping organise a conference. This year, I was asked if I wanted to help organise the <a href="https://dddperth.com">DDD Perth</a> conference. I said 'heck yes', and so I was enlisted. I'd never been a part of anything like this before, so I was looking forward to stepping completely out of my comfort zone. This post <em>isn't</em> a retrospective, but more a collection of my jumbled thoughts articulated in written form.</p>
<p>The first main take away from my experiences was:</p>
<blockquote>
<p>You meet some damn awesome people.</p>
</blockquote>
<p>Whether its fellow organisers, attendees, speakers or hotel staff, you come across some really amazing people. They are extremely focused, great at their jobs and are usually willing to go above and beyond in helping people out. I'd been following some of these people on Twitter for quite some time, so I already had a great deal of respect for them which was solidified on meeting them in person. There are so, <em>so</em> many awesome people in the developer community, and I honestly felt honoured to have been able to listen to them speak, and interact with some of them on a personal level, directly as a result of helping organise DDD Perth.</p>
<p>The next thing that jumps out at me is:</p>
<blockquote>
<p>Conferences are damn hard work.</p>
</blockquote>
<p>I was honestly shocked at the amount of thought, organisation and planning that goes into creating the experience I'd taken for granted as an attendee the previous year (the inaugural DDD Perth conference was just last year and I bloody loved every second). When things are going smoothly, you get the impression that everyone just YOLOs everything, but it coudln't be further from the truth. Overall, things went fairly well on the day and the feedback we had was pretty positive.</p>
<p>What I find fascinating about this, is that there were a few times I wanted to give up and withdraw my help. I'd just started a new job and was still adjusting to that, on top of having some interesting clients to deal with who took a significant part of my energy during the day, I honestly came very close to throwing in the towel. Thankfully, my wife saved the day and convinced me to stay on and I'm so bloody glad she did. On the day of conference, looking around at the amount of people we'd all gathered in one place to talk tech for the entire day (we had 3 tracks of speakers!), it hit me the significance of what we'd accomplished, and it was <em>extremely</em> satisfying, which gets me pretty fired up for next year! :)</p>
<p>I think in conclusion, the first point of this post justifies the second. Conferences are some pretty hairy things to put together, but the satisfaction you get from contributing to the community in this fashion, and all the cool people you get to meet, more than justifies the energy put in. I hope you enjoyed my rambling, and if you have any thoughts or feelpinions of your own, feel free to hit up me on <a href="https://twitter.com/arggrande">Twitter</a>. :)</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[On Seq and the usefulness of Serilog]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr - Seq and Serilog are an amazing combination and worth checking out</p>
</blockquote>
<p>I've recently been dealing with <a href="https://getseq.net">Seq</a>, a structured logging tool used for .NET Applications, and <a href="https://serilog.net">Serilog</a>, a .NET wrapper for logging events to Seq. Having used Serilog and Seq a few times now, across a few</p>]]></description><link>https://pendingtechnical.com/on-seq-and-the-usefulness-of-serilog/</link><guid isPermaLink="false">5cb1a21af4a648698ea01362</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Tue, 01 Nov 2016 07:01:39 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr - Seq and Serilog are an amazing combination and worth checking out</p>
</blockquote>
<p>I've recently been dealing with <a href="https://getseq.net">Seq</a>, a structured logging tool used for .NET Applications, and <a href="https://serilog.net">Serilog</a>, a .NET wrapper for logging events to Seq. Having used Serilog and Seq a few times now, across a few different projects, I thoroughly recommend it if you're looking some really simple, clean and powerful logging.</p>
<p>Today's post came about due to some recent troubleshooting I had to do at a client site, as we were observing some strange behaviour with Serilog. The resulting investigation inspired me to dig into Serilog specifically, to have a look at what other cool stuff I could find. I'm also attempting a new style with the associated code for this post, hosting in its own <a href="https://github.com/arggrande/SerilogPoC">repository</a> on GitHub. Previously, I'd attempted hosting them within a single generic 'BlogEntryCode' repository, with readme.md files for explanations, but I think I like this form of isolation a bit better. I've also split the major stages of my investigations into separate commits:</p>
<ol>
<li><a href="https://github.com/arggrande/SerilogPoC/commit/d4a51457e9430e4dd3c7cd4202d8ef1df9296bc6">Use of static logging configuration with Serilog.</a> (initial commit, so this is a bit noisy)</li>
<li><a href="https://github.com/arggrande/SerilogPoC/commit/a57139df2ead6f1b8199173f5128479b4a0958b2">Added ILogger injection via Autofac, with request correlation via SerilogWeb.Classic</a></li>
<li><a href="https://github.com/arggrande/SerilogPoC/commit/5d7b765f9c266bdebe0bee7a2bae4732c18ae646">Demonstrate use of SelfLog to output Serilog internal exceptions, using a bad Seq URL.</a></li>
<li><a href="https://github.com/arggrande/SerilogPoC/commit/7e2a5a06cbc7913b762631b2a00eb493db4328c8">Added in a demonstration of the use of ContextProperties, with Destructuring example.</a></li>
</ol>
<p>So if you're playing along at home, you can check out each of the specific commits to see how the code was running at that point at in time. Well... here we go!</p>
<h4 id="initialsetupandinstallation">Initial setup and installation</h4>
<p>To install Seq, simply go <a href="https://getseq.net/Download">here</a> and download &amp; install the file. A default installation will be done in a flash, and you'll be up and running in no time. For Serilog, simply add the Serilog Nuget packages via <code>Install-Package Serilog</code> and <code>Install-Package Serilog.Sinks.Seq</code>. We'll add more, but those will come later.</p>
<h4 id="staticloggingconfigurationwithserilog"><a href="https://github.com/arggrande/SerilogPoC/tree/d4a51457e9430e4dd3c7cd4202d8ef1df9296bc6">Static Logging Configuration with Serilog</a></h4>
<p>Serilog's primary pattern for configuring itself is through the static property Log.Logger, in the Serilog namespace. Using this will let you use the static property <code>Log</code> throughout your classes, letting you output to Seq through <code>Information</code>, <code>Warning</code>, <code>Error</code> and <code>Fatal</code> methods.</p>
<p>Setting up a basic configuration is fairly easy:</p>
<pre><code>    Log.Logger = new LoggerConfiguration()
        .WriteTo.Seq(ConfigurationManager.AppSettings[&quot;SeqUrl&quot;])
        .CreateLogger();
</code></pre>
<p>This uses the concept of a <a href="https://github.com/serilog/serilog/wiki/Provided-Sinks">Sink</a>, this being an external representation of something, to write to Seq, for a given Seq Instance URL (in this case, I'm storing the URL in the web.config of the application). Serilog can be used for things other than Seq, so the amount of things it can write to is pretty amazing, and very handy.</p>
<p>Now, in our HomeController.cs file, we can log that the Index action is being hit successfully.</p>
<pre><code>    public ActionResult Index()
    {
        Log.Information(&quot;Invoking Index() Action&quot;);
        ViewBag.Title = &quot;Home Page&quot;;
        Log.Information(&quot;Finished Index() Action&quot;);
        return View();
    }
</code></pre>
<p>If we go to our Seq instance, we can see the method entries there:<br>
<img src="https://pendingtechnical.com/content/images/2016/11/seq1-1.png" alt="Basic Static configuration of Serilog"></p>
<p>So personally, I'm not a fan of static anything (in fact, there's an interesting situation further down in this post which highlights why static can be troublesome at times), so I wanted to see if I could inject the ILogger interface (Serilog's interface of choice) into my controllers, through the use of Autofac...</p>
<h4 id="iloggerinjectionviaautofac"><a href="https://github.com/arggrande/SerilogPoC/tree/a57139df2ead6f1b8199173f5128479b4a0958b2">ILogger Injection via Autofac</a></h4>
<p><sup>With the bonus addition of Request Correlation!</sup></p>
<p>Add the following Nuget packages to your solution, via the following:</p>
<ul>
<li><code>Install-Package Autofac</code></li>
<li><code>Install-Package Autofac.Mvc5</code></li>
<li><code>Install-Package AutofacSerilogIntegration</code></li>
<li><code>Install-Package SerilogWeb.Classic</code></li>
</ul>
<p>Once this is done, in the App_Start folder, create an IoCConfig.cs file. This is where we'll configure Autofac, Serilog and (bonus!) give Serilog Http Request correlation (so you can track http requests across the application).</p>
<p>There's a few new concepts with this stage, these being Serilog Enrichers, the Log Context, and how Serilog deals with Autofac.</p>
<p>Enrichers are classes that add extra information to the log entries. There are quite a few ways to do this, but for now we'll just focus on the basics. This works in close conjunction with the LogContext, which allows you to push properties to the context of the current Log item being pushed to Seq. The AutofacSerilogIntegration package provides an extension method used on the Autofac ContainerBuilder, for us to pass our logging implementation in.</p>
<p>SerilogWeb is a specific package that provides some enrichers that deal specifically with the Web side of things. This gives you out-of-the-box Http Request correlation on things like; Http Request Id, Session Id, UserNames and Request Trace Ids. If you want more information, head over to the GitHub <a href="https://github.com/serilog-web/classic">page</a>, and check it out.</p>
<pre><code>    public static class IoCConfig
    {
        private static IContainer Container { get; set; }
        public static void Configure()
        {
            var logger = new LoggerConfiguration()
                .Enrich.FromLogContext()
                .Enrich.With&lt;HttpRequestIdEnricher&gt;()
                .WriteTo.Seq(ConfigurationManager.AppSettings[&quot;SeqUrl&quot;])
                .CreateLogger();

            var builder = new ContainerBuilder();
            builder.RegisterLogger(logger);
            builder.RegisterControllers(typeof(WebApiApplication).Assembly);

            Container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
        }
    }
</code></pre>
<p>As you can see, things are starting to get a little meatier with this next step. We're calling the <code>.Enrich</code> property on the logger configuration class, asking Serilog to enrich all calls to Seq with the LogContext initially (so any changes we may want to make on the fly to the LogContext property will be used), and then we're specifying an out-of-the-box enricher from the SerilogWeb.Classic library, in the form of <code>HttpRequestIdEnricher</code>. This adds a <code>HttpRequestId</code> property to all calls to Seq.</p>
<p>After this, we're using Autofac to build our IoC container, and we're calling the extension method <code>RegisterLogger</code> and passing in our logger that we've configured above. This means that wherever we reference the <code>ILogger</code> Serilog Interface, Autofac will provide our logging configuration accordingly. Then we're registering the Controllers of our application, and setting the DependencyResolver, so things just Magically Work™.</p>
<p>Now, our controller changes slightly to the following:</p>
<pre><code>    public class HomeController : Controller
    {
        private readonly ILogger _logger;

        public HomeController(ILogger logger)
        {
            _logger = logger;
        }
        public ActionResult Index()
        {
            _logger.Information(&quot;Invoking Index() Action with injected logger&quot;);
            ViewBag.Title = &quot;Home Page&quot;;
            _logger.Information(&quot;Finished Index() Action with injected logger&quot;);
            return View();
        }
    }
</code></pre>
<p>If we build &amp; run the application, and check our Seq logs, we should have the following:<br>
<img src="https://pendingtechnical.com/content/images/2016/11/Seq2.png" alt="Successfully injected ILogger into our Application"></p>
<p>Success! We now have a nicely injected ILogger with which to Log to our hearts content! Thats the Dream™...</p>
<p>... At least until things go wrong!</p>
<h4 id="selflogandinternalserilogexceptions"><a href="https://github.com/arggrande/SerilogPoC/tree/5d7b765f9c266bdebe0bee7a2bae4732c18ae646">SelfLog and internal Serilog Exceptions</a></h4>
<p>I must admit, one of my bugbears with Serilog is the fact it <strong>silently fails</strong> if your configuration is invalid, or if something else goes wrong. It will swallow the exception, and you'll be left scratching your head as to why you cant get any log output. Thankfully, Serilog provides the <code>SelfLog</code> property to assist in troubleshooting when things go wrong.</p>
<p>The usage for SelfLog is fairly straightforward. Enable it, and give it an output to write to when it realises something has gone wrong. A simple example is outputting to the Debug output window.</p>
<pre><code>	Serilog.Debugging.SelfLog.Enable(msg =&gt; Debug.WriteLine(msg));
</code></pre>
<p>However, what I did for the commit linked above, was actually write the output to a text file:</p>
<pre><code>    var location = HttpRuntime.AppDomainAppPath;
    var file = File.CreateText(location + &quot;\\serilogexceptions.log&quot;);

    Serilog.Debugging.SelfLog.Enable(TextWriter.Synchronized(file));
</code></pre>
<p>Note the use of <code>TextWriter.Synchronized</code>, this is because the way SelfLog writes to the file by default isn't thread safe. Passing in your <code>TextWriter</code> to the <code>TextWriter.Synchronized</code> method ensures that Serilog writes to it in a safe manner.</p>
<p>To demonstrate this, I changed the <code>SeqUrl</code> application setting to an invalid url. Run the application and you should get something similar to the following:</p>
<p><img src="https://pendingtechnical.com/content/images/2016/11/Seq3-1.png" alt="Serilog Internal Exceptions"></p>
<p>Overall, I don't like how Serilog handles this aspect of itself. I would rather it throw an error in your face (like EntityFramework and Autofac do, when you misconfigure them), to let you know something is wrong. It's not a <em>massive</em> thing, just my own opinion. (It's also possible there is a way to do this, I just haven't found it yet!)</p>
<p>Lastly, I want to talk about ContextProperties, and the amazing way in which Serilog destructures data for logging.</p>
<h4 id="contextpropertiesanddestructuringlogdata"><a href="https://github.com/arggrande/SerilogPoC/tree/7e2a5a06cbc7913b762631b2a00eb493db4328c8">Context Properties and Destructuring Log Data</a></h4>
<p>In the third section, around ILogger injection, you'll notice we added <code>.Enrich.FromLogContext</code> to our configuration of Serilog. This lets us see any associated properties that have been pushed to the LogContext, for the given call to Seq. Personally, I find this one of the most powerful parts of Serilog. It gives us a very fine-grained control around the amount of information we push out with a log entry into Seq, and using it is very simple:</p>
<pre><code>	LogContext.PushProperty(&quot;SomeProperty&quot;, &quot;SomeValue&quot;)
</code></pre>
<p>The PushProperty method returns an IDisposable, so you can use this to effectively scope how long the properties hang around for. This, taken straight from the Serilog <a href="https://github.com/serilog/serilog/wiki/Enrichment">wiki</a>, is a really good (contrived) example:</p>
<pre><code>log.Information(&quot;No contextual properties&quot;);

using (LogContext.PushProperty(&quot;A&quot;, 1))
{
    log.Information(&quot;Carries property A = 1&quot;);

    using (LogContext.PushProperty(&quot;A&quot;, 2))
    using (LogContext.PushProperty(&quot;B&quot;, 1))
    {
        log.Information(&quot;Carries A = 2 and B = 1&quot;);
    }

    log.Information(&quot;Carries property A = 1, again&quot;);
}
</code></pre>
<p>In my PoC application, I've added a very basic json file data store, with a sample file containing player information from <a href="http://store.steampowered.com/app/730/">Counter-Strike: Global Offensive</a>*, updated the Index view accordingly, and added a new Player view. I've scattered some logging throughout the HomeController, including when things potentially go wrong, to demonstrate the usefulness of ContextProperties.</p>
<pre><code>public class HomeController : Controller
{
    private readonly ILogger _logger;
    private readonly IPlayerService _playerService;

    public HomeController(ILogger logger, IPlayerService playerService)
    {
        _logger = logger;
        _playerService = playerService;
    }
    public ActionResult Index()
    {
        _logger.Information(&quot;Attempting to load all players.&quot;);
        ViewBag.Title = &quot;Home Page&quot;;

		var players = _playerService.GetPlayers();

        if(players.Count &gt; 0)
        	_logger.Information(&quot;Found players&quot;);

        return View(players);
    }

    public ActionResult Player(string alias)
    {
        _logger.Information(&quot;Attempting to find player {alias}.&quot;, alias);
        var player = _playerService.GetPlayer(alias);
        if (player == null)
        {
            using (LogContext.PushProperty(&quot;PlayerCount&quot;, _playerService.GetPlayers().Count))
            _logger.Warning(&quot;Player {alias} not found. Valid players include: {players}&quot;, alias, _playerService.GetPlayers());

            _logger.Information(&quot;Redirecting to Index Action&quot;);
            return RedirectToAction(&quot;Index&quot;);
        }

        _logger.Information(&quot;Player with alias {alias} found, with name {name}&quot;, alias, player.Name);
        return View(player);
	}
}
</code></pre>
<p>There's a few things going on here. Initially, we're just logging informational entries to Seq, tracking when we hit the Index action, and that we've found some players to list.</p>
<p>When we try and hit the Player action, we log an informational entry to Seq, using handlebars in the message: <code>_logger.Information(&quot;Attempting to find player {alias}.&quot;, alias);</code>  then passing the alias we are attempting to search for as the next argument.</p>
<p>This is where Serilog appends a new <code>alias</code> property to the log entry, and gives it a value of the next paramter passed in (in this case, our <code>alias</code> parameter on the action). Next, we actually try and retrieve the player from the PlayerService. If we don't find it, we log a <code>Warning</code> with Serilog, passing in the <code>alias</code>, and a <code>players</code> object as the second paramter.</p>
<p>I honestly think this part is pretty cool. Now, Serilog takes the structured data you've passed in, destructures it and appends it as a property on the log entry, storing it as raw json! We're also adding a new <code>ContextProperty</code> called <code>PlayerCount</code>, so if we were calling off to another external service, the <code>PlayerCount</code> property would be passed to the context of any inner calls to the ILogger interface.</p>
<p>If we run the application, view a player, and attempt to find an invalid player, you should see the following in your logs:<br>
<img src="https://pendingtechnical.com/content/images/2016/11/Seq4.png" alt="More logging with context properties and destructuring of log data"></p>
<p>See the yellow circle in one of the log entries? This is the <code>Warning</code> signal recognised by Seq. Seq gives you the ability, on the right of that screenshot, to filter by different signals, which can be handy when you're in a hurry and need a quick filtered view of what's going on.</p>
<p>ContextProperties and Serilog destructuring are incredibly powerful tools at our disposal when interacting with Seq, and adding logging to our applications. I think it gives us a level of control and flexibility over our logging that, to be honest, I haven't seen elsewhere.</p>
<h4 id="gotchas">Gotchas</h4>
<p>As is ever the case with any library, there are some Gotchas. The investigations I mentioned at the start of this post revolved around the conflicting configuration of Serilog itself. Because Serilog can be configured statically, it means that you can potentially have other sources modifying the configuration silently. We had an internal Nuget package attempting to configure its own Serilog configuration, which was throwing off our main configuration in the web application. This lead to some head-scratching as I was trying to figure out why my ContextProperties weren't being written at the times I expected. If you run into a similar situation, I <em>think</em> the best way of handling it would be to have the internal Nuget package expose a way to be given a logging configuration. I do believe the Autofac registrations also provide a slightly different way of solving this scenario, as you could use Modules for the internal package to provide its <em>own</em> logging configuration at registration time (however feel free to hit me up on <a href="https://twitter.com/arggrande">Twitter</a> if you think I'm wrong, or you have a better way!).</p>
<h4 id="wrappingup">Wrapping up</h4>
<p>And that's a wrap! Delving into Serilog has been quite interesting, and hopefully you've enjoyed reading this post as much as I've enjoyed writing it! I also hope this post has effectively demonstrated how darn <em>useful</em> Serilog and Seq are when used in conjunction with each other.</p>
<p><sup>* If you're wondering 'Adam did you just contrive a situation so you could reference Counter-Strike in a technical blog post?' Yes. Yes I did :) </sup></p>
<h5 id="usefullinks">Useful Links</h5>
<ul>
<li><a href="https://github.com/serilog/serilog/wiki">Serilog Documentation</a></li>
</ul>
<p>Edit: 15/6/2017 - Silly me had <code>Add-Package</code> instead of <code>Install-Package</code> :(</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[iisreset]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr - I restart everything I can, all the time, because I don't trust computers, software, hardware, firmware or networking.</p>
</blockquote>
<p>This is a blog post I've been wanting to write for a long time, probably about a year or so, give or take a few months.  I've been in</p>]]></description><link>https://pendingtechnical.com/iisreset/</link><guid isPermaLink="false">5cb1a21af4a648698ea01361</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Mon, 31 Oct 2016 02:08:19 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><blockquote>
<p>tl;dr - I restart everything I can, all the time, because I don't trust computers, software, hardware, firmware or networking.</p>
</blockquote>
<p>This is a blog post I've been wanting to write for a long time, probably about a year or so, give or take a few months.  I've been in software development for almost 10 years now (and consulting for most of that), and as such I've seen a lot of crazy stuff. Things that don't make sense, things that are just plain hilarious (once I've calmed down from unspeakable rage), and things that defy the very <em>fabric</em> of what we consider reality. There's a reason one of my all-time favourite blog posts is called <a href="https://www.stilldrinking.org/programming-sucks">'Programming Sucks'</a>. So at this point you might be thinking &quot;oh, this is just another jaded software developer ranting about about software&quot;. Congratulations, that's exactly what this post is! :D Basically, venting is good for the soul, and this post represents my attempt at venting my anger and frustration in a semi-lighthearted manner. So... I'm going to say something I've been wanting to say for the longest time...</p>
<p>I don't trust computers. At all.</p>
<p>Ahhh, that certainly is theraputic. Now you might be thinking &quot;Adam, you're in software development! You look and stare at computers all day every day, and bash on the keyboard  eventually hoping something will work!&quot;. Yes... yes, right you are! But bear with me, dear reader. There is a method to my madness.</p>
<p>Its possible at this point, you've looked at the title, and wondering if I've made some sort of mistake, I haven't. For any computer or server with IIS installed, <code>iisreset</code> is the command that restarts IIS. In web development, a lot of the time I'm having to deal with IIS and its various shenanigans, so the choice of <code>iisreset</code> as the title of this blog post is a very deliberate choice.</p>
<p>IIS has what is called 'Application Pools', that serve as containers for the process that your website is running under, and for the most part, they work very well. If you've made a particular type of change to your website, and you deploy it, all you need to (theoretically) do is recycle the Application Pool and ta-da! The server reloads the fresh files/DLLs into memory and your websites are now happily churning along on the latest incarnation of your website.</p>
<p>That is, until, things go horribly wrong.</p>
<p>I've been burnt many, many times by servers/computers that don't necessarily behave as they should. One of the most frustrating things that happens in the above situation is for, whatever reason, something goes wrong in the internals of IIS and recycling the Application Pool doesnt have <em>quite</em> the effect you'd expect and you're left scratching your head for several hours while you troubleshoot various things, with a slow descent into madness.</p>
<p>For developers (for me at least), there are few things worse than simple things that <em>should</em> work, but don't. Which is why my default, when changing anything to do with a website, is to restart IIS itself, through the glories of <code>iisreset</code>, as opposed to relying on the Application Pool to recycle properly (keep in mind, I'm talking mostly local development with this post). This will flush out whatever garbage has been caught on the inner gears of IIS internals, and usually this avoids any head-banging troubleshooting.</p>
<p>Now most developers at this point will be laughing at me, and I <em>completely</em> understand why. Most of the time, recycling the Application Pool works perfectly well, and restarting IIS just for something simple is definitely a sledgehammer meets nail sort of thing. But they haven't seen the things I've seen. Restarting IIS, for most of the situations I've dealt with so far, is a fairly quick process. That extra second I use in restarting IIS itself, rather than relying on the Application Pool, saves me from those times where I spend half a day scratching my head trying to figure out what's gone wrong, when nothing has actually gone wrong, its just IIS having a moment. I don't trust Application Pools. I don't trust IIS. I will use whatever tools are at my disposal to minimise the risk of something completely damn <em>crazy</em> ruining my day.</p>
<p>BizTalk is another platform where this sort of mentality can pay off in spades. BizTalk has a habit of holding things from the GAC in memory, so if you're not careful you can get into <em>a lot</em> of trouble with a rogue DLL hanging around where you didn't expect, or when BizTalk itself is having a moment. For most things when I'm dealing with BizTalk I will restart the Host Instance itself after making a change, because I don't trust BizTalk. And I'd rather take the extra 3 seconds restarting the Host Instance than having to deal with the black box that is BizTalk (and I'm fairly sure any BizTalk dev reading this right now will be emphatically nodding yes at the screen). Once, somehow the underlying XML of an <em>orchestration shape</em> got corrupted to the point where it completely broke the subscription it was listening for... The fix? Delete the shape, and re-add it. Bam. Fixed. This is why I don't trust BizTalk.</p>
<p>This is why, for general development purposes, I take the attitude of:</p>
<blockquote>
<p>Restart everything you can, <em>all</em> the time. Nothing is sacred.</p>
</blockquote>
<p>Heck, if I see some weird things happening when I'm doing development, I will restart my damn PC at the drop of a hat. I don't trust my PC.</p>
<p>If it's a quick process to restart whatever you're dealing with, and strange things are happening, restart everything you can. Even if nothing eventuates from it, and nothing magically fixes itself, at the very least you can rule out some of the crazier stuff that can happen in the world of software development.</p>
<p>There's a reason this <a href="https://www.youtube.com/watch?v=nn2FB1P_Mn8">quote</a> resonates so strongly (and hilariously) in the IT world.</p>
<p>If you've made it this far, dear reader, I salute you. Thankyou for taking the time to listen to my ranting :)</p>
<p><strong>Update</strong>: A colleague gave me some very valuable feedback, saying that I was potentially advocating this sort of method on a production environment. After re-reading the post I could see his point, so I thought I'd jump back in and clarify: This is definitely <em>not</em> the recommended way of dealing with production issues. You should have sufficient instrumentation, logging and monitoring in place to figure out what's going if you're seeing strange things. Restarting a production server should be the very, very, <em>very</em> last thing you attempt in fixing issues. Thar be Dragons!</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[BizTalk and the Dreaded No Subscribers Found Message]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>At some point, everyone who's ever worked on a BizTalk application will encounter the &quot;The published message could not be routed because no subscribers were found&quot; error message. Like most BizTalk error messages, this can be caused by a variety of things. Your Send Ports might be listed,</p>]]></description><link>https://pendingtechnical.com/biztalk-and-the-dreaded-no-subscribers-found/</link><guid isPermaLink="false">5cb1a21af4a648698ea01360</guid><category><![CDATA[biztalk]]></category><category><![CDATA[troubleshooting]]></category><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Mon, 12 Oct 2015 09:40:35 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>At some point, everyone who's ever worked on a BizTalk application will encounter the &quot;The published message could not be routed because no subscribers were found&quot; error message. Like most BizTalk error messages, this can be caused by a variety of things. Your Send Ports might be listed, your Receive Shapes on the Orchestrations you've created might have an incorrect filter, or you simply might have forgotten about the filter completely.</p>
<p>Today's issue however, was none of those things. After going through and checking my Send and Receive Ports, double and triple checking my filter expressions, and even getting a Real BizTalk Person™ to sanity check what was going on, we were stumped.</p>
<p>In the course of googling that error because (because Developers™), I stumbled across a suggestion to check the actual recognised Subscriptions that had been deployed to BizTalk itself, from the Group Management console.</p>
<p>The Subscriptions in a given BizTalk environment can be accessed by creating a new query in the Group Management Console, and changing the &quot;Search For&quot; value to &quot;Subscriptions&quot; (and any other filters you might want), and clicking &quot;Run Query&quot;. This returns a complete list of Subscriptions associated with the various BizTalk applications installed on the server, so anything that is responsible for creating a Subscription in BizTalk can be viewed here. Like, for instance, a Receive Message shape behaving badly.</p>
<p>In my instance, I'd had to change the filters and schema type on my Receive Shape at some point, as I'd realised that the schema being used was incorrect. On changing it to the correct values, it had somehow <strong>corrupted</strong> the Receive Shape on the designer, and had spat out an incorrect filter expression when creating the Subscription in BizTalk. So, I deleted and re-added the Recieve Shape, hooked it back up the MessageBox, and on deploying the changed Orchestration, it re-created the Subscription with the correct filter expressions. Huzzah!</p>
<p>Hope this helps some other poor developer out there dealing with the same issue :)</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Debugging and the Modules Window]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Its very easy to forget how bloody <em>large</em> Visual Studio can be, whatever the incarnation. Every now and then, you'll stumble across something that just makes you think &quot;damn, thats pretty cool&quot;, and wonder why you didn't know about it sooner. Yesterday, I had one of those times.</p>]]></description><link>https://pendingtechnical.com/debugging-and-the-modules-window/</link><guid isPermaLink="false">5cb1a21af4a648698ea0135f</guid><category><![CDATA[debugging]]></category><category><![CDATA[visual-studio]]></category><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Wed, 30 Sep 2015 13:19:39 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Its very easy to forget how bloody <em>large</em> Visual Studio can be, whatever the incarnation. Every now and then, you'll stumble across something that just makes you think &quot;damn, thats pretty cool&quot;, and wonder why you didn't know about it sooner. Yesterday, I had one of those times. It was just a small thing, but I think its changed how I'll be debugging applications from this point forward, especially tricky components that dont always play nice with the debugger out the box (I'm looking at you, shonky legacy ActiveX controls).</p>
<p>I was in the process of wrestling with a custom BizTalk Pipeline Component, trying to figure out why the hell I was getting some really random issues while <em>trying</em> to debug my component. There's also a blog post there, but I wanted to share this first.</p>
<p>I came across an article (and, stupid me, didn't bookmark it at the time) that showed you how to load specific debug symbols during debugging. If you weren't aware of it, this is called the &quot;Modules&quot; window in Visual Studio, and seems to be in all of the versions from 2010 to 2015. To get to it, start debugging your application, and hit a breakpoint <em>somewhere</em>, just so you get it to break. If you then go to the Debug Menu, and select Windows -&gt; Modules, you'll get a shiny little view which shows all the DLLs currently in scope! It also lists the path the <em>specific</em> DLL, so where it's actually being referenced from, and similar columns for the symbols files. How did I not know about this sooner!?</p>
<p><img src="https://pendingtechnical.com/content/images/2015/09/Modules-Window-1.png" alt="Modules Window"></p>
<p>From here, you can right click on the offending DLL that isn't loading the symbols you expect, and actually navigate to a PDB file, and attempt to load them from there. An interesting thing to note is, that if you get an error about a mismatch  between the files, it means the PDB file is out of sync with the DLL you're currently debugging (or, obviously, it's the incorrect PDB file for the DLL!). In my case, this was because the DLL was being loaded from the GAC (ugh, thanks BizTalk), rather than the local DLL in my bin folder.</p>
<p>Another interesting thing I discovered during this little adventure, was if you right click on a DLL, and click &quot;Symbol Load Information&quot;, it will show a screen that shows all the <em>possible</em> places it's trying to look for the PDB files!</p>
<p><img src="https://pendingtechnical.com/content/images/2015/09/Symbol-Load-Information.png" alt="Symbol Information"></p>
<p>So if you really wanted to, you could dump a whole bunch of PDB files in some specific system folders, and debugging should just work™.</p>
<p>Have a good night, and hope it helped (or at least reinforce what you already knew!) :)</p>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[A New Place To Call Home]]></title><description><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Better <a href="http://pendingtechnical.azurewebsites.net/a-new-style-of-blogging/">late</a> than never, right?</p>
<p>Its taken a while, but I've finally converted my WordPress to blog to Ghost. Ghost is an open source blogging platform, with a heavy focus on the content being created. Minimalistic (to my eyes, anyway), and lightning fast.</p>
<p>As I'm lucky enough to have an</p>]]></description><link>https://pendingtechnical.com/a-new-place-to-call-home/</link><guid isPermaLink="false">5cb1a21af4a648698ea0135e</guid><dc:creator><![CDATA[Adam Grande]]></dc:creator><pubDate>Sun, 28 Sep 2014 10:46:56 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><!--kg-card-begin: markdown--><p>Better <a href="http://pendingtechnical.azurewebsites.net/a-new-style-of-blogging/">late</a> than never, right?</p>
<p>Its taken a while, but I've finally converted my WordPress to blog to Ghost. Ghost is an open source blogging platform, with a heavy focus on the content being created. Minimalistic (to my eyes, anyway), and lightning fast.</p>
<p>As I'm lucky enough to have an MSDN subscription, I've hosted my website on Azure, where I get free credits each month, which can be used towards any of the bajillions (yes, a Real™ unit of measurement) features available.</p>
<blockquote>
<p>If you want to host a website on Azure, you can too! If you sign up for the Azure Trial, you get 10 websites for free, which run an amazing range of platforms/techs. <a href="http://azure.microsoft.com/en-us/services/websites/">Check it out here!</a>.</p>
</blockquote>
<p>One of the most amazing features that Ghost supports, is the use of Markdown within its posts. Think of Markdown as like a short-hand formatting mini-language. Putting in a new heading is as easy as typing &quot;#My Heading&quot;. In short, its <em>amazing</em>.</p>
<blockquote>
<p>On Azure, you can also spin up a pre-made Ghost Website, without any of the <s>messy</s> fun stuff I had to do to get it working.</p>
</blockquote>
<p>I'm not going to bother going into the steps I took to get it up and running, as others have already covered it many times, all in excellent details <a href="http://www.hanselman.com/blog/HowToInstallTheNodejsGhostBloggingSoftwareOnAzureWebsites.aspx">Scott Hanselman's</a> site is where I found the most helpful content around the Azure-related commands, for use when wanting to create websites on the fly, on Azure itself (it's awesomely simple!). And for the actual meat &amp; bones of the site itself (generating the <em>correct</em> JavaScript/Styles/Dependencies etc), I used a post on one <a href="http://www.jbillmann.com/installing-ghost-on-azure-web-sites/">Jeremiah Billmann's</a> website. I found Jeremiah's post to be a bit more helpful, as I was running into issues with Scott's around the Grunt initialization (though in retrospect, it was most likely a <a href="http://en.wikipedia.org/wiki/User_error#PEBCAK">PEBKAC</a> issue). One very important lesson learned, is that all of the grunt/npm commands should be run in the <em>same</em> folder as where your Ghost site is located. If not, things will not install correctly (or at all!) and you will be scratching your head wondering where it all went wrong.</p>
<p>The other awesome thing with the above two links is that both deal with deploying to Azure from a Git repository. Make some changes, commit, and push to the Azure Git remote (think of it as a staged location) that Scott's post will add for you (or you can add yourself, using the guide in Jeremiah's post), and Azure will automatically pick it up, check it and deploy it.</p>
<p>It's bloody <strong>Magic™</strong>.</p>
<p>I've also used a nifty little tool, called <a href="https://www.npmjs.org/package/wp2ghost">&quot;wp2ghost&quot;</a>, to convert my posts from WordPress' XML format, to the JSON format that Ghost is expecting.</p>
<p>To export the posts from WordPress, go to the WordPress Dashboard, go Tools -&gt; Export, and then click &quot;Export&quot;, which will start a file download containing the content of your blog (images included!).</p>
<blockquote>
<p>Note: If you are currently self-hosting your WordPress blog, you can do this much quicker with the <a href="https://wordpress.org/plugins/ghost/">Ghost Plugin</a> for WordPress. Install the plugin, and click 'Export', and that's it. The steps below are not required.</p>
</blockquote>
<p>Go to the <a href="https://www.npmjs.org/package/wp2ghost">wp2ghost</a> page, and download the zip file. Extract it somewhere.</p>
<p><strong>A Gotcha:</strong> There is an issue with the package.json file in wp2ghost, where the version number in the package.json file (what the NodeJS Package Manager uses to resolve dependencies for the package), is invalid, as NPM uses a <a href="http://semver.org/">semantic versioning</a> scheme, expecing 3 lots of numbers.</p>
<p>Open the package.json file, and change the version value from &quot;0.0.3.4&quot; to &quot;0.3.4&quot; and save it. Then run...</p>
<pre><code>npm install
</code></pre>
<p>...from the NodeJS Command Prompt, in the location you've extracted the wp2ghost utility, it will magically (not magically, but you know what I mean) resolve the dependencies it needs.</p>
<p>After this, copy your exported WordPress XML file to the wp2ghost installation directory and, using the NodeJS Command Prompt, run:</p>
<pre><code>node wp2ghost [yourfile].xml
</code></pre>
<p>As my very first contrubution to the open source community, I've fixed the package.json file and sent a <a href="https://github.com/xna2/wp2ghost/pull/3">Pull Request</a> to the project's creator. Exciting!</p>
<p>Now that's all taken care of, to import the file into your Ghost website, it's a simple matter of going to:</p>
<pre><code>http://[yourghostblog.com]/ghost/debug
</code></pre>
<p>And from the file picker displayed there, import the file and its all done (images included, which still boggles my puny mind!).</p>
<p>So there you have it! My journey from WordPress to Ghost has been fun, and I hope this helps anyone looking to make the same move.</p>
<p>Good luck! Ping me on <a href="http://twitter.com/arggrande">Twitter</a> if you have any questions or comments :)</p>
<p>Other useful links...</p>
<ul>
<li><a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet">Markdown Cheat Sheet</a></li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>