Page 2 of 22

Feature Gating part 1 : what is it?

Last week I was invited as speaker at the monthly DevDay Salerno to talk about Feature Gating. The recording will be soon available on YouTube (even though it will be in italian, sorry).

Seems that the topic captured some interest so I thought it was a good idea to write a little about it here. 

In this series of articles we will

  • discover what Feature Gating is
  • what strategy can we use to persist our data
  • some design patterns
  • how Feature Gating can help us and why should we be using it
  • how to fight the infamous tech debt

So let’s start!

As I wrote already in my last post, Feature Gating is an interesting and easy tool to leverage when you want more flexibility during production deployment. It helps controlling and shipping new features faster allowing practices like canary releases and A/B testing.

But what’s the heart of it? An IF block. Nothing else. 

Suppose you’re asked to rewrite a functionality, the first thing you would probably do is commenting the old code and replace it with a new function. Something like this:

Then (probably, hopefully) you update your tests and deploy to production. And right after you discover that maybe

  • the code is not exactly doing what it’s supposed to do
  • performances are lower than expected
  • a bug slipped through
  • whatever

So how can you control this without updating the code and deploying again? Let’s see a very simple solution:

We introduced another actor, this “checkFeatureIsOn” function. It will take the name of the feature and return a boolean flag indicating whether or not use the new codepath.

In the next article we will explore how would you store all the flags. Stay tuned!

DevDay Salerno: let’s talk about Feature Gating!

Tomorrow I’ll be speaking at the monthly Meetup hosted by the DevDay Salerno community! The topic of the day will be “Feature Gating“, I’ll talk about the general idea, use cases and best practices. The talk will be language-agnostic as this is more a pattern rather than a framework/library. I will show some code but try to keep the discussion more on the “theory-side”. 

I have always been more attracted to software architecture and design patterns so I tend to avoid putting too much effort in whatever library is the hype of the moment. 

Feature Gating is an interesting and easy tool to leverage when you want more flexibility during production deployment. It helps controlling and shipping new features faster allowing practices like canary releases and A/B testing.

One of the event organizers is an old friend of mine and ex coworker from my Healthware days. A while ago we discussed about having me presenting something but, as often happens, life stood in the way (along with me moving to a different country altogether).
So as soon as I had the chance to plan ahead my trip back to Italy he managed to find a slot for me πŸ™‚ 

Unfortunately the slides are in Italian so I don’t think I’ll share them on this blog but I will be writing soon a more detailed post so stay tuned!

In the meantime, if you’re near Salerno and fancy a little geekiness come and say hi!

 

How an AppDomain can help you isolate your method calls

In one of my latest pet-projects (which with a bit of luck is about to become a real project, knock on wood!) I have been in need of executing code in total isolation form the containing application. 

Without giving too many details, the system allows plugins to be uploaded ( as standard .NET assemblies ), stored and eventually executed. However, in order to avoid a rogue plugin to jeopardise the entire application with nasty stuff like infinite loops or random exceptions, I needed a way to isolate their execution.

Being this a new project, I started writing it using .NET Core but had to revert very quickly to the ol’ reliable Framework. Seems that as of now Assemblies can be loaded in memory but there’s no way to unload them.
Just for the sake of documentation, the class responsible of loading is AssemblyLoadContext . Unfortunately loaded assemblies will be kept in memory till the containing process gets closed (more details here).

So what’s the alternative? AppDomains ! As often happens, the MS documentation does a pretty good job explaining what they are and how should be used so I’ll move straight to the point.

I wrote a small example and pushed it to GitHub, you can find it here.

The core is the Isolator class: as you can see from the code it can be instantiated passing the Type of the class you want to isolate and the name of the method you want to run on it. Something like this:

using (var isolatedFoo = new Isolator(typeof(Foo), “Bar”))
     isolatedFoo.Run();

Under the hood the Isolator will:

  • create a new AppDomain
  • load the assembly containing typeof(Foo) 
  • create an instance of Foo
  • execute the “Bar” method on said instance

Also, being a very polite class, it will unload the AppDomain during the Dispose() .

