Monday, 7 August 2017

Generating self-signed HTTPS certificates with subjectAltNames

We provide online services via a bunch of different websites, using federated authentication so that if you sign in to our authentication server, you get a *.mydomain.com cookie that’s sent to any other server on our domain.

We use local wildcard DNS, so there’s a *.mydomain.com.local record that resolves everything to 127.0.0.1, and for each developer machine we create a  *.mydomain.com.hostname record that’s an alias for hostname, so you can browse to www.mydomain.com.<machine> to see code running on another developer’s workstation, or www.mydomain.com.local to view your own local development code.

This works pretty well, but getting a local development system set up involves running local versions of several different apps – and since Google Chrome now throws a security error for any HTTPS site whose certificate doesn’t include a “subject alternative name” field, getting a bunch of local sites all happily sharing the same cookies over HTTPS proved a bit fiddly.

So… here’s a batch file that will spit out a bunch of very useful certificates, adapted from this post on serverfault.com.

How it works

  1. Get openssl.exe working - I use the version that's shipped with Cygwin, installed into C:\Windows\Cygwin64\bin\ and added to my system path.
  2. Run makecert.bat. If you don't want to specify a password, just provide a blank one (press Enter). This will spit out three files:
    • local_and_hostname.crt
    • local_and_hostname.key
    • local_and_hostname.pfx
  3. Double-click the local_and_hostname.crt file, click "Install Certificate", and use the Certificate Import Wizard to import it. Choose "Local Machine" as the Store Location, and "Trusted Root Certification Authorities" as the Certificate Store.
  4. Open IIS, select your machine, open "Server Certificates" from the IIS snapin, click "Import..." in the Actions panel
  5. Select the local_and_hostname.pfx certificate created by the batch file. If you used a password when exporting your PKCS12 (.pfx) file, you'll need to provide it here
  6. Finally, set up your IIS HTTPS bindings to use your new certificate.

Yay! Security! 

Monday, 31 July 2017

Deployment Through the Ages

Vanessa Love just posted this intriguing little snippet on Twitter:

And I got halfway through sticking some notes into the Google doc, and then thought actually this might make a fun blog post. So here’s how deployment has evolved over the 14 years since I first took over the hallowed mantle of [email protected].

2003: Beyond Compare (maybe?)

The whole site was classic ASP – no compilation, no build process, all connection credentials and other settings were managed as application variables in the global.asa file. On a good day, I’d get code running on my workstation, test it in our main target browsers, and deploy it using a visual folder comparison tool. It might have been Beyond Compare; it might have been something else. I honestly can’t remember and the whole thing is lost in the mists of time. But that was basically the process – you’d have the production codebase on one half of your screen and your localhost codebase on the other half, and you’d cherry-pick the bits that needed to be copied across.

Of course, when something went wrong in production, I’d end up reversing the process – edit code directly on live (via UNC share), normally with the phone wedged against my shoulder and a user on the other end; fix the bug, verify the user was happy, and then do a file sync in the other direction to get everything from production back onto localhost. Talk about a tight feedback loop – sometimes I’d do half-a-dozen “deployments” in one phone call. It was a simpler time, dear reader. Rollback plan was to hammer Ctrl-Z until it’s working again; disaster recovery was tape backups of the complete source tree and database every night, and the occasional copy’n’paste backup of wwwroot before doing something ambitious.

Incidentally, I still use Beyond Compare almost daily – I have it configured as my merge tool for fixing Git merge conflicts. It’s fantastic.

2005: Subversion

Once we hired a second developer (hey Dan!) the Beyond Compare approach didn’t really work so well any more, so we set up a Subversion server. You’d get stuff running on localhost, test it, maybe share an http://www.spotlight.com.dylan-pc/ link (hooray for local wildcard DNS) so other people could see it, and when they were happy, you’d do an svn commit, log into the production web server (yep, the production web server – just the one!) and do an svn update. That would pull down the latest code, update everything in-place. There was still the occasional urgent production bugfix. One of my worst habits was that I’d fix something on production and then forget to svn commit the changes, so the next time someone did a deployment (hey Dan!) they’d inadvertently reintroduce whatever bug had just been fixed and we’d get upset people phoning up asking why it was broken AGAIN.

2006: FinalBuilder

This is where we start doing things with ASP.NET in a big way. I still dream about OnItemDataBound sometimes… and wake up screaming, covered in sweat. Fun times. The code has all long since been deleted but I fear the memories will haunt me to my grave.

Anyway. By this point we already had the Subversion server, so we had a look around for something that would check out and compile .NET code, and went with FinalBuilder. It had a GUI for authoring build pipelines and processes, some very neat features, and could deploy .NET applications to IIS servers. This was pretty sophisticated for 2006. 

2008: test server and msdeploy

After one too many botched FinalBuilder deployments, we decided that a dedicated test environment and a better deployment process might be a good idea. Microsoft had just released a preview of a new deployment tool called MSDeploy, and it was awesome. We set up a ‘staging environment’ – it was a spare Dell PowerEdge server that lived under my desk, and I’d know when somebody accidentally wrote an infinite loop because I’d hear the fans spin up. We’d commit changes to Subversion, FinalBuilder would build and deploy them onto the test server, we’d give everything a bit of a kicking in IE8 and Firefox (no Google Chrome until September 2008, remember!) and then – and this was magic back in 2008 – you’d use msdeploy.exe to replicate the entire test server into production! Compared to the tedious and error-prone checking of IIS settings, application pools and so on, this was brilliant. Plus we’d use msdeploy to replicate the live server onto new developers’ workstations, which was a really fast, easy way to get them a local snapshot of a working live system. For the bits that still ran interpreted code, anyway.

2011: TeamCity All The Things!

By now we had separate dev, staging and production environments, and msdeploy just wasn’t cutting it any more. We needed something that can actually build different deployments for each environments – connection strings, credentials, and so on. And there’s now support in Visual Studio for doing XML configuration transforms, so you create a different config file for every environment, check those into revision control, and get different builds for each environment. I can’t remember exactly why we abandoned FinalBuilder for TeamCity, but it was definitely a good idea – TeamCity has been the backbone of our build process ever since, and it’s a fantastically powerful piece of kit.

2012: Subversion to GitHub

At this point, we’d grown from me, on my own doing webmaster stuff, to a team of about six developers. Even Subversion is starting to creak a bit, especially when you’re trying to merge long-lived branches and getting dozens of merge conflicts, so we start moving stuff across to GitHub. It takes a while – I’m talking months – for the whole team to stop thinking of Git as ‘unnecessarily complicated Subversion’ and really grok the workflow, but we got there in the end.

Our deployment process at this point was to commit to the Git master branch, and wait for TeamCity to build the development version of the package. This would get built and deployed. Once it was tested, you’d use TeamCity to build and deploy the staging version – and if that went OK, you’d build and deploy production. Like very step on this journey, it was better than anything we’d had before, but had some obvious drawbacks. Like the fact we had several hundred separate TeamCity jobs and no consistent way of managing them all.

2013: Octopus Deploy and Klondike

When we started migrating from TeamCity 6 to TeamCity 7, it became rapidly apparent that our “build everything several times” process… well, it sucked. It was high-maintenance, used loads of storage space and unnecessary CPU cycles, and we needed a better system.

Enter Octopus Deploy, whose killer feature for us was the ability to compile a .NET web application or project into a deployment NuGet package (an “octopack”), and then apply configuration settings during deployment. We could build a single package, and then use Octopus to deploy and configure it to dev, staging and live. This was an absolute game-changer for us. We set up TeamCity to do continuous integration, so that every commit to a master branch would trigger a package build… and before long, our biggest problem was that we had so many packages in TeamCity that the built-in NuGet server started creaking.

This started life as an experimental build of themotleyfool/NuGet.Lucene – which we actually deployed onto a server we called “Klondike” (because klondike > gold rush > get nuggets fast!) – and it worked rather nicely. Incidentally, that NuGet.Lucene library is now the engine behind themotleyfool/Klondike, a full-spec NuGet hosting application – and I believe our internal hostname was actually the inspiration for their project name. That was a lot of fun for the 18 months or so that Klondike existed but we were still running the old NuGet.Lucene codebase on a server called ‘klondike’. It’s OK, we’ve now upgraded it and everything’s lovely.

