You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Pennon is primarily intended for use with Ring, but can also be used elsewhere.
It is based on a few simple concepts, making it highly composable and adaptable.
Usage
Feature flags in Pennon are identified with keywords.
This assumes you are using the Ring middleware and are inside a request handler.
Feature flags are enabled or disabled by "toggles". A toggle is a function that
takes the name of a feature flag, and returns true, false, or nil.
Multiple toggles can be active at once. When a toggle returns true or false it
switches the feature flag on or off. If it returns nil it leaves the feature
flag in whatever state it was left in by previous toggles.
For example, we could have three different toggles configured. One checks if a
feature has been turned on or off globally, one checks if the current user has
the feature enabled, and finally the last one checks for a query parameter that
temporarily enables the features.
The :link-sharing feature is still experimental, but the QA people are trying
it out by adding a query parameter to the URI.
The :reporting feature is mostly ready, and so we have given a few customers
early access in exchange for feedback.
The :new-layout has been rolled out, but it has made a high profile customer
unhappy, so it's been disabled for this customer while we make some fixes.
:link-sharing
:reporting
:new-layout
global
nil
nil
true
user
nil
true
false
query-param
true
nil
nil
(feature? x)
true
true
false
To use Pennon with Ring, use pennon.core/wrap-feature-flags, passing the Ring
handler, the available feature flags, and the toggle factories to use.
A toggle factory is a function that takes a Ring request map, and returns a
toggle, for example:
(defnmy-toggle-factory [req]
(fn [flag]
(= flag :link-sharing)))
This factory is called once per request, the inner function is then called once
for each feature flag. This allows you to toggle based on the current request or
session, and it gives you an opportunity to do one time setup like accessing a
database.
A complete example:
(nsmy-app.core
(:require [pennon.core :refer [wrap-feature-flags feature?]]
[pennon.toggles :refer [query-params-toggle-factory])
[compojure.core :refer [defroutes GET]]))
(deffeatures #{:link-sharing:reporting:new-layout})
(defdefault-enabled-flags #{:new-layout})
(defndb-toggle-factory [_]
(let [enabled-features (db-fetch-enabled-features)]
(fn [flag]
(some #{flag} enabled-features))))
(defnuser-toggle-factory [req]
(let [enabled-features (fetch-user-features (-> req :session::identity)]
(fn [flag]
(some #{flag} enabled-features))))
(deffeature-toggles
[(constantlydefault-enabled-flags) ;; use of a set as a hard-coded toggle function
db-toggle-factory
user-toggle-factory
query-params-toggle-factory ;; provided by pennon.toggles, checks for flag_on=.. and flag_off=... request params
])
(defroutesroutes
(GET"/" [] (if (feature?:link-sharing) ,,, ) ))
(defhttp-handler
(-> routes
(wrap-feature-flags features feature-toggles)))
Use outside Ring
The feature? function checks pennon.core/*features*. The Ring middleware
takes care of binding this. If you are using Pennon elsewhere you have to make
sure that somewhere up the stack you wrap your code in a binding form.
This is only a short summary of the Full Text, this information is not legal advice.
MPL is a copyleft license that works on individual files. Any changes you make to files covered by MPL must be made available under MPL, but you may combine these with non-MPL (proprietary) source files in the same project. Version 2.0 is compatible with GPL version 3. You can distribute binaries under a proprietary license, as long as you make the source available under MPL.