Scientist gem 조사
15536 단어 scientistRubyRefactoring
About scientist
과학tistgem은github사가 제작한 테스트 도구(=새로운 논리 실험을 할 수 있는 도구)이다.
Let's pretend you're changing the way you handle permissions in a large web app. Tests can help guide your refactoring, but you really want to compare the current and refactored behaviors under load.
심정으로 삼다
테스트가 팩스를 통과한 결과 식별 동작에 문제가 없을 때 매우 유용하지만 현행과 팩스 후의 행위가 정말 변했는지 비교할 수 없다.
통절히 알다.
왜?
Febrary032016 Scientist 1.0과 함께 발표된 후편
http://githubengineering.com/scientist/
대규모 팩스Branch by Abstraction를 위해서요.단, Abstraction layer를 넣으면 코드 path가 원래와 다르기 때문에 Refactor 후 이전 행동 테스트 방법과는 견고하지 않습니다.
- 예컨대 예상치 못한 곳에서 부르면 abstraction layer는 통과하지 않겠죠?
시험이 왜 불충분한가
- 매우 복잡한 시스템으로는 테스트 용례를 망라할 수 없다.망라를 해보면 테스트량이 많아지고 개발 속도가 떨어져요
- 원래 존재하는 데이터의 질에 문제가 있을 수 있습니다.나는 그런 데이터에 부딪혔을 때의 행동거지를 모른다.
따라서 Production data와 User는 시험이 필요합니다.
특징.
코드 path를 바꾸지 않고 제품 데이터의 행동을 테스트할 수 있습니다.
새로운 기능을 테스트하려면 다음과 같은 기분이 좋습니다.
Getting Started
Sample Code: https://github.com/threetreeslight/rails-lab/tree/scientist
다음 관계에 대한 Rails 애플리케이션에 대해 살펴보겠습니다.Author 1-* Book
또한 과학자의method는 다음과 같습니다.class Author < ApplicationRecord
def luckey_number
id
end
end
oldway와 newway의 비교 메커니즘 구축
old way(기존 설치)와 new way(팩스 후 설치)class Author < ApplicationRecord
def luckey_number
experiment = Scientist::Default.new "book.lucky_number"
experiment.context author: id, name: name
experiment.use { id } # old way
experiment.try { rand(10) } # new way
experiment.run
end
end
luckey_number는use block과try block을 실행합니다.
이렇게 하면 새로 실시한 수익치와 다르다는 것을 검증할 수 있다.
또한,experiment는useblock의 실행 결과를 되돌려야 합니다.
try 실행 제어 및 게시
Scientist::Default
try의 실행 제어와compare 결과를 발송합니다.Scientist::Default
class는Scientist::Experiment
용Interface의 임시 실현이기 때문에 실제적으로 어떠한 제어와 발송도 하지 않습니다.
https://github.com/github/scientist/blob/master/lib/scientist/default.rb
따라서 전용 experment를 제작한다.class MyExperiment < Scientist::Default
def publish(result)
# Store the timing for the control value,
StatsD.measure "science.#{name}.control", result.control.duration
# for the candidate (only the first, see "Breaking the rules" below,
StatsD.measure "science.#{name}.candidate", result.candidates.first.duration
# and counts for match/ignore/mismatch:
if result.matched?
StatsD.increment "science.#{name}.matched"
elsif result.ignored?
StatsD.increment "science.#{name}.ignored"
else
StatsD.increment "science.#{name}.mismatched"
# Finally, store mismatches in redis so they can be retrieved and examined
# later on, for debugging and research.
store_mismatch_data(result)
end
end
def store_mismatch_data(result)
payload = {
:name => name,
:context => context,
:control => observation_payload(result.control),
:candidate => observation_payload(result.candidates.first),
:execution_order => result.observations.map(&:name)
}
key = "science.#{name}.mismatch"
Rails.logger.warn "#{key}: #{payload}"
REDIS.lpush key, payload
REDIS.ltrim key, 0, 1000
end
def observation_payload(observation)
if observation.raised?
{
:exception => observation.exception.class,
:message => observation.exception.message,
:backtrace => observation.exception.backtrace
}
else
{
# see "Keeping it clean" below
:value => observation.cleaned_value
}
end
end
end
여기서 아래의 내용을 측정하고 있다.
Sample Code: https://github.com/threetreeslight/rails-lab/tree/scientist
다음 관계에 대한 Rails 애플리케이션에 대해 살펴보겠습니다.
Author 1-* Book
또한 과학자의method는 다음과 같습니다.class Author < ApplicationRecord
def luckey_number
id
end
end
oldway와 newway의 비교 메커니즘 구축
old way(기존 설치)와 new way(팩스 후 설치)
class Author < ApplicationRecord
def luckey_number
experiment = Scientist::Default.new "book.lucky_number"
experiment.context author: id, name: name
experiment.use { id } # old way
experiment.try { rand(10) } # new way
experiment.run
end
end
luckey_number는use block과try block을 실행합니다.이렇게 하면 새로 실시한 수익치와 다르다는 것을 검증할 수 있다.
또한,experiment는useblock의 실행 결과를 되돌려야 합니다.
try 실행 제어 및 게시
Scientist::Default
try의 실행 제어와compare 결과를 발송합니다.Scientist::Default
class는Scientist::Experiment
용Interface의 임시 실현이기 때문에 실제적으로 어떠한 제어와 발송도 하지 않습니다.https://github.com/github/scientist/blob/master/lib/scientist/default.rb
따라서 전용 experment를 제작한다.
class MyExperiment < Scientist::Default
def publish(result)
# Store the timing for the control value,
StatsD.measure "science.#{name}.control", result.control.duration
# for the candidate (only the first, see "Breaking the rules" below,
StatsD.measure "science.#{name}.candidate", result.candidates.first.duration
# and counts for match/ignore/mismatch:
if result.matched?
StatsD.increment "science.#{name}.matched"
elsif result.ignored?
StatsD.increment "science.#{name}.ignored"
else
StatsD.increment "science.#{name}.mismatched"
# Finally, store mismatches in redis so they can be retrieved and examined
# later on, for debugging and research.
store_mismatch_data(result)
end
end
def store_mismatch_data(result)
payload = {
:name => name,
:context => context,
:control => observation_payload(result.control),
:candidate => observation_payload(result.candidates.first),
:execution_order => result.observations.map(&:name)
}
key = "science.#{name}.mismatch"
Rails.logger.warn "#{key}: #{payload}"
REDIS.lpush key, payload
REDIS.ltrim key, 0, 1000
end
def observation_payload(observation)
if observation.raised?
{
:exception => observation.exception.class,
:message => observation.exception.message,
:backtrace => observation.exception.backtrace
}
else
{
# see "Keeping it clean" below
:value => observation.cleaned_value
}
end
end
end
여기서 아래의 내용을 측정하고 있다.Redis
$ vim config/initialize/redis.rb
require 'redis'
REDIS = Redis.new(url: ENV['REDIS_URL'])
metric
Giithub의 Sample은 메트릭을 그레이트에 넣었다고 한다.
metric의 인터페이스는 statsd 호환됩니다
brubeck를 사용한다고 하는데, 이번statsd로 갑니다.
설정이 번거롭기 때문에graphite와statsd의 설정이 번거롭기 때문에 이 그림을 사용했습니다.
https://github.com/hopsoft/docker-graphite-statsd
statusD의 유입에 사용되었다Shopify/statsd-instrument.
$ vim config/initialize/status_d.rb
require 'statsd-instrument'
# Sets up a UDP backend. First argument is the UDP address to send StatsD packets to,
# second argument specifies the protocol variant (i.e. `:statsd`, `:statsite`, or `:datadog`).
StatsD.backend = StatsD::Instrument::Backends::UDPBackend.new(ENV['STATSD_URL'], :statsite)
ref graphite의 장점Macerel의 시간 시퀀스 데이터베이스 기술 지원제작된 Experiment의 용도
class Author < ApplicationRecord
has_many :books
def luckey_number
+ experiment = Scientist::Experiment.new "book.lucky_number"
experiment.context author: id, name: name
experiment.use { id } # old way
experiment.try { rand(10) } # new way
experiment.run
end
end
+ module Scientist::Experiment
+ def self.new(name)
+ MyExperiment.new(name)
+ end
+ end
실행
$ docker-compose up --build -d app
$ docker-compose exec app bash
> rails c
> 100.times{ Author.first.luckey_number }
Author Load (2.5ms) SELECT "authors".* FROM "authors" ORDER BY "authors"."id" ASC LIMIT ? [["LIMIT", 1]]
{:name=>{:name=>"book.lucky_number"}, :context=>{:author=>1, :name=>"Chuck norris"}, :control=>{:value=>1}, :candidate=>{:value=>6},:execution_order=>["control", "candidate"]}
=> 1
실행 metric
$ open http://`dinghy ip`:8080/dashboard
노력하면 github 블로그에 이런 게 있어요.작은 실패 데이터 on redis
$ docker-compose exec app bash
> radis-cli -h redis
redis:6379> KEYS science.*
1) "science.book.lucky_number.mismatch"
redis:6379> LRANGE science.book.lucky_number.mismatch 0 -1
1) "{:name=>\"book.lucky_number\", :context=>{:author=>1, :name=>\"Chuck norris\"}, :control=>{:value=>1}, :candidate=>{:value=>8}, :execution_order=>[\"control\", \"candidate\"]}"
2) "{:name=>\"book.lucky_number\", :context=>{:author=>1, :name=>\"Chuck norris\"}, :control=>{:value=>1}, :candidate=>{:value=>7}, :execution_order=>[\"candidate\", \"control\"]}"
3) "{:name=>\"book.lucky_number\", :context=>{:author=>1, :name=>\"Chuck norris\"}, :control=>{:value=>1}, :candidate=>{:value=>0}, :execution_order=>[\"candidate\", \"control\"]}"
오피스
개인이 생각하는 사용 장소는 다음과 같다.
한결
등도 새로운 논리의 집행을 제어할 수 있다.사용이 편리하다.
코드 흐름 ├── scientist
│ ├── default.rb
│ ├── errors.rb
│ ├── experiment.rb
│ ├── observation.rb
│ ├── result.rb
│ └── version.rb
└── scientist.rb
라인 수량은 별거 아니에요.
동작도 매우 간단하다.
├── scientist
│ ├── default.rb
│ ├── errors.rb
│ ├── experiment.rb
│ ├── observation.rb
│ ├── result.rb
│ └── version.rb
└── scientist.rb
Scientist::Default
이라면 작성Scientist::Result
Scientist::Result
의 정보를 배포Reference
이 문제에 관하여(Scientist gem 조사), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ThreeTreesLight/items/9529857cbc7fbbcf01bc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)