It was also in 2013 that we started exploring the idea of automatic semantic versioning – I wrote a post in October 2013 explaining how we hacked together an early version of this. Here’s another post from January 2017 explaining how it’s evolved. We’re still working on it. Versioning is hard.

And now?

So right now, our build process works something like this.

  1. Grab the ticket you’re working on – we use Pivotal Tracker to manage our backlogs
  2. Create a new GitHub branch, with a name like 12345678_fix_the_microfleems – where 12345678 is the ticket ID number
  3. Fix the microfleems.
  4. Push your changes to your branch, and open a pull request. TeamCity will have picked up the pull request, checked out the merge head and built a deployable pre-release package (on some projects, versioning for this is completely automated)
  5. Use Octopus Deploy to deploy the prerelease package onto the dev environment. This is where you get to tweak and troubleshoot your deployment steps.
  6. Once you’re happy, mark the ticket as ‘finished’. This means it’s ready for code review. One of the other developers will pick it up, read the code, make sure it runs locally and deploys to the dev environment, and then mark it as ‘delivered’.
  7. Once it’s delivered, one of our testers will pick it up, test it on the dev environment, run it past any business stakeholders or users, and make sure we’ve done the right thing and done it right.
  8. Finally, the ticket is accepted. The pull request is merged, the branch is deleted. TeamCity builds a release package. We use Octopus to deploy that to staging, check everything looks good, and then promote it to production.

And what’s on our wishlist?

  • Better production-grade smoke testing. Zero-footprint tests we can run that will validate common user journeys and scenarios as part of every deployment – and which potentially also run as part of routine monitoring, and can even be used as the basis for load testing.
  • Automated release notes. Close the loop, link the Octopus deployments back to the Pivotal tickets, so that when we do a production deployment, we can create release notes based on the ticket titles, we can email the person who requested the ticket saying that it’s now gone live, that kind of thing.
  • Deployments on the dashboards. We want to see every deployment as an event on the same dashboards that monitor network, CPU, memory, user sessions – so if you deploy a change that radically affects system resources, it’s immediately obvious there might be a correlation.
  • Full-on continuous deployment. Merge the PR and let the machines do the rest.

So there you go – fourteen years worth of continuous deployments. Of course, alongside all this, we’ve moved from unpacking Dell PowerEdge servers and installing Windows 2003 on them to running Chef scripts that spin up virtual machines in AWS and shut them down again when nobody’s using them – but hey, that’s another story.

Thursday, 27 July 2017

Securing Blogger with CloudFlare and HTTPS

As you may have read, life is about to get a whole lot harder for websites without HTTPS. Now this site is hosted on Blogger – I used to run my own MovableType server, but I realised I was spending way more time messing around with the software than I was actually writing blog posts, so I shifted the whole thing across to Blogger about a decade ago and never really looked back.

One of the limitations of Blogger is that it doesn’t support HTTPS if you’re using custom domains – there’s no way to install your own certificate or anything. So, since Chrome’s about to crank up the warnings for any websites that don’t use HTTPS, I figured I ought to set something up. Enter CloudFlare, who are really rather splendid.

First, you sign up. (bonus points for them NOT forcing you to choose a password that contains a lowercase letter, an uppercase letter, a number, a special character, the poo emoji and the Mongolian vowel separator).

Second, you tell them which domain you want to protect:

image

They scan all your DNS records, which takes about a minute – and not only is there a nice real-time progress bar keeping you in the loop, they use this opportunity to play a really short video explaining what's going on. I think this is absolute genius.

image

Finally, after checking it's picked up all your DNS records properly (it had), you tell your domain registrar to update the nameservers for your domain to CloudFlare's DNS servers, give it up to 24 hours, and you're done. Zero downtime, zero service interruption – the whole thing was smooth, simple, and completely free-as-in-beer.

Yes, I realise this does not encrypt content end-to-end. For what we're doing here, this is absolutely fine. It'll secure your traffic against dodgy hotel wi-fi and unscrupulous internet service providers - and if anyone's genuinely intercepting HTTP traffic between CloudFlare and Google, I'm sure they can think of more exciting things to do with it than mess around with my blog posts.

Having done that, I then had to use the Google Chrome console to track down the resources – photos and the odd bit of script – that were being hosted via HTTP, and update them to be HTTPS. The only thing I couldn't work out how to fix was the search bar that's embedded in Blogger's default page layout – it's injected by JavaScript, it's hosted by Google's CDN (so I can't use any of CloudFlare's clever rewriting tricks to fix it), it's stuck inside an IFRAME, and it points to http://www.dylanbeattie.net/search – see the plain HTTP with no S?

image

After an hour or so of messing around with CSS, I gave up, posted a question on the ProWebmasters Stack Exchange, and – of course, immediately found the solution; go into Blogger, Layout, find the Navbar gadget, click Edit, and there's an option to switch the nav off entirely.

So there you go. Thanks to CloudFlare, https://www.dylanbeattie.net/ now has a green padlock on it. I don't know about you, but I take comfort in that.

image

Friday, 21 July 2017

Summer 2017 .NET Community Update

Summer here in the UK is normally pretty quiet, but this year there's so much going on around .NET and the .NET community that I thought this would be a great opportunity to do a bit of a round-up and let you all know about some of the great stuff that's going on.

First, there's the news of two new .NET user groups starting up in southern England. Earlier this week, I was down in Bournemouth speaking at the first-ever meetup of the new .NET Bournemouth group, and thoroughly enjoyed it. Three speakers – Stuart Blackler, Tommy Long and me – with talks on leadership, agile approaches to information security, and an updated version of my "happy code" talk I've done at a few conferences already this year. The venue and A/V setup worked flawlessly, there was a strong turnout, and some really good questions and discussion after each of the talks – I think it's going to turn out to be a really engaging group, so if you're in that part of the world, stop by and check them out. Their next few meetup dates are on meetup.com/Net-Bournemouth already.

Next month, Steve Gordon is starting a new .NET South East group based in Brighton, who will be kicking off with their inaugural meetup on August 22nd with Steve talking about Docker for .NET developers.

Brighton based .NET South East user group logo

There's a great post on Steve's blog explaining what he's doing and what he's hoping to get out of the group, and they're also on meetup.com/dotnetsoutheast (and I have to say, they've done an excellent job of branding the Meetup site – nice work!)

It's an exciting time for .NET – between the cross-platform stuff that's happening around Xamarin and .NET Core, new tooling like JetBrains Rider and Visual Studio Code, and the growing number of cloud providers who are supporting C# and .NET Core for building serverless cloud applications, we've come a long, long way from the days of building Windows Forms and databinding in Visual Studio .NET.

If you're interested in really getting to grips with the future of .NET, join us at the Progressive.NET Tutorials here in London in September. With a great line-up of speakers including Julie Lerman, Jon Skeet, Jon Galloway, Clemens Vasters and Rachel Appel – plus Carl Franklin and Rich Campbell from DotNetRocks, and a few familiar faces you might recognise from the London.NET gang – it promises to be a really excellent event. It goes a lot deeper than most conferences – with one day of talks and two days of hands-on workshops, the idea is that attendees don't just go away with good ideas, they actually leave with running code, on their laptops, that they can refer back to when they take those ideas back to the office or to their own projects. Check out the programme, follow #ProgNET on Twitter, and hopefully see some of you there. 

Then on Saturday 16th September – the day after Progressive.NET – is the fourth DDD East Anglia community conference in Cambridge. Their call for speakers is now closed, but voting is open until July 29th – so sign up, vote on the sessions you want to see – or just vote for mine if you can't make your mind up ;) - and hopefully I'll see some of you in Cambridge.

