Last active
December 14, 2015 02:39
-
-
Save camshaft/5015469 to your computer and use it in GitHub Desktop.
other experiment ideas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module dependencies | |
*/ | |
var express = require("express") | |
, experiments = require("./experiments"); | |
var app = module.exports = express(); | |
/** | |
* Features | |
*/ | |
// Defaults to [true, false] | |
experiments.feature("validate"); | |
// Multi-variant | |
experiments.feature("loginButtonColor", ["red", "blue", "green", "yellow"]); | |
/** | |
* Configure our app | |
*/ | |
app.configure(function(){ | |
app.use(experiments); | |
}); | |
app.get("/", function(req, res, next){ | |
res.render("view"); | |
}); | |
app.get("/ad-hoc", function(req, res, next) { | |
// We can do ad-hoc features | |
res.feature("welcomeMessage", ["message1", "message2"], function(err) { | |
if(err) return next(err); | |
if(res.features.validate) { | |
// Our validate feature is turned on | |
} | |
else { | |
// It's turned off | |
} | |
res.render("view"); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Module dependencies | |
*/ | |
var pivot = require("pivot"); | |
/** | |
* Expose experiments | |
*/ | |
var experiments = module.exports = pivot(); | |
/** | |
* Store the user's enabled features | |
*/ | |
experiments.serialize(function(features, req, res, next){ | |
res.cookie("pivot", JSON.stringify(features)); | |
next(); | |
}); | |
/** | |
* Get the enabled features for the user | |
*/ | |
experiments.deserialize(function(req, res, next){ | |
next(null, JSON.parse(req.cookies.pivot)); | |
}); | |
/** | |
* Gives the user object to pivot | |
*/ | |
experiment.findUser(function(req, res, next){ | |
next(null, req.user); | |
}); | |
/** | |
* Retrieve feature settings from our backend | |
* | |
* This can be anything: | |
* * JSON file | |
* * API Call (i.e. Product owner service) | |
* * DB Call | |
* | |
* These should really be separate modules so you can have pluggable backends to do this stuff | |
*/ | |
experiments.lookup(function(){ | |
var features = {}; | |
/** | |
* @param {String} name | |
* @param {Array[String]} variants | |
* @param {Function} done | |
*/ | |
return function(name, variants, done){ | |
/** | |
* We can do a few things here: | |
* * Lookup our feature settings locally | |
* * If we dont have it, notify the admin control panel page | |
* * Log outdated features; either ones that should be integrated or ones that should be removed | |
*/ | |
// In this case we'll just look it up locally | |
// This should also look up if the variants have changed | |
if(features[name]) { | |
done(null, features[name]); | |
} | |
else { | |
var feature = features[name] = {}; | |
variants.forEach(function(variant) { | |
// Give it an equal split by default (expects 0 to 1) | |
feature[variant] = 1/variants.length; | |
// We could also give it a list of groups | |
// feature[variant] = ["beta", "admins"]; | |
// or just a single group | |
// feature[variant] = "beta"; | |
}); | |
done(null, features[name]); | |
} | |
}; | |
})()); | |
/** | |
* Tells pivot which variant gets assigned to the user | |
* | |
* @param {String} feature | |
* @param {Object} variants | |
* @param {Object} user | |
* @param {Function} done | |
*/ | |
experiments.assign(function(feature, variants, user, done){ | |
/** | |
* If the variant is a group, we can inspect the `user` object to check where they fall | |
* If the variant is a weight, we can implement our own random assignment algorithm | |
* | |
* The callback expects the name of the variant chosen for the given user | |
*/ | |
// For this example we're just going to assign the first variant to everyone | |
done(null, Object.keys(variants)[0]); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1> | |
<% switch(features.welcomeMessage){ %> | |
<% case "message1": %> | |
"Welcome!" | |
<% break; %> | |
<% case "message2": %> | |
"Hey there Friend!" | |
<% break; %> | |
<% } %> | |
</h1> | |
<div class="login"> | |
<button class="btn btn-<%= features.loginButtonColor %>">Login</button> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="login" data-pivot="'loginButtonColor'"> | |
<button data-pivot-vary="'red'" class="btn btn-red">Login</button> | |
<button data-pivot-vary="'blue'" class="btn btn-blue">Login</button> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The only view engines that would work with this setup are async ones