Variants

实现变量(实验,MODs)系统。 允许根据条件进行动态标志评估。(Implementations of a variants (experiments, mods) system. Allows for dynamic flag evaluation based on conditions.)

Github星跟蹤圖

背景

在Web应用程序中,通常为独特的用户组提供不同的体验。 灵活的设计应允许在Web开发中实现常见的模式,如:

  • A/B测试
  • 实验功能
  • 受信任的测试人员组
  • 渐进功能推出
变量提供了一种表达方式来定义和有条件地修改实验特征,也可以强制调整(用于开发)。
请注意,以下README仅提供变量的一般概述,并且与语言无关。 目前,还有为Node.js和Go编写的端口。 有关更多信息,请参阅实现特定的README。
要有条件地选择某些功能,它们必须受到变量标志的保护。 变量标志是可以指向语言原语、数组或对象的全局唯一字符串。 最常见的变量标志是简单的布尔值,因此可以使用以下代码:
if (variants.getFlagValue('enable_product_access')) {  throw Error('Authenticated failed.')}

设计

  • 每个服务包含变量
  • 变体包含0个或更多个条件和1个或更多个mod
  • 条件根据条件类型和值评估当前请求
  • Mods修改变量标志
  • 在门控控制流的代码中检查变量标志

概覽

名稱與所有者Medium/variants
主編程語言JavaScript
編程語言Go (語言數: 2)
平台
許可證Other
發布數3
最新版本名稱v0.3.4 (發布於 )
第一版名稱v0.3.2 (發布於 )
創建於2012-06-12 02:12:42
推送於2023-04-06 23:23:23
最后一次提交2020-03-17 15:52:37
星數202
關注者數172
派生數8
提交數84
已啟用問題?
問題數0
打開的問題數0
拉請求數27
打開的拉請求數0
關閉的拉請求數3
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?

Variants

Background

In web applications it is common to provide varying experiences to unique sets of users. A flexible design should allow implementations of common patterns in web development like:

  • A/B testing
  • Experimental features
  • Trusted tester groups
  • Gradual feature rollouts

Overview

Variants provide an expressive way to define and conditionally modify experimental features, which can also be forcefully adjusted (for development).

Note that the following README only provides a general overview of variants, and is language independent. Currently, there are ports written for Node.js and Go. See the implementation-specific READMEs for more information.

To conditionally gate certain features, they must be protected by variant flags. Variant flags are globally unique strings that can point to a language primitive, array or object. Most commonly, variant flags are simple boolean values so that the below code is possible:

if (variants.getFlagValue('enable_product_access')) {
  throw Error('Authenticated failed.')
}

Design

  • Each service contains variants
  • Variants contain 0 or more conditions and 1 or more mods
  • Conditions evaluate the current request based on the condition type and values
  • Mods modify variant flags
  • Variant flags are checked in code to gate control flow

Variant

Variants are globally defined objects that may optionally modify values based on some conditions. All variants are evaluated on a per request basis, which means that they are scoped to request-based values such as: user ip, specific users, groups of users, query parameters, etc.

Variants must have an id and a list of conditions and mods. A variant must contain at least one mod to be valid.

variant: {
  required string id
  optional string conditional_operator
  optional condition[] conditions
  required mod[] mods
}

Condition

Conditions return true or false based on the current request object. If more than one condition is supplied, then the conditional_operator (either "OR" or "AND") must be supplied.

Below is a list of condition types:

USER_ID

User id is a condition that evaluates the given condition based on a list of usernames in the "values" field.

E.g.

{
  "type": "USER_ID",
  "values": [
    "somedude74",
    "anotherdude323",
    "hax0r1337"
  ]
}

USER_ID_MOD

User id mods use a hashed value of the current user’s username mapped onto a range from 0-99. It allows the properties "range_start" and "range_end", which contain values between 0-99 and range_end must be greater than range_start.

By default, this uses the unique user id of an authenticated user. However, the "cookie_type" field can be set to "NSID" to refer to unauthenticated users.

E.g.

{
  "type": "USER_ID_MOD",
  "values": [ 0, 9 ]
}

Note: This is useful for rolling out new features, such as to 1% -> 10% -> 50% -> 100% of users.

RANDOM

Random will randomly determine whether or not a given request is eligible for the variant.

E.g.

{
  "type": "RANDOM",
  "value": 0.25
}

Mod

Mods are triggered when the conditions are met on the given variant. The format of a mod is simply a key and a value. The key must refer to a global identifier for the variant flag.

Full spec

Spec in pseudo-protobuf format:

message Variants {
  repeated Variant variants;
}

message Variant {

  enum Operator {
    AND, // "AND"
    OR   // "OR"
  }

  // Unique identifier.
  required string id;

  // Readable description of the feature.
  optional string description;

  // Optional operator to evaluate the conditions.
  optional Operator conditional_operator;

  // List of conditions to evaluate.
  repeated Condition conditions;

  // List of mods to be triggered.
  repeated Mod mods;
}

message Condition {

  enum Type {
    RANDOM,
    USER_ID,
    USER_ID_MOD,
    USER_IP
  };

  // Type of condition.
  required Type type;

  // Single value.
  optional * value;

  // List of values.
  repeated * values;
}

message Mod {
  // Name of the variant flag to modify.
  required string flag;

  // Value to set.
  required * value;
}

Appendix

Contributing

Questions, comments, bug reports, and pull requests are all welcome.
Submit them at the project on GitHub.

Bug reports that include steps-to-reproduce (including code) are the
best. Even better, make them in the form of pull requests that update
the test suite. Thanks!

Author

David Byttow
supported by The Obvious Corporation.

License

Copyright 2012 The Obvious Corporation.

Licensed under the Apache License, Version 2.0.
See the top-level file LICENSE.txt and
(http://www.apache.org/licenses/LICENSE-2.0).

去到頂部