t_shirt_logo_thumb[23]Finally, just in case any readers of this blog DON'T know about the London .NET User Group… yep, we have .NET User Group! In London! I know, right? We're on meetup.com/London-NET-User-Group, and on Twitter as @LondonDotNet, and we meet every month at SkillsMatter's CodeNode building near Moorgate.

Our next meetup is on August 8th, with Ana Balica talking about the history and future of HTTP and HTTP/2, and Steve Gordon – and on September 12th we've got Rich Campbell joining us for a Progressive.NET special meetup and presenting the History of .NET as you've never heard it before.

New people, new meetups, new platforms and new ideas. Like I said, it's a really exciting time to be part of the .NET community – join us, come to a meetup, follow us online, and let's make good things happen.

Tuesday, 4 July 2017

Use Flatscreens

This started life as a lightning talk for PubConf after NDC in Sydney, back in August 2016… and after quite a lot of tweaking, editing and learning to do all sorts of fun things with Adobe AfterEffects and Premiere, it's finally on YouTube. The inspiration is, of course, "Wear Sunscreen", Baz Luhrmann's 1999 hit song based on an essay written by Mary Schmich. Video footage and stock photography is all credited at the end of the clip, and the music, vocals, video, audio and, well, basically everything else is by me. Happy listening - and don't forget to use flatscreens :)

Ladies and gentlemen of the class of 2017… use flat screens. If I could offer you only one tip for the future, flat screens would be it. The benefits of flat screens have been proved by Hollywood, whereas the rest of my advice has no basis more reliable than my own meandering experience.
 
I will dispense this advice... now.

Enjoy the confidence and optimism of greenfield projects. Oh, never mind. You will not appreciate the confidence and optimism of greenfield until everything starts going to hell. But trust me, when you finally ship, you'll look back at the code you wrote and recall in a way you can't grasp now how simple everything seemed, and how productive you really were. Your code is not as bad as you imagine.

Don't worry about changing database providers. Or worry, but know that every company who ever used an OR/M in case they needed to switch databases never actually did it. The real problems in your projects are the dependencies you don't control; the leaking air conditioner that floods your data centre at 5pm on the Thursday before Christmas.

Learn one thing every day that scares you.

Optimise.

Don't reformat other people's codebases; don't put up with people who reformat yours.

Rebase

Don't get obsessed with frameworks. Sometimes they help, sometimes they hurt. It's the user experience that matters, and the user doesn't care how you created it.

Remember the retweets you receive; forget the flame bait. If you succeed in doing this, tell me how.

Keep your old hard drives. Throw away your old network cards.

Refactor.

Don't feel guilty if you don't understand f#. Some of the most productive junior developers I've worked with didn't know F#. Some of the best systems architects I know still don't.

Write plenty of tests.

Be kind to your keys; you'll miss them when they're gone.

Maybe you have a degree; maybe you don't. Maybe you have an open source project; maybe you won't. Maybe you wrote code that flew on the Space Shuttle; maybe you worked on Microsoft SharePoint. Whatever you do, keep improving, and don't worry where your next gig is coming from. There's a big old world out there, and they're always going to need good developers.

Look after your brain. Don't burn out, don't be afraid to take a break. It is the most powerful computer you will ever own.

Launch, even if you have no users but your own QA team.

Have a plan, even if you choose not to follow it.

Do NOT read the comments on YouTube : they will only make you feel angry.

Cache your package dependencies; you never know when they'll be gone for good.

Read your log files. They're your best source of information, and the first place you'll notice if something's starting to go wrong.

Understand that languages come and go, and that it's the underlying patterns that really matter. Work hard to fill the gaps in your knowledge, because the wiser you get,  the more you'll regret the things you didn't know when you were young.

Develop in 86 assembler once, but stop before it makes you smug; develop in Visual Basic once, but stop before it makes you stupid.

Read.

Accept certain inalienable truths. Your code has bugs, you will miss your deadlines, and you, too, might end up in management. And when you do, you'll fantasize that back when you were a developer, code was bug-free, deadlines were met, and developers tuned their database indexes.

Tune your database indexes.

Don't deploy your code without testing it. Maybe you have a QA team. Maybe you have integration tests. You never know when either one might miss something.

Don't mess too much with your user interface, or by the time you ship, it will look like a Japanese karaoke booth.

Be grateful for open source code, but be careful whose code you run. Writing good code is hard, and open source is a way of taking bits from your projects folder, slapping a readme on them, and hoping if you put them on GitHub somebody else will come along and fix your problems.

But trust me on the flat screens.

Wednesday, 28 June 2017

Interview with Channel 9 at NDC Oslo

I was in Oslo earlier this month, where – as well as doing the opening keynote, a couple of talks, a workshop on hypermedia systems and PubConf – I had the chance to chat with Seth Juarez from Channel 9 about code, culture, speaking at conferences, and… all kinds of things, really.

The interview's here, or you can watch it over on Channel9.msdn.com - thanks Seth and co for taking the time to put this together!

Saturday, 13 May 2017

Interview with habrahabr.ru about HTTP APIs in .NET

Next week I'll be in Russia, where I'm speaking about HTTP APIs and REST at the DotNext conference in Saint Petersburg. As part of this event, I've done an interview with the Russian tech site Хабрахабр about the history and future of API development on the web and in Microsoft.NET. The interview's available on their site habrahabr.ru (in Russian), but for readers who are interested but can't read Russian, here's the original English version.


Cathedral in Saint Petersburg, Russia. goodfreephotos.com / Photo by DEZALB.

Q: What kind of APIs are you designing? Where does API design fit into software development?

That’s kind of an interesting question, because I think one of the biggest misconceptions in software is that designing APIs is an activity that happens separately to everything else. Sure, there are certain kinds of API projects – particularly things like HTTP APIs which are going to be open to the public – where it might make sense to consider API design as a specific piece of work. But the truth is that most developers are actually creating APIs all the time – they just don’t realise they’re doing it. Every time you write a public method on one of your classes or choose a name for a database table, you’re creating an interface – in the everyday English sense of the word – that will end up being used by other developers at some point in the future. Other people on your team will use your classes and methods. Other teams will use your data schema or your message format.

What’s interesting, though, is that once developers realize that the code they’re working on will probably form part of an API, they tend to go too far in the other direction. They’ll implement edge cases and things that they don’t actually need, just in case somebody else might need it later. I think there’s a very fine balance, and I think the key to that balance is to be very strict about only building the features that you need right now, but to make those things as reusable and self-explanatory as you can. There’s a great essay by Pieter Hintjens, Ten Rules for Good API Design, that goes into more detail about these kinds of ideas.

The biggest API project I’m working on at the moment is a thing I’m building at Spotlight in the UK, where I work. It’s a hypermedia API exposing information about professional actors, acting jobs in film and television, and various other kinds of data used in the casting industry. We’re building it in the architectural style known as REST – and if you’re not sure what REST is, you should come to my talk at DotNext in Saint-Petersburg and learn all about it. There’s lots of different patterns for creating HTTP APIs – there’s REST, there’s GraphQL, there’s things like SOAP and RPC – but for me, the biggest appeal of REST is that I think the constraints of the RESTful style lead to a natural decoupling of the concepts and operations that your API needs to support, which makes it easier to change things and evolve the API design over time.

Q: One of the most famous applications that was "killed" by backward compatibility is IE. The problem of this browser was that it has too large number of applications for which it was required to have backward compatibility. Problem was solved by adding new application Edge, which is updatable and supports all new standards. Can you give an piece of advice on how not to get caught by that backward-compatibility trap? As an example could it be a modularity which doesn't have layers? May be there is a way to replace API with RESTful API, Service Oriented Architecture or something else?

I’ve been building web applications for a long, long time – I wrote my first HTML page a couple of years before Internet Explorer even existed, back when the only browsers were NCSA Mosaic and Erwise. It’s fascinating to look back at the history of the web, and how the web that exists today has been shaped and influenced by things like the evolution of Internet Explorer – and you’re absolutely right; one of the reasons why Microsoft has introduced a completely new browser, Edge, in the latest versions of Windows is that Internet Explorer’s commitment to backwards-compatibility has made it really difficult to implement support for modern web standards alongside the existing IE codebase.

