All Projects → andrewvy → Experiment

andrewvy / Experiment

Licence: mit
🔬 Elixir Library for carefully refactoring critical paths by performing experiments.

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Experiment

Honeyjs
An open source Javascript Honey Pot implementation
Stars: ✭ 20 (+233.33%)
Mutual labels:  library, refactoring
Zlib Ng
zlib replacement with optimizations for "next generation" systems.
Stars: ✭ 807 (+13350%)
Mutual labels:  library
Android Hot Libraries
收集总结 Android 项目中值得推荐的优秀开源项目
Stars: ✭ 755 (+12483.33%)
Mutual labels:  library
Yasumi
The easy PHP Library for calculating holidays
Stars: ✭ 788 (+13033.33%)
Mutual labels:  library
Wild Workouts Go Ddd Example
Complete application to show how to apply DDD, Clean Architecture, and CQRS by practical refactoring of a Go project.
Stars: ✭ 756 (+12500%)
Mutual labels:  refactoring
M3u8
Parser and generator of M3U8-playlists for Apple HLS. Library for Go language. 🎦
Stars: ✭ 800 (+13233.33%)
Mutual labels:  library
Slug Generator
Slug Generator Library for PHP, based on Unicode’s CLDR data
Stars: ✭ 740 (+12233.33%)
Mutual labels:  library
Rulerz
Powerful implementation of the Specification pattern in PHP
Stars: ✭ 827 (+13683.33%)
Mutual labels:  library
Swipeablecard
A simple implementation of swipe card like StreetView
Stars: ✭ 812 (+13433.33%)
Mutual labels:  library
Etl
Embedded Template Library
Stars: ✭ 783 (+12950%)
Mutual labels:  library
Scrollbooster
Enjoyable content drag-to-scroll library
Stars: ✭ 775 (+12816.67%)
Mutual labels:  library
Textfieldboxes
Material Design text field that comes in a box, based on (OLD) Google Material Design guidelines.
Stars: ✭ 760 (+12566.67%)
Mutual labels:  library
Vlany
Linux LD_PRELOAD rootkit (x86 and x86_64 architectures)
Stars: ✭ 804 (+13300%)
Mutual labels:  library
Adafruit sensor
Common sensor library
Stars: ✭ 757 (+12516.67%)
Mutual labels:  library
Devtools
The Hoa\Devtools library.
Stars: ✭ 5 (-16.67%)
Mutual labels:  library
Libssh2
the SSH library
Stars: ✭ 743 (+12283.33%)
Mutual labels:  library
Vuesax Next
Vuesax v4: framework components for Vuejs
Stars: ✭ 773 (+12783.33%)
Mutual labels:  library
Slim.js
Fast & Robust Front-End Micro-framework based on modern standards
Stars: ✭ 789 (+13050%)
Mutual labels:  library
Tfidf
Simple TF IDF Library
Stars: ✭ 6 (+0%)
Mutual labels:  library
Cup
CUP, common useful python-lib. (Currently, Most popular python lib in baidu)
Stars: ✭ 826 (+13666.67%)
Mutual labels:  library

Experiment

Hex.pm Hex.pm Inline docs

Elixir Library for carefully refactoring critical paths, influenced heavily by github/scientist.


Running Elixir in production? ExUnit says all your tests pass? Can't wait to be utilizing the awesome hot-code reloading feature to push up your new changes? Well, hold on there, for critical parts of your application you may need more reassurance.

Experiment allows you to run refactored code side-by-side (concurrently) with your previously written code, compare the outputs of each, and notifying when something didn't return as expected.


Documentation

Documentation is available at http://hexdocs.pm/experiment


Installation

Add Experiment as a dependency to your project.

defp deps do
  [{:experiment, "~> 0.0.3"}]
end

Then run mix deps.get to fetch it.


Usage

Let's say you're refactoring a super important controller. Tests can help, but sometimes you really want to pit your refactored code against your current code.

defmodule App.ImportantAPIController do
  def index(conn, params) do
    widget =
      Experiment.new("returns widget for rendering")
      |> Experiment.test(&func_to_experiment/1, ["foo"])
      |> Experiment.test("Named Experiment", &another_func_to_experiment/0)
      |> Experiment.control(&func_that_works/0)
      |> Experiment.compare(&custom_compare_tests/2)
      |> Experiment.perform_experiment

    render conn, widget: widget
  end

  def func_to_experiment(type) do
    %{type: type}
  end

  def another_func_to_experiment do
    %{type: "bar"}
  end

  def func_that_works do
    %{type: "foo"}
  end

  # Override default behavior which `==` the control and candidate.
  def custom_compare_tests(control, candidate) do
    control.type == candidate.type
  end
end

By default, the default Experiment adapter uses Logger.info for outputting. If an experiment crashes, a stacktrace is provided as it's result.

12:53:14.250 [info]  [Experiment] Example: returns widget for rendering - Test 1

Control: {:ok, :bar}
Candidate: {:ok, :foo}


12:53:14.256 [info]  [Experiment] returns widget for rendering - Test 1

Control: {:ok, :foo}
Candidate: "** (ErlangError) erlang error: ArgumentError\n    test/experiment_test.exs:139: anonymous fn/1 in ExperimentTest.test handles experiment exceptions/1\n    (experiment) lib/experiment/utils.ex:18: anonymous fn/2 in Experiment.Utils.bind/2\n    (experiment) lib/experiment.ex:99: anonymous fn/1 in Experiment.perform_experiment/1\n    (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2\n    (elixir) lib/task/supervised.ex:40: Task.Supervised.reply/5\n    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3\n"

Customizing Adapter

You can define your own Experiment adapter for recording results by using the Experiment.Base module.

defmodule App.ExperimentAdapter do
  use Experiment.Base
  require Logger

  def record(lab, control, candidate) do
    # Get the lab name
    Logger.info lab.name

    # Log out control's result
    Logger.info "#{control.name} - #{inspect control.result}"

    # Log out candidate's result
    Logger.info "#{candidate.name} - #{inspect candidate.result}"

    # Do something with the results, save them to the DB, etc.
  end
end

In your config, you can specify your own Experiment adapter.

config :experiment,
  adapter: App.ExperimentAdapter
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].