More under the hood, the real magic happens inside the IsolatorRunner class. As you can see from the code it inherits from MarshalByRefObject, this will allow the instance to act as an intermediary between the two AppDomains, with a proxy that will be automatically generated to intercept the calls on the other side.

Being this a quick example, I didn’t focus on the quality of the interfaces. So for example being forced to use a string to denote the method to execute is a little…disappointing. 

I’ll work a little more in the next days (weeks?) and try to come up with a nicer API, maybe using Expressions and Funcs πŸ™‚

How to reset the entities state on a Entity Framework Db Context

I had two bad days. Those days wasted chasing a stupid bug. I had a test class with 4 test cases on my infrastructure layer. If executed one by one, they pass. If the whole suite was executed, only the first one was passing.

At the end I found out that it was due to the Entity Framework Core db Context tracking the state of the entities. More or less. 
In a nutshell, every time a call to SaveChanges() fails,  the subsequent call on the same instance of the db context will retry the operations. 

So let’s say your code is making an INSERT with bad data and fails. Maybe you catch that and then you do another write operation reusing the db context instance.

Well that will fail too. Miserably.

Maybe it’s more correct to say that the second call will look for changes on the entities and will try to commit them. Which is basically the standard and expected behaviour.

Since usually db context instances are created for every request this might not be a big issue.

However, in case you are writing tests using XUnit Fixtures, the instance is created once per test class and reused for all the tests in that class. So in this case it might affect test results.

A potential solution is to reset the state of the changed entities, something like this:

Another option is to avoid entirely reusing the db context and generating a new one from scratch.
In my code the db context was registered on the DI container and injected as dependency. I changed the consumer classes to use a Factory instead and that fixed the tests too πŸ™‚

How I used Travis CI to deploy Barfer on Azure

Ok this time I want to talk a little bit about how I used Travis CI to deploy Barfer on Azure. Last time I mentioned how much helped having a Continuous Delivery system up and running so I thought it would be worth expanding a little bit the concept.

Some of you may say: “Azure already has a continuous delivery facility, why using another service?”. Well there’s a bunch of reasons why:

  • when I started writing Barfer I had no idea I was going to deploy on Azure
  • in case I move to another hosting service, I’ll just have to change a little bit the deployment configuration
  • CD on Azure is clunky and to be honest I still don’t know if I like Kudu.

Let me spend a couple of words on the last point. Initially I wanted to deploy all the services on a Linux web-app. Keep in mind that I wrote Barfer using Visual Studio Code on a Macbook Pro. So I linked the GitHub repo to the Azure Web App and watched my commits being transformed into Releases.

Well, turns out that Kudu on Linux is not exactly friendly. Also, after the first couple of commits it was not able to delete some hidden files in the node_modules folder. Don’t ask me why.

I spent almost a week banging my head on that then at the end I did two things:

  1. moved to a Windows Web-App
  2. dropped Azure CD and moved to Travis CI

Consider also that I had to deploy 2 APIs, 1 web client and 1 background service (the RabbitMQ subscriber) and to be honest I have absolutely no desire of learning how to write a complex deployment script. I want tools to help me doing the job, not blocking my way.

The Travis CI interface is  very straightforward: once logged in, link the account to your GitHub one and pick the repository you want to deploy. Then all you have to do is create a .yml script with all the steps you want to perform and you’re done.

Mine is quite simple: since I am currently deploying all the services together (even though each one has its own independent destination), the configuration I wrote makes use of 5 Build Stages. The first one runs all the unit and integration tests then for every project there’s a custom script that

  1. downloads the node packages (or fetches them from the cache)
  2. builds the sources
  3. deletes the unnecessary files
  4. pushes all the changes to Azure

The whole process takes approx 10 minutes to run due to the fact that for every commit all the projects will be deployed, regardless where the actual changes are. I have to dig deeper into some features like tags or special git branches, but I will probably just split the repo, one per project. I just have to find the right way to manage the shared code. 

© 2018 Davide Guida

Theme by Anders NorenUp ↑