Part of the reason why that backwards compatibility exists is that, around the year 2000, there was a massive shift in the way that corporate IT systems were developed. There are countless corporations who have bespoke applications for doing all sorts of business operations – stock control, inventory, HR, project management, all kinds of things. Way back in the 1980s and early 1990s, most of them used a central mainframe system and employees would have to use something like a terminal emulator to connect to that central server, but after the first wave of the dotcom boom hit in the late 1990s, companies realised that most of their PCs now had a web browser and an network connection, and so they could replace their old mainframe terminal applications with web applications. Windows had enormous market share at the time, and Internet Explorer was the default browser on most Windows PCs, so lots of organizations built intranet web applications that only had to work on a specific version of Internet Explorer. Sometimes they did this to take advantage of specific features, like ActiveX support; more often I think they just did it save money because it meant they didn’t have to do cross-browser testing. This happened with some pretty big commercial applications as well; as late as 2011, Microsoft Dynamics CRM still offered no support for any browser other than Internet Explorer.

So you’ve got all these companies who have invested lots of time and money in building applications that only work with Internet Explorer. Those applications aren’t built using web standards or progressive enhancement or with any notion of ‘forward compatibility’ – they’re explicitly targeting one version of one browser running on one operating system. And so when Microsoft releases a new version of Internet Explorer, those applications fail – and the companies don’t want to invest in upgrading their legacy intranet applications, so they blame the browser. So we end up with this weird situation where here in 2017, Microsoft are still shipping Internet Explorer 11, which has a compatibility mode where it switches back to the IE9 rendering engine but sends a user agent string claiming that it's IE7. Meanwhile, everyone I know uses Google Chrome or Safari for all their web browsing - but still has an IE shortcut on their desktop for when they have to log in to one of those legacy systems. .

So… to go back to the original question: is there anything Microsoft could have done to avoid this trap? I think there’s a lot of things they could have done. Building IE from the ground up with a modular rendering engine, so that later versions could selectively load the appropriate engine for rendering a particular website or application. They could have made more effort to embrace the web standards that existed at the time, instead of implementing ad-hoc support for things like the MARQUEE tag and ActiveX plugins, which would have avoided the headache of having to support these esoteric features in later versions. The point is, though, none of this mattered at the time. Their focus – the driving force behind the early versions of Internet Explorer – was not to create a great application with first-class support for web standards. They were trying to kill Netscape Navigator and win market share – and it worked.

Q: Let’s imagine someone is going to introduce an API. So they collect some requirements, propose a version and gets feedback. That’s rather simple and straightforward thing. But if there are any hidden obstacles there down the road?

Always! Requirements are going to change – in fact, one of the biggest mistakes you can make is to try and anticipate those changes and make your design ‘future-proof’. Sometimes that pays off, but what mostly happens is that you end up with a much more complicated design purely because you’re trying to anticipate those future changes. Those obstacles are often things outside your control. There’s a change to the law that means you need to expose certain data in a different way. There’s a change to one of the other systems in your organization, or one of your cloud hosting providers announces that they’re deprecating a particular feature that you were relying on.

The best thing to do is to identify something simple and usable, ship it, and get as quickly as you can to a point where your API is stable, there’s no outstanding technical debt, and your team is free to move on to the next thing. That way when you do encounter one of those ‘hidden obstacles’, you have a stable codebase to use as a basis for your solution, and you have a team who have the time and the bandwidth to deal with it. And if by some stroke of luck you don’t hit any hidden obstacles, then you just move on to the next thing on your backlog.

Q: Continue with API design. We’ve released the v1.0 of our API and now v1.1 is approaching. I believe many of us noticed http://example.com/v1/test and http://example.com/v1.1/test or something. What are the best practices (a couple of points) you can think of that can help a developer to design a good v1.1 API in respect to v1.0?

It’s worth reading up on the concept of semantic versioning, (SemVer) and taking the time to really understand the distinction between major, minor and patch versions. SemVer says that you shouldn’t introduce any breaking changes between version x.0 and version x.1, so the most important thing is to understand what would constitute a breaking change for your particular API.

If you’re working with HTTP APIs that return JSON, for example, a typical non-breaking change would be adding a new data field to one of your resources. Clients that are using version 1.1 and are expecting to see this additional field can take advantage of it, whereas clients that are still using version 1.0 can just discard the unrecognised property.

There’s a related question about how you should manage versioning in your APIs. One very common solution is to expose URLs via routing – api.example.com/v1/ as opposed to api.example.com/v1.1 – but if you’re adhering to the constraints of a RESTful system, you really need to understand whether the change in version represents a change in the underlying resource or just the representation. Remember that a URI is a Uniform Resource Identifier, and so we really shouldn’t be changing the URI that we’re using to refer to the same resource.

For example – if we have a resource api.example.com/images/monalisa. We could request that resource as a JPEG (Accept: image/jpeg), or as a PNG (Accept: image/png), or ask the server if it has a plain-text representation of the resource (Accept: text/plain) – but they’re just different representations of the same underlying resource, and so they should all use the same URI.

If – say – you’ve completely replaced the CRM system used by your organization, and so “version 1” of a customer represents a record used in the old CRM system and “version 2” represents that same customer after they’ve been migrated onto a completely new platform, then it probably makes sense to treat them as separate resources and give them different URIs.

Versioning is hard, though. The easiest thing to do is never change anything

Q: .NET Core - what do you think about its API?

When .NET Core was first announced in 2015, back when it was going to be be called .NET Core 5.0, it was going to be a really stripped-down, lightweight alternative to the .NET Framework and the Common Language Runtime. That was an excellent idea in terms of making it easier to port .NET Core to different platforms, but it also left a sizable gap between the API exposed by .NET Core, and the ‘standard’ .NET/CLR API that most applications are built against.

I believe – and this is just my interpretation based on what I’ve read and people I’ve talked to – that the idea was that .NET Core would provide the fundamental building blocks. It would provide things like threading, filesystem access, network access, and then a combination of platform vendors and the open source community would develop the modules and packages that would eventually match the level of functionality offered by something like the Java Class Library or the .NET Framework. That’s a great idea in principle, but it also creates a chicken-and-egg situation: people won’t build libraries for a platform with no users, but nobody wants to use a platform that doesn’t have any libraries.

So, the decision was made that cross-platform .NET needed a standard API specification that would provide the libraries that users and application developers expected to be available on the various supported platforms. This is .NET Standard 2.0, which is already fully supported by the .NET Framework 4.6.1 and will be supported in the next versions of .NET Core and Xamarin. Of course, .NET Core 1.1 is out, and works just fine, and you can use it right now to build web apps in C# regardless of whether you’re running Windows or Linux or macOS, which is pretty awesome – but I think the next release of .NET Core is going to be the trigger for a lot of framework and package developers to migrate their projects across to .NET Core, which in turn should make it easier for developers and organizations to migrate their own applications.

Tram on Moscow Gate Square in Saint Petersburg. freegoodphotos.com /  Photo by Dinamik.

API flexibility VS. API precision. One can design a method API so it can accept many different types of values. It’s flexibility. We also can design a method API with lots of rules on input parameters. Both ways are correct. Where is the boundary across these approaches? When should I make a “strict” API and when should I make a more “flexible” design? Don’t forget that you should take backward-compatibility into account.

By implementing an API where the method signatures are flexible, all you’re doing is pushing the complexity to somewhere else in your stack. Say we’re building an API for finding skiing holidays, and we have a choice between

DoSearch(SearchCriteria criteria)

and

DoSearch(string resortName, string countryCode, int minAltitude, int maxDistanceToSkiList)

One of those methods is pretty easily extensible, because we can extend the definition of the SearchCriteria object without changing the method signature – but we’re still changing the behaviour of the system, we’re just not changing that particular method. By contrast, we could add new arguments to our DoSearch method signature, but if we’re working in a language like C# where you can provide default argument values, you won’t break anything by doing that as long as you provide sensible defaults for the new arguments.

