So I’ve been wanting to get a decent feature toggle framework set up for my project at work. It’s one of those things which isn’t useful until it is, and then the pressure is on so you put off adding it, until it’s not useful again. So why not now!
I want to get access to the benefits of feature toggles like faster integration into production, canary deployments, A/B testing and all that good stuff.
This is what I found out in a very brief spike into my options.
Research spike into my options
The project I work on is Django with Django REST Framework. We have a couple of workers (also python) in the mix.
While feature toggles at their core are simple enough to implement. I don’t want to reinvent the wheel if I don’t have to.
Waffle vs Gargoyle
For Django there’s a useful comparison site which is where I started my investigation. Looking at this waffle and gargoyle immediately standout as the most popular and more active projects so I dove a little deeper into those project.
gargoyle, at least the original project is dead, and has been forked by YPlan. The pulse for the fork is flatline, but has a comparable amount of commit activity to waffle although fewer contributors. So it’s death and resurrection aren’t reason enough to rule it out completely. On the other hand it’s not a great sign either. There’s no issue tracker that I can see for gargoyle-yplan, which is also a bit of a red flag.
waffle is definitely the winner in terms of popularity and activity as seen it it’s pulse. The little discussion<0> I can find on the subject seems to favor waffle, but there’s not a huge amount to go on.
waffle does have an active issue tracker that seems to be maintained, but there is a worrying issue titled “Waffle can’t be used directly on DRF’s request objects”, which doesn’t seem a show stopper, but is a concern.
Feature wise they seem roughly the same although Gargoyle seems a little more flexible. This is reiterated in the docs for waffle;
The other major, active feature flag tool for Django is Disqus’s Gargoyle. Both support similar features, though Gargoyle offers more options for building custom segments in exchange for some more complexity and requirements.
That’s clearly a little out of date, but looking at the API of both projects I’d say the Gargoyle does seem to have a bit more flexibility there.
Why do I need flexibility
There’s a number of assumptions that are often true about these kinds of deployments (sweeping generalisations ahoy!);
- Views aren’t paper thin.
- Templates and forms are likely to be used.
- Users are probably interacting with some sort of GUI.
- Cookies are involved.
- The user model is relatively traditional. Users are created locally and can be members of groups.
- A request is almost always in the picture. The model layer is rarely invoked without a request or view being heavily involved.
However, the project I’m working on is significantly different from this. The most significant reason being that it’s only interface is a RESTful API and that API relies heavily on the functionality provided by Django REST Framework. There are a number of other complications;
- We have workers that are accessing either the API or DB directly using the model layer but not always with a request object.
- We manager a number of external resources and databases not mapped onto Django’s ORM.
- Our user model has more complex requirements.
Also, our project is evolving rapidly, we’ve got a fair amount of tech debt and some weird stuff that doesn’t make sense if you were starting from scratch.
One of the things that’s often bothered me about Django, compared to other frameworks like Pyramid is that it’s very tightly coupled, both the internal components (ORM, templating, views etc) and the external third-party packages. I think Django has improved in recent years on this front, and it’s this tight coupling that means Django is so darn conveniant to use, but in my experience stuff gets gnarly when you try to go off the beaten path.
With our rapid evolution I fear that inflexibility is going to cause problems. For example it’d be good to be able to switch out one of our ORM based models for an object backed by some other form of persistence, but there is no easy way to provide a consistent interface to Django’s so that legacy code doesn’t flip it’s shit. For this reason I am hesitant to couple the project, if I don’t have to, to more Django specific magic.
Basically, however much I want some easy answers right now, I need to make sure I don’t sacrifice flexibility to get them.
It’s design is much more Django agnostic than the other alternatives and can be used without Django at all. In fact I’ve seen it recommended in a number of more generic overviews of Python feature flag libraries<1><2><3>. That being said it still provides good integration with Django via gutter-django.
The docs describe a really nice looking API too, especially for query flags
based on generic collections of objects. It also could use a variety of
persistence backends including Django, Redis or any object which provides the
Then I discovered it’s Python 2 only! Doh! So much for that.
So now what
Well, so much for it being an easy decision. I’m probably over-thinking it. Had I not discovered gutter I wouldn’t have got excited about it’s architecture and then subsequently hung up on what waffle and gargoyle-yplan don’t have.
My next steps are to reconsider some of the other options in the comparison matrix to see if any options look close to gutter. gargoyle-yplan was the evolutionary ancestor to gutter so maybe I can settle. Otherwise waffle has the more active community it seems.
I’ll let you guys know how it works out.Go Top