site address:
web.archive.org/web/20210817161003/https://github.com/github/scientist redirected to: web.archive.org/web/20210817202640/https://github.com/github/scientist
site title:
GitHub - github/scientist: A Ruby library for carefully refactoring critical paths.
|
|
|
Our opinion (on Friday 02 October 2026 9:12:57 UTC):
- no comments
|
|
|
|
After content analysis of this website we propose the following hashtags:
|
|
|
|
Meta tags:
description= :microscope: A Ruby library for carefully refactoring critical paths. - GitHub - github/scientist: A Ruby library for carefully refactoring critical paths.;
Headings (most frequently used words):
scientist, launching, github, science, ignoring, experiments, results, errors, an, experiment, and, desktop, code, in, latest, commit, git, stats, files, readme, md, how, do, making, useful, breaking, the, rules, hacking, wrappers, alternatives, maintainers, about, releases, packages, used, by, 58, contributors, 47, languages, controlling, comparison, adding, context, expensive, setup, keeping, it, clean, mismatches, enabling, disabling, ramping, up, publishing, testing, handling, designing, finishing, entirely, trying, more, than, one, thing, no, control, just, candidates, without, including, topics, resources, license, learn, contribute, connect, with, others, xcode, visual, studio, custom, mismatch, candidate, callback, noise, error, rates, providing, fake, timing, data,
Text of the page (most frequently used words):
the (108), #scientist (76), #experiment (61), end (59), and (54), you (43), try (37), user (35), science (31), for (30), control (29), use (28), this (26), candidate (25), can (23), result (23), github (22), name (22), def (22), with (20), your (18), run (18), include (18), code (18), will (18), class (18), new (17), block (17), exception (17), that (16), method (16), raised (16), all (15), model (15), when (15), behavior (14), results (13), widget (13), default (13), data (13), way (13), ruby (12), but (12), ignore (12), mismatch (12), observation (11), publish (11), context (11), permissions (10), blocks (10), any (10), error (10), clean (10), value (10), read (9), not (9), more (9), myexperiment (9), mismatches (9), compare (9), enabled (9), test (8), using (8), values (8), timing (8), useful (8), always (8), time (7), about (7), 2021 (7), are (7), check_user (7), candidates (7), one (7), may (7), experiments (7), only (7), don (7), tags (6), refactoring (6), valid (6), than (6), nothing (6), first (6), mywidget (6), add (6), some (6), operation (6), raise (6), message (6), version (6), library (5), carefully (5), paths (5), here (5), instead (5), allows (5), exceptions (5), entirely (5), how (5), observations (5), match (5), return (5), from (5), run_if (5), map (5), statsd (5), see (5), staff (5), returns (5), users (5), again (5), load (5), feb (5), desktop (5), branches (5), jump (5), security (4), published (4), license (4), readme (4), critical (4), node (4), runs (4), tests (4), need (4), call (4), without (4), like (4), cleaner (4), duration (4), these (4), just (4), second (4), helper (4), also (4), define (4), old (4), require (4), sometimes (4), whether (4), true (4), ignoring (4), back (4), every (4), both (4), was (4), called (4), errors (4), custom (4), implementation (4), redis (4), key (4), store (4), below (4), percent_enabled (4), want (4), admin (4), instances (4), expensive (4), web (4), commit (4), pull (4), launching (4), download (4), api (3), packages (3), typescript (3), perl (3), controlling (3), available (3), newer (3), place (3), aren (3), module (3), including (3), names (3), execution (3), trying (3), thing (3), fabricate_durations_for_testing_purposes (3), writing (3), various (3), behaviors (3), good (3), idea (3), isn (3), via (3), breaking (3), rules (3), system (3), has (3), production (3), there (3), order (3), which (3), invoked (3), raise_on_mismatches (3), failed (3), handle (3), callback (3), rescues (3), list (3), mismatcherror (3), know (3), testing (3), keeping (3), observation_payload (3), later (3), increment (3), example (3), publishing (3), wrap (3), request (3), ramping (3), disabling (3), yet (3), login (3), userservice (3), value_for_new_code (3), setup (3), set_default (3), view (3), 2019 (3), mar (3), latest (3), open (3), happens (3), actions (3), issues (3), sign (3), repository (3), signed (2), another (2), tab (2), window (2), refresh (2), session (2), reload (2), pricing (2), contact (2), contributors (2), mit (2), topics (2), zerowidth (2), maintainers (2), java (2), lab (2), lancew (2), laboratory (2), truewill (2), net (2), alternatives (2), wrappers (2), make (2), automatically (2), requires (2), script (2), hacking (2), where (2), able (2), probably (2), won (2), come (2), normal (2), usage (2), takes (2), hash (2), keyed (2), override (2), actual (2), provide (2), durations (2), report (2), providing (2), fake (2), ways (2), turn (2), raw (2), alternative (2), once (2), simultaneously (2), guaranteed (2), reporting (2), get (2), still (2), even (2), care (2), have (2), often (2), setting (2), stuff (2), understand (2), removing (2), keep (2), write (2), between (2), until (2), been (2), different (2), finishing (2), such (2), false (2), noise (2), rates (2), modify (2), systems (2), verify (2), during (2), find (2), our (2), running (2), reason (2), changing (2), designing (2), internal (2), symbol (2), replace (2), set (2), handling (2), custommismatcherror (2), diffs (2), diff (2), suite (2), help (2), cleaned_value (2), above (2), else (2), backtrace (2), payload (2), store_mismatch_data (2), debugging (2), they (2), ignored (2), matched (2), its (2), must (2), 100 (2), initialize (2), attr_accessor (2), say (2), configured (2), enabling (2), doesn (2), considered (2), analysis (2), needed (2), alice (2), bob (2), carol (2), value_for_original_code (2), big_object (2), before_run (2), under (2), destruction (2), adding (2), compares (2), comparison (2), included (2), really (2), none (2), making (2), information (2), around (2), support (2), lower (2), nov (2), 2014 (2), contributing (2), drop (2), versions (2), matrix (2), git (2), 3fb138b (2), olleolleolle (2), patch (2), 150 (2), merge (2), codespace (2), xcode (2), cli (2), learn (2), https (2), refname (2), show (2), could (2), insights (2), projects (2), requests (2), notifications (2), star (2), 432 (2), stars (2), education (2), plans (2), explore (2), sep (2), out, perform, action, blog, training, docs, status, privacy, terms, inc, shell, languages, used, releases, resources, rubygem, rick, jesseplusplus, jbarnette, browser, fightmegg, aws, lambda, serverless, swift, junkpiano, kotlin, spoptchev, jelmersnoeck, calavera, elixir, cwbriones, madcapjake, scientistp6, clojure, yeller, deno, paleontologist, tzientist, es6, ziyasal, trello, tomiaijo, rawls238, scientist4j, python, joealcorn, scientistproject, php, daylerees, rails, engine, storing, analyzing, activerecord, realgeeks, lab_tech, unixy, box, sure, modern, bundler, unit, development, dependencies, installed, easier, extends, uses, shown, matching, provided, reported, absolutely, suspicious, happening, depend, specific, canned, times, knows, trick, named, omit, pass, tested, each, compared, query, can_sql, sql, service, usually, isolated, visualization, quite, bit, harder, log, disregard, path, blew, ability, incrementally, silently, altogether, greater, efficiency, scientists, gotta, weird, side, duplication, well, after, case, roll, unacceptable, remove, resolve, ongoing, perfectly, converges, controls, start, thinking, mind, sequentially, random, upon, depends, change, before, potentially, yielding, calibrate, expectations, respect, arising, systemic, conditions, external, proposed, changes, consider, starting, invoke, then, proceed, introducing, negatives, found, most, existing, anywhere, writes, happen, ensure, correct, written, reviewing, helped, situations, overlooked, runtime, reading, two, reconciliation, scripts, alongside, because, determine, impossible, guarantee, safe, wrapping, methods, operations, handled, failure, track, internalerrortracker, within, helpers, simply, since, halts, better, continue, whole, canceled, standarderror, tracks, rescuing, cause, unexpected, rescue, restrictive, scripterror, systemexit, pre, processing, messages, raise_with, fetch, reportservice, join, to_s, instruct, helpful, experimental, defines, attribute, 1000, ltrim, lpush, execution_order, research, finally, retrieved, examined, mismatched, elsif, counts, given, instance, associated, implement, however, sent, graphite, placed, capped, collection, what, sensitive, performance, database, levels, caching, memcache, per, thread, locals, rand, important, off, lest, amok, villagers, pitchforks, doorstep, current_user, members, dashboard, items, dashboard_items, dashboardcontroller, codepath, anyone, who, disable, merely, otherwise, defers, raises, other, confirmed_email, unconfirmed, early, stages, possible, generate, reasons, haven, fixed, known, cases, showing, metrics, tell, note, discard, previous, access, currently, further, ado, comes, handy, runner, provides, cleaners, cleaned, final, sort, full, researching, logins, new_code, original_code, deep_copy, worthwhile, nil, modifies, copy, should, occur, going, their, contexts, self, default_scientist_context, new_safe_destroy, old_scary_destroy, destroy, extra, lot, very, identify, them, retrieve, observed, now, calls, sets, skipped, super, inspect, examples, anything, doing, declare, machinery, returned, creating, wordy, instantiate, publishes, swallow, record, overriding, measures, seconds, randomizes, decides, original, whatever, does, bunch, behind, scenes, let, pretend, large, app, guide, current, refactored, gemspec, documentation, explaining, txt, gemfile, 2018, fix, typo, eold, travis, yml, 2016, added, coveralls, coverage, tracking, gitignore, modules, lib, apr, update, changelog, release, doc, type, permalink, files, commits, 186, stats, eol, problem, preparing, please, ready, visual, studio, zip, work, fast, official, checkout, svn, url, clone, switch, master, forks, fork, organization, suggested, sales, marketplace, program, community, forum, events, project, connect, others, source, guides, learning, trending, collections, contribute, enterprise, team, customer, stories, sponsors, integrations, review, codespaces, mobile, features, why, skip, content, wayback, machine, http, archive, org, 20210817202640, com, timestamps, capture, fail, success, 2022, 2020, aug, jul, 2015, 2026, 836, captures,
Text of the page (random words):
is called the control the try block is called the candidate creating an experiment is wordy but when you include the scientist module the science helper will instantiate an experiment and call run for you require scientist class mywidget include scientist def allows user science widget permissions do experiment experiment use model check_user user valid old way experiment try user can read model new way end returns the control value end end if you don t declare any try blocks none of the scientist machinery is invoked and the control value is always returned making science useful the examples above will run but they re not really doing anything the try blocks don t run yet and none of the results get published replace the default experiment implementation to control execution and reporting require scientist experiment class myexperiment include scientist experiment attr_accessor name def initialize name name name end def enabled see ramping up experiments below true end def raised operation error see in a scientist callback below p operation operation failed with error error inspect super will re raise end def publish result see publishing results below p result end end when scientist experiment is included in a class it automatically sets it as the default implementation via scientist experiment set_default this set_default call is is skipped if you include scientist experiment in a module now calls to the science helper will load instances of myexperiment controlling comparison scientist compares control and candidate values using to override this behavior use compare to define how to compare observed values instead class mywidget include scientist def users science users do e e use user all returns user instances e try userservice list returns userservice user instances e compare do control candidate control map login candidate map login end end end end adding context results aren t very useful without some way to identify them use the context method to add to or retrieve the context for an experiment science widget permissions do e e context user user e use model check_user user valid e try user can read model end context takes a symbol keyed hash of extra data the data is available in experiment publish via the context method if you re using the science helper a lot in a class you can provide a default context class mywidget include scientist def allows user science widget permissions do e e context user user e use model check_user user valid e try user can read model end end def destroy science widget destruction do e e use old_scary_destroy e try new_safe_destroy end end def default_scientist_context widget self end end the widget permissions and widget destruction experiments will both have a widget key in their contexts expensive setup if an experiment requires expensive setup that should only occur when the experiment is going to be run define it with the before_run method code under test modifies this in place we want to copy it for the candidate code but only when needed value_for_original_code big_object value_for_new_code nil science expensive but worthwhile do e e before_run do value_for_new_code big_object deep_copy end e use original_code value_for_original_code e try new_code value_for_new_code end keeping it clean sometimes you don t want to store the full value for later analysis for example an experiment may return user instances but when researching a mismatch all you care about is the logins you can define how to clean these values in an experiment class mywidget include scientist def users science users do e e use user all e try userservice list e clean do value value map login sort end end end end and this cleaned value is available in observations in the final published result class myexperiment include scientist experiment def publish result result control value user alice user bob user carol result control cleaned_value alice bob carol end end note that the clean method will discard the previous cleaner block if you call it again if for some reason you need to access the currently configured cleaner block scientist experiment cleaner will return the block without further ado this probably won t come up in normal usage but comes in handy if you re writing say a custom experiment runner that provides default cleaners ignoring mismatches during the early stages of an experiment it s possible that some of your code will always generate a mismatch for reasons you know and understand but haven t yet fixed instead of these known cases always showing up as mismatches in your metrics or analysis you can tell an experiment whether or not to ignore a mismatch using the ignore method you may include more than one block if needed def admin user science widget permissions do e e use model check_user user admin e try user can admin model e ignore user staff user is staff always an admin in the new system e ignore do control candidate new system doesn t handle unconfirmed users yet control candidate user confirmed_email end end end the ignore blocks are only called if the values don t match if one observation raises an exception and the other doesn t it s always considered a mismatch if both observations raise different exceptions that is also considered a mismatch enabling disabling experiments sometimes you don t want an experiment to run say disabling a new codepath for anyone who isn t staff you can disable an experiment by setting a run_if block if this returns false the experiment will merely return the control value otherwise it defers to the experiment s configured enabled method class dashboardcontroller include scientist def dashboard_items science dashboard items do e only run this experiment for staff members e run_if current_user staff end end ramping up experiments as a scientist you know it s always important to be able to turn your experiment off lest it run amok and result in villagers with pitchforks on your doorstep in order to control whether or not an experiment is enabled you must include the enabled method in your scientist experiment implementation class myexperiment include scientist experiment attr_accessor name percent_enabled def initialize name name name percent_enabled 100 end def enabled percent_enabled 0 rand 100 percent_enabled end end this code will be invoked for every method with an experiment every time so be sensitive about its performance for example you can store an experiment in the database but wrap it in various levels of caching such as memcache or per request thread locals publishing results what good is science if you can t publish your results you must implement the publish result method and can publish data however you like for example timing data can be sent to graphite and mismatches can be placed in a capped collection in redis for debugging later the publish method is given a scientist result instance with its associated scientist observation s class myexperiment include scientist experiment def publish result store the timing for the control value statsd timing science name control result control duration for the candidate only the first see breaking the rules below statsd timing 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 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 above value observation cleaned_value end end end testing when running your test suite it s helpful to know that the experimental results always match to help with testing scientist defines a raise_on_mismatches class attribute when you include scientist experiment only do this in your test suite to raise on mismatches class myexperiment include scientist experiment implementation end myexperiment raise_on_mismatches true scientist will raise a scientist experiment mismatcherror exception if any observations don t match custom mismatch errors to instruct scientist to raise a custom error instead of the default scientist experiment mismatcherror class custommismatcherror scientist experiment mismatcherror def to_s message there was a mismatch here s the diff diffs result candidates map do candidate diff new result control candidate end join n message n diffs end end science widget permissions do e e use report find id e try reportservice new fetch id e raise_with custommismatcherror end this allows for pre processing on mismatch error exception messages handling errors in candidate code scientist rescues and tracks all exceptions raised in a try or use block including some where rescuing may cause unexpected behavior like systemexit or scripterror to rescue a more restrictive set of exceptions modify the rescues list default is exception scientist observation rescues replace standarderror in a scientist callback if an exception is raised within any of scientist s internal helpers like publish compare or clean the raised method is called with the symbol name of the internal operation that failed and the exception that was raised the default behavior of scientist default is to simply re raise the exception since this halts the experiment entirely it s often a better idea to handle this error and continue so the experiment as a whole isn t canceled entirely class myexperiment include scientist experiment def raised operation error internalerrortracker track science failure in name operation error end end the operations that may be handled here are clean an exception is raised in a clean block compare an exception is raised in a compare block enabled an exception is raised in the enabled method ignore an exception is raised in an ignore block publish an exception is raised in the publish method run_if an exception is raised in a run_if block designing an experiment because enabled and run_if determine when a candidate runs it s impossible to guarantee that it will run every time for this reason scientist is only safe for wrapping methods that aren t changing data when using scientist we ve found it most useful to modify both the existing and new systems simultaneously anywhere writes happen and verify the results at read time with science raise_on_mismatches has also been useful to ensure that the correct data was written during tests and reviewing published mismatches has helped us find any situations we overlooked with our production data at runtime when writing to and reading from two systems it s also useful to write some data reconciliation scripts to verify and clean up production data alongside any running experiments noise and error rates keep in mind that scientist s try and use blocks run sequentially in random order as such any data upon which your code depends may change before the second block is invoked potentially yielding a mismatch between the candidate and control return values to calibrate your expectations with respect to false negatives arising from systemic conditions external to your proposed changes consider starting with an experiment in which both the try and use blocks invoke the control method then proceed with introducing a candidate finishing an experiment as your candidate behavior converges on the controls you ll start thinking about removing an experiment and using the new behavior if there are any ignore blocks the candidate behavior is guaranteed to be different if this is unacceptable you ll need to remove the ignore blocks and resolve any ongoing mismatches in behavior until the observations match perfectly every time when removing a read behavior experiment it s a good idea to keep any write side duplication between an old and new system in place until well after the new behavior has been in production in case you need to roll back breaking the rules sometimes scientists just gotta do weird stuff we understand ignoring results entirely science is useful even when all you care about is the timing data or even whether or not a new code path blew up if you have the ability to incrementally control how often an experiment runs via your enabled method you can use it to silently and carefully test new code paths and ignore the results altogether you can do this by setting ignore true or for greater efficiency compare true this will still log mismatches if any exceptions are raised but will disregard the values entirely trying more than one thing it s not usually a good idea to try more than one alternative simultaneously behavior isn t guaranteed to be isolated and reporting visualization get quite a bit harder still it s sometimes useful to try more than one alternative at once add names to some try blocks require scientist class mywidget include scientist def allows user science widget permissions do e e use model check_user user valid old way e try api user can read model new service api e try raw sql user can_sql read model raw query end end end when the experiment runs all candidate behaviors are tested and each candidate observation is compared with the control in turn no control just candidates define the candidates with named try blocks omit a use and pass a candidate name to run experiment myexperiment new various ways do e e try first way e try second way end experiment run second way the science helper also knows this trick science various ways run first way do e e try first way e try second way end providing fake timing data if you re writing tests that depend on specific timing values you can provide canned durations using the fabricate_durations_for_testing_purposes method and scientist will report these in scientist observation duration instead of the actual execution times science absolutely nothing suspicious happening here do e e use control e try candidate e fabricate_durations_for_testing_purposes control 1 0 candidate 0 5 end fabricate_durations_for_testing_purposes takes a hash of duration values keyed by behavior names by default scientist uses control and candidate but if you override these as shown in trying more than one thing or no control just candidates use matching names here if a name is not provided the actual execution time will be reported instead like scientist experiment cleaner this probably won t come up in normal usage it s here to make it easier to test code that extends scientist without including scientist if you need to use scientist in...
|
|
| Thumbnail images (randomly selected): * Images may be subject to copyright. | |  |
|
Verified site has: 131 subpage(s). Do you want to verify them? Verify pages:
|
The site also has references to the 2 subdomain(s)
|
|
|
The site also has 3 references to other resources (not html/xhtml )
|
Pages verified in the last hours (randomly selected):
|
|
Top 50 hastags from of all verified websites.
| |
|
|
|
|
|
|
Load Info| page size | 55819 | | load time (s) | 2.056407 | | redirect count | 1 | | speed download | 27149 | | server IP | 207.241.237.3 |
|
|
|
|
|
|
|
|
* Image may be subject to copyright.
|
|