At some point, though, you need to communicate to the API consumers what search parameters are accepted by your API, and there’s lots of ways to accomplish that. If you’re building a .NET API that’s installed as a NuGet package and used from within code, then using XML comments on your methods and properties is a great way to explain to your users what they need to specify when making calls to your API. If your API is an HTTP service, look at using hypermedia and formats like SIREN to define what parameter values and ranges are acceptable.

I should add that I think within the next decade, we’re going to start seeing a whole different category of APIs powered by machine learning systems, where a lot of the conventional rules of API design won’t apply. It wouldn’t surprise me if we got an API for finding skiing holidays where you just specify what you want in natural language, and so there’s not even a method signature – you just call something like DoSearch(“ski chalet, in France or Italy, 1400m or higher, that sleeps 12 people in 8 bedrooms, available from 18-25 January 2018”) – and the underlying system will work it all out for us. Those sorts of development in machine learning are hugely exciting, but they’re also going to create a lot of interesting challenges for the developers and designers trying to incorporate them into our products and applications. 


Thanks to Alexej Sommer for taking the time to set this up (and for translating my answers into Russian – Спасибо!), and if you're at DotNext next week and want to chat about APIs, hypermedia or any of the stuff in the interview, please come and say hi!

Thursday, 27 April 2017

It Works On My Machine!

I saw on Twitter this morning that Derick Bailey is looking for people to share their own “works on my machine” stories… and halfway through filling out his survey, I decided this would probably be much more fun if I nicked his survey questions and turned them into headings in a blog post. Mainly ‘cos writing for an audience appeals to me far more than filling out survey – but Derick (and anyone else who cares?) is very welcome to use anything in this post as part of their own research.

What's typically going through your head when you say "works on my machine" to a QA person or another developer?

I think the interesting question here is actually – what did somebody say to you that caused you to respond with “it works on my machine?”

Here’s three fairly common scenarios:

Q: This code throws an exception when we run it on the staging environment…
A: It works on my machine.

Q: How are you getting on with that improvement to the search algorithm?
A: It works on my machine.

Q: Did you get anywhere with that really weird solution to the mapping problem that Chris found on StackOverflow?
A: It works on my machine…

See how in each case, there’s a sort of implicit subtext? See, I think we all understand that there’s often quite a big difference between solving a problem and delivering a solution. In almost all development scenarios, the first step is to get the code you’re working on running locally and doing the right thing on your development system – and often to do that, we have to hack things around. Running web servers as a local admin user. Granting “Everyone Full Control” of all the files in the media folder. Manually tweaking registry keys, installing DLLs, reusing credentials for APIs and external services – there’s a whole lot of stuff that has to happen as well as just writing some code, but most of the time, the code is the focus and the rest just feels like friction.

So… to answer the original question, when I tell somebody something works on my machine, I’m thinking “ok, what else, other than my own code, do we need to do to deploy the solution, close the ticket and move on?” When you’re working on spikes and prototypes, that’s a natural part of the conversation. If you’ve submitted a ticket to QA for final pre-release testing and it doesn’t work, there’s naturally a bit of tension because implicit in the conversation is the fact that somebody thinks you haven’t done your job properly – and “well it works on my machine” can come across as defensive.

Can you share a story about a time when you have said, or thought, this?

Ah, dozens. The most common example for me is when I’m making a change that spans code in 4-5 different projects, so I’ve checked them all out… in one project I’ve added a database column, in another there’s some new HTTP request routing, in the third there’s a new message queue subscriber, and then there’s the new feature code that relies on all of those changes to work properly. And it works on MY machine because locally I’ve already made all of those changes, but it get it working anywhere else, all five projects need to be reviewed, built, packaged, configured and deployed onto the same environment. Or, for another developer to work on it, they need to check out five specific branches from five specific projects and then probably run a couple of configuration scripts as well – and there’s invariable one or two little things that didn’t require any explicit configuration on my own workstation but then it turns out your teammate has enabled WebDAV publishing under Windows Programs and Features and so their IIS configuration isn’t the same as yours.

How do you typically feel when someone says, "works on my machine," to you?

First off, I’m happy. See, I’ve worked with a very small number of developers who didn’t bother doing even this most basic validation of the work they were doing. They’d commit something, open a pull request and ask for a code review, and you’d look at what they did and think “that’s a bit weird”, so you’d wander over and say “hey, can you show me how this feature works?” – and they will actually say “I don’t know, I can’t run that project”. 

“Works on my machine” at least indicates that they’ve got all the code checked out, they’ve compiled it, and they’ve actually got it running. That’s a good start. That’s something you can work with. And at that point, it’s a great opportunity to explain things like configuration management or deployment scripts.

Can you share a story about a time when someone said this to you?

We had a problem a few weeks ago where we ported an old project from VS2010 to VS2015, and TeamCity wouldn’t build it properly. An absolute textbook example – another developer comes to me and says “well, it works on my machine; it builds fine and I can run all the tests, but TeamCity won’t run any of the unit tests and so the build keeps failing.” Turned out to be a rogue wildcard somewhere in the TeamCity build config settings that was causing it to pick up unit test DLLs from the \obj\ folders instead of \bin\. Which, of course, doesn’t happen when you’re running tests using Resharper or NCrunch, because those tools are smart enough to understand path conventions.

What are the 3 largest causes of someone saying "works on my machine"?

In my experience? The biggest one is dependencies between multiple projects. The “feature”, the unit of business value we’re trying to deliver, requires changes across several different projects and so those changes need to be coordinated and deployed together in order to run and test the new feature, and it’s very easy to miss a step when you’re trying to capture and package all of those code and configuration dependencies.

Second biggest would have to be mismatches between developer environments. We have some people running Windows 8.1, some people running Windows 10, some people working via remote desktop onto virtual machines in the cloud, and then all the various quirks of people’s individual OS configurations like the aforementioned WebDAV Authoring support.

Third? Probably data. Lookup tables, test records, and code that’s brittle because it depends on specific records existing in a particular state, and when you check out the code it doesn’t include the migration steps or SQL scripts that are necessary to set up those records.

Actually, I’m going to go for four, because the one that bites me all the time – probably once a week – is that when you add a new file to a Visual Studio solution, it doesn’t save the .csproj file by default. The new file gets added to the repo and pushed up to GitHub, but the project reference to that new file still only exists on your local machine. Sometimes it’ll crash the build; sometimes – if it’s an image or a script file or something – it’ll build, pass tests, deploy, and then fail on the test server because the new file isn’t included in the .csproj and so wasn’t included when the deployment package was built. If you think your organisation doesn’t have this problem, search your GitHub repo for commit messages including the phrase “csproj file”…

How do you combat the "works on my machine" problem?

There’s a couple of things that have definitely made a big difference to our team at Spotlight. One is setting up an internal NuGet server (we’re running Klondike), and making sure that if your project code references DLLs or any other static components, those dependencies are managed as NuGet packages. That way the first time you build the project, it’ll download all of those obscure DLLs for you instead of waiting for you to get an error message, look it up on the wiki, etc.

One is giving everybody the ability to build and deploy pre-release packages. We have TeamCity and GitHub configured so that as soon as you open a pull request, TeamCity will try and build a deployable package based on the merge head of your feature branch. This means you, the developer, can get packaged builds of your work in progress, deploy it onto one of our testing environments and see for yourself whether it’s going to work or not. Which means you get the chance to fix the bugs and configuration problems before passing it on to anyone else to review or test.

belgian-beers

Oh, and we have something called escrow beers. If you want to introduce a new tool, dependency, language or something into one of our projects, you have to put a six-pack of beer (or a box of cookies or something similarly delicious) in escrow, in the kitchen. Put a post-it note on it saying what it’s for – and then when some poor developer is working late to get a feature out and they discover that they need to install grunt or gulp or bower or yeoman or FAKE or PSake or whatever, there’s goodies in the fridge that will help. That’s doesn’t necessarily inhibit the adoption of new tech, but having to go out and buy beer or cookies makes people stop to think about how their changes might affect their teammates, and so they’ll add some checkout scripts to get the new thing working, or document it on the wiki, or organise a demo to show everyone what they need to know. It's also funny how often somebody thinks a new tool or language is ABSOLUTELY TOTALLY AMAZING and there's no way we can possibly live without it… except it's not actually quite amazing enough to justify walking to a shop at lunchtime and buying a box of cookies.

