dl_experiment 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/dl_experiment.rb +2 -0
  3. data/lib/experiment.rb +105 -0
  4. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f959d8602ba46ba1ebd32da595018a01b78a096865c9a8f6af1e4535965b9ae8
4
+ data.tar.gz: 443240e50b6d2c06d7bd4cebf74711b73729bb1e9d1cafba36b2b00abb741d6b
5
+ SHA512:
6
+ metadata.gz: c54557eddb3a13195b894dfc5387879d34012cfc6d01edcaf5d6f9c93c312933bb44d2c102688fcc71f9600a676430ee735152c5298c45ac0ced8f38b800ade0
7
+ data.tar.gz: 5cc327f74240af73e07b3fff02f034f9158c3e2c0d4249fd9305f06e33742278a63f9fee5a76393b3270d9d4a6912f41c7a314328c088cea4a40631df3640933
@@ -0,0 +1,2 @@
1
+ require 'experiment'
2
+
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Experiment
4
+ class << self
5
+ def protocol(name)
6
+ name = String(name)
7
+ raise('Please provide an experiment name') if name.empty?
8
+ experiment = Experiment.new(name)
9
+ yield(experiment)
10
+ experiment.raise_on_diff! if rails_test_mode?
11
+ experiment.result
12
+ end
13
+
14
+ def rails_test_mode?
15
+ defined?(Rails) && Rails.env.test?
16
+ end
17
+ end
18
+
19
+ class Result
20
+ attr_accessor :value, :error
21
+ def initialize(value: nil, error: nil)
22
+ self.value = value
23
+ self.error = error
24
+ end
25
+ end
26
+
27
+ DEFAULT_COMPARISON = ->(legacy, experiment) { legacy == experiment }
28
+ DEFAULT_ENABLER = -> { true }
29
+
30
+ def initialize(name)
31
+ @name = name
32
+ @compare_with = DEFAULT_COMPARISON
33
+ @enable = DEFAULT_ENABLER
34
+ end
35
+
36
+ def legacy(&block)
37
+ raise 'Missing block' unless block
38
+ @legacy = block
39
+ self
40
+ end
41
+
42
+ def experiment(&block)
43
+ raise 'Missing block' unless block
44
+ @experiment = block
45
+ self
46
+ end
47
+
48
+ def compare_with(&block)
49
+ raise 'Missing block' unless block
50
+ @compare_with = block
51
+ self
52
+ end
53
+
54
+ def enable(&block)
55
+ raise 'Missing block' unless block
56
+ @enable = block
57
+ self
58
+ end
59
+
60
+ def on_diff(&block)
61
+ raise 'Missing block' unless block
62
+ @on_diff = block
63
+ self
64
+ end
65
+
66
+ def result
67
+ raise 'Please call the legacy helper in your protocol block' unless @legacy
68
+ raise 'Please call the experiment helper in your protocol block' unless @experiment
69
+ legacy_result = exec(@legacy)
70
+ return forward(legacy_result) unless self.class.rails_test_mode? || @enable.call
71
+ experiment_result = exec(@experiment)
72
+ if @on_diff
73
+ if legacy_result.error.class != experiment_result.error.class ||
74
+ legacy_result.error&.message != experiment_result.error&.message ||
75
+ !@compare_with.call(legacy_result.value, experiment_result.value)
76
+ @on_diff.call(legacy_result, experiment_result)
77
+ end
78
+ end
79
+ forward(legacy_result)
80
+ end
81
+
82
+ def raise_on_diff!
83
+ on_diff do |legacy_result, experiment_result|
84
+ raise ExperimentError,
85
+ "Experiment: #{@name}; "\
86
+ "Legacy result: #{legacy_result.inspect}; "\
87
+ "Experiment result: #{experiment_result.inspect}"
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def forward(result)
94
+ raise result.error if result.error
95
+ result.value
96
+ end
97
+
98
+ def exec(block)
99
+ Result.new(value: block.call)
100
+ rescue StandardError => error
101
+ Result.new(error: error)
102
+ end
103
+
104
+ class ExperimentError < StandardError; end
105
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dl_experiment
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexandre Ignjatovic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-12-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A framework meant to help you test (in production or in tests) the impact
14
+ of an iso functional change
15
+ email: alexandre.ignjatovic@doctolib.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/dl_experiment.rb
21
+ - lib/experiment.rb
22
+ homepage: https://rubygems.org/gems/hola
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: A mini scientist-like framework
45
+ test_files: []