Fuge, an Erlang Port of GitHub's Scientist Library

GitHub Erlang   2016-02-18 23:27:37 发布
您的评价:
     
0.0
收藏     0收藏
文件夹
标签
(多个标签用逗号分隔)

来自: https://github.com/sthadka/fuge

fuge

fuge is an Erlang library for carefully refactoring critical paths. Fuge allows you to implement Branch by Abstraction in production.

Inspiration

See the excellent GitHub Scientist Post on why this pattern is useful.

Github Scientist Ruby library

Features

Current set of features supported by fuge:

  • Run old code alongside one or multiple versions of new code. fuge runs all the versions of the code provided and provides results in a stable order. Only the result of the control code is returned.
  • Compare the results of each version. The output of each of version executed is available for comparison.
  • Get run time for each version. Run time allows us to compare and see which version of the code is faster.
  • The different code versions are run in a random order. This allows us to average out the advantage/disadvantage of the code's run order.
  • Subscriber model for publishing information. fuge is agnostic to how results are used afterwards and is extensible using subscribers. fuge also provides a way to maintain state for each subscriber, removing the necessity of making the subscriber a process with state.
  • Allows context information for every run. Context information can allow debugging the performance difference and it is passed on to the subscribers as is.

Warning

Please keep the following in mind before using fuge in production!

  • fuge is currently in alpha stage and in heavy development.
  • fuge is to be run only on code without side effects and code that is idempotent.
  • While fuge itself has a very low overhead (one ETS read, timing information, one gen_server cast), running multiple versions of the code in production will have a performance hit.

Usage

We try to find the sum of consecutive numbers for illustration.

% Start fuge application
1> application:start(fuge).
ok
% Create a new fuge
2> fuge:new(my_fuge).
ok
% Control code
3> Control = fun () -> lists:sum(lists:seq(1, 1000)) end.
#Fun<erl_eval.20.54118792>
% Candidate code
4> Candidate = fun() -> 1000 * (1000 + 1) div 2 end.
#Fun<erl_eval.20.54118792>
% Run the experiment
5> fuge:run(my_fuge, Control, Candidate).
500500

Output with the default logging subscriber:

=INFO REPORT==== 18-Feb-2016::07:55:22 ===
Fuge: {fuge,my_fuge,[fuge_subscriber_logger],[]}
=INFO REPORT==== 18-Feb-2016::07:55:22 ===
Result: {fuge_result,undefined,
                     {fuge_data,81,500500},
                     [{fuge_data,52,500500}],
                     [0,1]}

In the "Result" portion, we can see that the first version of the code ran in 81 microseconds vs the candidate's 52 microseconds. We can also see that the value "500500" returned by both the versions is the same.

Planned Features

  • Subscribers for different use cases (e.g. graphite)

Roadmap

  • Tests for edge cases
  • Benchmark
  • Run subscribers in separate process to avoid building a queue on fuge_server.
  • Maybe create an example application for clear understanding of usage.
  • Add options to fine tune the run.

扩展阅读

JavaScript port of Ruby library Scientist, carefully refactoring critical paths
Erlang库、资源和实用内容:Awesome Erlang
MQTT物联网协议相关开发库
Emacs包、库等资源集合:Awesome Emacs
免费英文编程电子书集合

为您推荐

实用的Json工具类(Gson)
Fuge, an Erlang Port of GitHub's Scientist Library
高性能JavaScript DOM编程
CefSharp初识--把网页移到桌面的神器
在Word文档里插入HTML或MarkDown的Python工具包

更多

GitHub
Erlang
Erlang开发
相关文档  — 更多
相关经验  — 更多
相关讨论  — 更多