So there you go… more than you ever wanted to know about code that works on my machine. Thanks again to Derick Bailey for the idea – and just to be clear, you’re welcome to use it, and please credit me by name if you use the information provided here in any follow-up posts or other material.

Monday, 24 April 2017

Robert M. Pirsig on "Stuckness"

Robert M. Pirsig, the author of "Zen and the Art of Motorcycle Maintenance", died today aged 88. I've read and re-read that book many times over the years. As somebody who has always found tranquillity in tinkering, I found that "Zen" evokes that meditative, transcendental state that one can achieve whilst doing mechanical maintenance better than anything I've read… and in others, it captures perfectly the awful frustration that can only be experienced when a perfectly simple job turns into a protracted bout of yak-shaving.

ZAMMcoverold

Of all the passages in the book, the one that has stayed with me the most is the one I've included below, on the subject of 'stuckness'. After countless evenings spent tweaking and tuning mountain bikes in my dad's garage, experiencing first-hand the frustration of a £800 mountain bike rendered completely useless by stripping the head off a 50p bolt, this passage resonated with me more than anything I think I've ever read. I still think of it frequently, normally when I find myself stuck on some hitherto inconsequential detail of a software project that's somehow managed to derail the entire team for days at a time. The book is excellent, and if you haven't read it I highly recommend it, but the passage in question is here. I hope Mr Pirsig's lawyers don't mind. :)

Stuckness. That's what I want to talk about today.

A screw sticks, for example, on a side cover assembly. You check the manual to see if there might be any special cause for this screw to come off so hard, but all it says is "Remove side cover plate" in that wonderful terse technical style that never tells you what you want to know. There's no earlier procedure left undone that might cause the cover screws to stick.

If you're experienced you'd probably apply a penetrating liquid and an impact driver at this point. But suppose you're inexperienced and you attach a self-locking plier wrench to the shank of your screwdriver and really twist it hard, a procedure you've had success with in the past, but which this time succeeds only in tearing the slot of the screw.

Your mind was already thinking ahead to what you would do when the cover plate was off, and so it takes a little time to realize that this irritating minor annoyance of a torn screw slot isn't just irritating and minor. You're stuck. Stopped. Terminated. It's absolutely stopped you from fixing the motorcycle.

This isn't a rare scene in science or technology. This is the commonest scene of all. Just plain stuck. In traditional maintenance this is the worst of all moments, so bad that you have avoided even thinking about it before you come to it.

The book's no good to you now. Neither is scientific reason. You don't need any scientific experiments to find out what's wrong. It's obvious what's wrong. What you need is an hypothesis for how you're going to get that slotless screw out of there and scientific method doesn't provide any of these hypotheses. It operates only after they're around.

This is the zero moment of consciousness. Stuck. No answer. Honked. Kaput. It's a miserable experience emotionally. You're losing time. You're incompetent. You don't know what you're doing. You should be ashamed of yourself. You should take the machine to a real mechanic who knows how to figure these things out.

It's normal at this point for the fear-anger syndrome to take over and make you want to hammer on that side plate with a chisel, to pound it off with a sledge if necessary. You think about it, and the more you think about it the more you're inclined to take the whole machine to a high bridge and drop it off. It's just outrageous that a tiny little slot of a screw can defeat you so totally.

What you're up against is the great unknown, the void of all Western thought. You need some ideas, some hypotheses. Traditional scientific method, unfortunately, has never quite gotten around to say exactly where to pick up more of these hypotheses. Traditional scientific method has always been at the very best, 20-20 hindsight. It's good for seeing where you've been. It's good for testing the truth of what you think you know, but it can't tell you where you ought to go, unless where you ought to go is a continuation of where you were going in the past. Creativity, originality, inventiveness, intuition, imagination..."unstuckness," in other words...are completely outside its domain.

We're still stuck on that screw and the only way it's going to get unstuck is by abandoning further examination of the screw according to traditional scientific method. That won't work. What we have to do is examine traditional scientific method in the light of that stuck screw.

We have been looking at that screw "objectively." According to the doctrine of "objectivity," which is integral with traditional scientific method, what we like or don't like about that screw has nothing to do with our correct thinking. We should not evaluate what we see. We should keep our mind a blank tablet which nature fills for us, and then reason disinterestedly from the facts we observe.

But when we stop and think about it disinterestedly, in terms of this stuck screw, we begin to see that this whole idea of disinterested observation is silly. Where are those facts? What are we going to observe disinterestedly? The torn slot? The immovable side cover plate? The color of the paint job? The speedometer? The sissy bar? As Poincaré would have said, there are an infinite number of facts about the motorcycle, and the right ones don't just dance up and introduce themselves. The right facts, the ones we really need, are not only passive, they are damned elusive, and we're not going to just sit back and "observe" them. We're going to have to be in there looking for them or we're going to be here a long time. Forever. As Poincaré pointed out, there must be a subliminal choice of what facts we observe.

The difference between a good mechanic and a bad one, like the difference between a good mathematician and a bad one, is precisely this ability to select the good facts from the bad ones on the basis of quality. He has to care! This is an ability about which formal traditional scientific method has nothing to say. It's long past time to take a closer look at this qualitative preselection of facts which has seemed so scrupulously ignored by those who make so much of these facts after they are "observed." I think that it will be found that a formal acknowledgment of the role of Quality in the scientific process doesn't destroy the empirical vision at all. It expands it, strengthens it and brings it far closer to actual scientific practice.

I think the basic fault that underlies the problem of stuckness is traditional rationality's insistence upon "objectivity," a doctrine that there is a divided reality of subject and object. For true science to take place these must be rigidly separate from each other. "You are the mechanic. There is the motorcycle. You are forever apart from one another. You do this to it. You do that to it. These will be the results."

This eternally dualistic subject-object way of approaching the motorcycle sounds right to us because we're used to it. But it's not right. It's always been an artificial interpretation superimposed on reality. It's never been reality itself. When this duality is completely accepted a certain nondivided relationship between the mechanic and motorcycle, a craftsmanlike feeling for the work, is destroyed. When traditional rationality divides the world into subjects and objects it shuts out Quality, and when you're really stuck it's Quality, not any subjects or objects, that tells you where you ought to go.

By returning our attention to Quality it is hoped that we can get technological work out of the noncaring subject-object dualism and back into craftsmanlike self-involved reality again, which will reveal to us the facts we need when we are stuck.

Let's consider a reevaluation of the situation in which we assume that the stuckness now occurring, the zero of consciousness, isn't the worst of all possible situations, but the best possible situation you could be in. After all, it's exactly this stuckness that Zen Buddhists go to so much trouble to induce; through koans, deep breathing, sitting still and the like. Your mind is empty, you have a "hollow-flexible" attitude of "beginner's mind." You're right at the front end of the train of knowledge, at the track of reality itself. Consider, for a change, that this is a moment to be not feared but cultivated. If your mind is truly, profoundly stuck, then you may be much better off than when it was loaded with ideas.

The solution to the problem often at first seems unimportant or undesirable, but the state of stuckness allows it, in time, to assume its true importance. It seemed small because your previous rigid evaluation which led to the stuckness made it small.

But now consider the fact that no matter how hard you try to hang on to it, this stuckness is bound to disappear. Your mind will naturally and freely move toward a solution. Unless you are a real master at staying stuck you can't prevent this. The fear of stuckness is needless because the longer you stay stuck the more you see the Quality...reality that gets you unstuck every time. What's really been getting you stuck is the running from the stuckness through the cars of your train of knowledge looking for a solution that is out in front of the train.

Stuckness shouldn't be avoided. It's the psychic predecessor of all real understanding. An egoless acceptance of stuckness is a key to an understanding of all Quality, in mechanical work as in other endeavors. It's this understanding of Quality as revealed by stuckness which so often makes self-taught mechanics so superior to institute-trained men who have learned how to handle everything except a new situation.

Normally screws are so cheap and small and simple you think of them as unimportant. But now, as your Quality awareness becomes stronger, you realize that this one, individual, particular screw is neither cheap nor small nor unimportant. Right now this screw is worth exactly the selling price of the whole motorcycle, because the motorcycle is actually valueless until you get the screw out. With this reevaluation of the screw comes a willingness to expand your knowledge of it.

- from "Zen and the Art of Motorcycle Maintenance" by Robert M Pirsig (September 6, 1928 – April 24, 2017)

Friday, 21 April 2017

There’s a problem with the phalange!

Yesterday I was throwing together a quick Entity Framework prototype to inspect and wrangle some data held in one of our legacy databases. I’m using the Entity Framework “Code first from Database” approach, where you use the tooling to generate your initial model for you but thereafter you modify it by hand. One of the tables I’m working with here is called LookupRanges, so when I generated a bunch of entities and DbSet<> mappings, I was a bit surprised when I ended up with a class called LookupRanx in my new model.

It took a minute or two to ascertain that yes, Entity Framework had mapped my LookupRanges (plural) table name onto a class called LookupRanx. But where on earth did that ‘Ranx’ come from? My hunch here is that somebody who worked on this pluralization code remembered that the English word phalanx has the plural form phalanges – and so implemented a rule that says ‘any word ending in –anges should be singularizaed to –anx. Out of curiousity, I dug out my huge ASCII file of English words, found all the words ending in *anges, and hacked up a quick SQL script to create tables named for all these words so I could run them through EF and see what class names were generated.

Well, it gets ‘changes’ and ‘phalanges’ right – and gets literally every other case wrong.

image

Now this, to me, is an outstanding example of one of the biggest problems in software development… smart people like working on things that are interesting, and will frequently spend time doing something that’s interesting instead of something that’s important.

Writing a library that can singularize and pluralize English words is fascinating. It’s a never-ending problem with dozens of rules and hundreds of edge cases, and you learn a lot of weird and cool esoteric facts about language and etymology whilst you’re doing it. But in this instance, something started out as a good idea (“hey – wouldn’t it be cool if the model generator would convert plural table names to singular class names?”), and got bogged down in edge cases (“is the plural of ‘tableau’ really ‘tableaux’?”) and – in this instance – ended up with a bizarre bug because one of those so-called edge cases actually ended up breaking the default – and entirely correct – behaviour.

First, phalanges is extremely unlikely to ever show up as the name of a table in an Entity Framework database model. I can think of dozens of real-world scenarios where you’d end up with a table name ending with –Ranges, –Exchanges or –Interchanges, but I’m honestly struggling to think of any remotely likely scenario where you have a Phalanges table in a SQL Server database. This is the kind of thing where the ticket or the user story probably just says ‘implement pluralization’, and then there’s no sub-prioritization or further analysis about just how much pluralization needs to be implemented. Second – it’s kind of a stupid edge case. We’re not trying to win points on University Challenge here, we’re building software. In contemporary English, phalange is an acceptable singular form, and phalanxes is an acceptable plural form. There’s no reason at all why they needed to implement support for this particular edge case. And third: if you really found yourself in a scenario where you had to map the Phalanges table to the Phalanx class, you can just rename it. It’s easy. Visual Studio has first-class support for this kind of refactoring.

And, as if that wasn’t confusing enough, there’s actually source code for an EnglishPluralizationService.cs on Microsoft’s GitHub repository. Somebody obviously had a lot of fun building this, tracking down all those bizarre little edge cases like seraph/seraphim, hippopotamus/hippopotami – but according to this implementation, the plural of phalanx is…  go on. Go and take a look.

Now, though, I’m going to eat an oranx and check my email. Using Microsoft Exchanx, of course.

Monday, 3 April 2017

The Pursuit of APIness: The Secret to Happy Code

I'll be giving a new talk at the London.NET User Group meetup here in London next Tuesday, based on an idea I've had rattling around for a decade or more now. See, it seems to me that over the course of my career, there's been a strong correlation between happy developers and successful projects. I can't think of any examples where a miserable death-march project has resulted in high-quality working software, and I can't think of too many instances where a group of happy, motivated developers has failed to deliver a working product. I've been thinking around this idea for a while, and started looking at it in terms of user experience – both the user experience that we as developers are creating for our end users, but also the 'user experience' that's being provided by the libraries, frameworks and tools that we're using to do our jobs. Here's the talk synopsis:

We spend our lives working with systems created by other people. From the UI on our phones to the cloud infrastructure that runs so much of the modern internet, these interactions are fundamental to our experience of technology - as engineers, as developers, as users - and user experiences are viral. Great user experiences lead to happy, productive people; bad experiences lead to frustration, inefficiency and misery.

Whether we realise it or not, when we create software, we are creating user experiences. People are going to interact with our code. Maybe those people are end users; maybe they're the other developers on your team. Maybe they're the mobile app team who are working with your API, or the engineers who are on call the night something goes wrong. These may be radically different use cases, but there's one powerful principle that works across all these scenarios and more. In this talk, we'll draw on ideas and insight from user experience, API design, psychology and education to show how you can incorporate this principle, known as discoverability, into every layer of your application. We'll look at some real-world systems, and we'll discuss how discoverability works with different interaction paradigms. Because, whether you're building databases, class libraries, hypermedia APIs or mobile apps, sooner or later somebody else is going to work with your code - and when they do, wouldn't it be great if they went away afterwards with a smile on their face?

If that sounds interesting (or if you think I'm completely wrong and you want to come along and heckle!), sign up at the SkillsMatter website and come along on Tuesday 11th. Hope to see you there.

Wednesday, 22 March 2017

Goodbye ECMAScript; hello UKMAScript!

The UK government has announced it will trigger Article 50 on March 29th, beginning the two-year process of the United Kingdom leaving the European Union.


That’s right - it will no longer be legal for British web developers to run ECMAScript, since the ECMAScript specification is controlled by the European Computer Manufacturers’ Association. We’re happy to announce that as of today, top engineers are starting work on a superior British programming language called UKMAScript.

UKMAScript will extend the core language specification with the following enhancements, which we believe will provide a massive boost to the UK tech industry and offset the immeasurable damage caused when all our EU colleagues and collaborators decide to exercise their freedom of movement.

  • Along with NaN and Infinity, UKMAScript will support a new primitive numeric value called MoneyForTheNhs, whose value is defined to be exactly 3.5x108 until it’s used as an argument to any function, at which point its value will be silently changed to zero after the function has returned.
  • The Math.round() method will behave as before, except Math.round(0.52) will now return Number.MAX_VALUE. Math.round(0.48) will return a new constant Number.TRAITORS and any attempt to use this value in calculations will throw a TreasonError
  • A new “illogical implication” operator !#> will be introduced. This is syntactically similar to the notion of logical implication in Boolean algebra, but designed to allow the scope of arguments to be massively exaggerated. For example, the statement (leave_eu !#> leave_customs_union && leave_eea) will implicitly bind the values of leave_customs_union and leave_eea to the value of leave_eu, despite this dependency not being expressed anywhere else in the codebase.
  • Along with null and undefined, a new language primitive brexit will be introduced. This has the special equality semantics (brexit == brexit) == undefined. typeof(brexit) will return the value “hard”, and attempting to evaluate brexit.valueOf() will throw a TreasonError.
  • UKMAScript features a new parallel programming paradigm implemented via the Referendum.Invoke() method. This causes a thread to break away from the main sequence of program control and attempt to continue execution despite no longer having access to any processing capabilities or shared resources of the host system. Note that if a thread A has called Referendum.Invoke(), any child process B attempting to call Referendum.Invoke() will be summarily ignored by process A on the grounds that it’s clearly developed a fault.

UKMAScript ships with no standard library or runtime, but the UKMAScript language committee assures us that platform vendors are lining up to deliver first-class support for the new language.

To further promote the popularity of UKMAScript, the only alternative permitted once Article 50 has been invoked is a new language called LABOUR, which takes many of the core language principles of COBOL-64 but is only accessible using the GNU/Corbyn compiler. This compiler has a tremendously exciting installation routine but then doesn’t actually do anything other than occasionally create internal process deadlocks for no reason.

Tuesday, 7 March 2017

It's a bug! It's a feature! It's… a limitation of the fundamental design of your test framework?

As some of you probably know, I'm a big fan of NCrunch. When I'm coding in C#, NCrunch gets a CPU core and a whole screen to itself (yes, I don't really write code on a system that looks like this) and sits there quietly running all my tests, all the time, and telling me the second I break anything.

I'm also a big fan of testing things that are as close to production behaviour as you can. Unit tests are great for informing the design of your components, but without integration testing you can't be sure they're actually going to work when you stick them together.

So on my current project, there's a suite of unit tests using FakeItEasy and assertions, and then a suite of integration tests that connect to the live API, follow the various hypermedia links, throw assorted JSON objects at the PUT and POST endpoints to see how they respond, and then call DELETE to clean up when they're done. And, just to keep us honest, we've got a post-deploy step in our Octopus Deploy script that will actually run the integration test suite as part of the deployment process, and roll the whole thing back if any of the tests fail. Another small step on the road to truly continuous deployment.

Anyway. Last week, I push a release to our dev environment, and a whole load of tests fail. Which is weird, because it worked on MY machine. And it worked on my machine when I pointed my local codebase at the database in the dev environment. And – here's the fun part – it worked on my machine when I pointed the entire test suite at the dev environment. So I start eliminating variables. One of the first things I pick up on is that my local test runner is NCrunch, whereas the post-deploy step is using nunit-console. So I run the local integration tests using nunit-console and – bang. Failures. Which is good, because I know what's causing the weirdness, but weird, because tests are supposed to either pass or fail regardless of what test runner you're using.

So I dig a little deeper, and I end up with what looks to me like a bug in NCrunch. See, we're using the TestCaseSource attribute to generate test cases for the API tests, and – because all we need is a bunch of different JSON objects – we're just spinning up new anonymous objects and passing them in as test cases.

Here's two anonymous objects:

var testCase1 = new { forenames = null, surname = "Batman" }
var testCase2 = new { forenames = String.Empty, surname = "Batman" }

What I noticed is that if you generate these two test cases, NCrunch will only see them as a single test – which I assumed was because their ToString() representations are equal, because null and String.Empty both return String.Empty when you ToString() them in this situation. So I opened a post about it on the NCrunch forums, even going so far as to suggest using GetHashCode() when enumerating test names, and got this really interesting response from Remco Mulder, the NCrunch lead developer:

Tests must be uniquely identifiable between execution and discovery runs. This isn't important for a tool like the nunit console runner where a test can be discovered and executed within the same process call (and thus identified by its memory address), but for a tool like NCrunch, there's no way to run the test or collect data from it without this. As you've identified, generated tests with a null parameter and an empty string will return the same result under .ToString(), so NCrunch can't tell them apart.

The only way to solve this is to change the design of your code. Try using the NUnit .SetName() method to give each of your generated tests a distinctive name.

Unfortunately .GetHashCode() is not a reliable solution to this problem as this method is not designed to generate the same identifier across different processes. This method returns different results under x86 vs x64, and under .NET Core it will actually return an entirely different result for each process. Because your code is responsible for generating the tests, the problem can only be solved within your own code.

I thought this was a really interesting insight into how a tool like NCrunch has to deal with situations that an in-process test runner like nunit-console will probably never encounter. It also turns out I’d dismissed that very warning a few weeks earlier – when it cropped up in response to an unrelated issue which produced the same symptons – and sure enough, after clicking the “Show all hidden warnings” button on the NCrunch toolbar, the warning popped back up – along with a very detailed explanation of what was causing it:

image

Plus, I had no idea that NUnit has a TestCaseData interface with a SetName() method on it, which gives a much nicer way of presenting these test cases in both NCrunch and NUnit. I've ended up with something akin to:

public static IEnumerable TestData() {
  foreach (var data in new[] { null, String.Empty }) {
    var testCase = new { forenames = data, surname = "Batman" };
    var json = JsonConvert.SerializeObject(testCase);
    yield return new TestCaseData(testCase).SetName(json);
  }
}

Oh, and if you're interested, the deployment failures were because of a weird validation rule that treats null as missing, which is fine, but String.Empty as an empty string which violates a string length constraint. Which is wrong, and now the API doesn't do it any more. This is just another reason why integration testing is a good idea. So there you have it – a bug that wasn’t a bug, a crash-course in how NUnit and NCrunch actually work behind the scenes, and a TIL for naming your NUnit tests explicitly. Happy Friday.

Wednesday, 22 February 2017

Progressive.NET 2017 : Call for Themes

In September, SkillsMatter will be hosting the eighth annual Progressive.NET Tutorials. Over the next few months, the programme committee – including me – will be working to create a line-up of themes, workshops, talks and speakers that reflects the state of the art in .NET here in 2017. We’ll be opening our call for papers next month, but before we do, we’d like your help. Yes, you!

Prog .NET Tutorials

What sets the Progressive.NET Tutorials apart from most conferences is our emphasis on deep-dive half-day workshops. Something between a normal conference talk and a full training course, the idea is that you go away afterwards with running code, on your own laptop, that you’ve written during the workshop and can refer back to when you’re trying to implement the things you’ve learned. Over the years we’ve introduced dozens of new ideas and technologies to the wider .NET community – from technologies like F#, NHibernate and OpenRasta, to patterns like machine learning, event sourcing and continuous deployment.

We’ve got loads of ideas for themes, tracks and workshops this year, but we’d like your input. What do you want to see? What’s “progressive” in your corner of the .NET ecosystem? Some of the themes we’re already talking about are:

.NET on Linux in Production

OK, so your .NET Core application runs on Linux – awesome. What else do you need to know? Security? Configuration management? Monitoring, infrastructure? What about tools like Nginx, HAProxy and Varnish? How can you combine the power of .NET Core runtime with the maturity and flexibility of the Linux platform?

Contributing to .NET Core and Open Source

.NET Core is now part of a rich ecosystem of open source projects, but even for experienced developers, the journey from using open source to actually contributing can be daunting. Want to learn more about contributor licenses, workflows, issues and how to find your way around an unfamiliar codebase?

Cloud Native and Serverless

Ten years ago we were talking about dumping physical servers for virtual servers… now we’re talking about getting rid of servers completely. Cloud native is a whole new world for app developers. 12-factor apps, microservices, API-first development and containerisation are changing the way we approach application development – and the “big three” cloud platforms - .NET Core. AWS Lambda, Google Cloud Functions and Azure Functions  -now all support running serverless code built with .NET Core 1.1. So what can you do with it? What’s involved in designing, implementing and deploying serverless and cloud native applications?

Mobile, Desktop and Beyond

At one extreme, we’re deploying microservice apps onto serverless infrastructure. At the other extreme, people running .NET on a wider range of devices than ever before. Xamarin gives us a true cross-platform development toolchain for building native apps for Android and iOS devices. Libraries like Unity are helping C# developers build virtual worlds, from interactive data visualisation tools to launching Kerbals into space. HoloLens, Kinect and the latest generation of VR headsets are letting us interact with applications in all sorts of unprecedented ways, and with .NET Core and Windows Nano Server, we’re even seeing .NET running on the Internet of Things.

Prog .NET Tutorials

Agree? Disagree? Did we miss anything?

What do you think? What do YOU want to see? Akka.NET? Hexagonal architecture? ES.Next? What would you love to spend half-a-day learning about – discussing principles and patterns, asking questions, and going away with running code on your laptop that you can refer back to?

Prog .NET Tutorials

Comment here, find me on Twitter (@dylanbeattie), drop me an email, or come and say hi at the next London.NET User Group meetup, and let me know what you think. And let’s make this the best Progressive.NET Tutorials yet.