使用强制分桶
November 21, 2024About 8 min
使用强制分桶
如何在 Eyeofcloud 功能实验中使用强制分桶将用户置于特定变体中。
强制分桶允许您以编程方式将用户从代码中放入变体中。
Forced Decision 方法允许您
- 设置强制决策。
- 获得强制决定。
- 删除强制决策。
- 删除所有强制决策。
要强制用户使用变体,请调用 SDK 强制决策方法,通过强制用户使用特定变体来测试和调试客户端应用程序的各种流程。
与允许列表不同,强制存储会立即发生(这意味着,无需等待数据文件更新),并且对可以强制存储的用户没有限制。
用法示例
有关实现信息,请参阅以下代码示例。
客户端 SDK 示例
Android-Kotlin
// Create the EyeofcloudUserContext, passing in the UserId and Attributes
val user = eyeofcloudClient.createUserContext("user-id")
val flagContext = EyeofcloudDecisionContext("flag-1", null)
val flagAndABTestContext = EyeofcloudDecisionContext("flag-1", "exp-1")
val flagAndDeliveryRuleContext = EyeofcloudDecisionContext("flag-1", "delivery-1")
val variationAForcedDecision = EyeofcloudForcedDecision("variation-a")
val variationBForcedDecision = EyeofcloudForcedDecision("variation-b")
val variationOnForcedDecision = EyeofcloudForcedDecision("on")
// set a forced decision for a flag
var success = user!!.setForcedDecision(flagContext, variationAForcedDecision)
var decision = user.decide("flag-1")
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision)
decision = user.decide("flag-1")
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision)
decision = user.decide("flag-1")
// get forced variations
val forcedDecision = user.getForcedDecision(flagContext)
println("[ForcedDecision] variationKey = " + forcedDecision!!.variationKey)
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext)
success = user.removeAllForcedDecisions()
Android-Java
/* Create the EyeofcloudUserContext, passing in the UserId and Attributes */
EyeofcloudUserContext user = eyeofcloudClient.createUserContext("user-id");
EyeofcloudDecisionContext flagContext = new EyeofcloudDecisionContext("flag-1", null);
EyeofcloudDecisionContext flagAndABTestContext = new EyeofcloudDecisionContext("flag-1", "exp-1");
EyeofcloudDecisionContext flagAndDeliveryRuleContext = new EyeofcloudDecisionContext("flag-1", "delivery-1");
EyeofcloudForcedDecision variationAForcedDecision = new EyeofcloudForcedDecision("variation-a");
EyeofcloudForcedDecision variationBForcedDecision = new EyeofcloudForcedDecision("variation-b");
EyeofcloudForcedDecision variationOnForcedDecision = new EyeofcloudForcedDecision("on");
// set a forced decision for a flag
Boolean success = user.setForcedDecision(flagContext, variationAForcedDecision);
EyeofcloudDecision decision = user.decide("flag-1");
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.decide("flag-1");
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.decide("flag-1");
// get forced variations
EyeofcloudForcedDecision forcedDecision = user.getForcedDecision(flagContext);
System.out.println("[ForcedDecision] variationKey = " + forcedDecision.getVariationKey());
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext);
success = user.removeAllForcedDecisions();
Flutter
/* Create the EyeofcloudUserContext, passing in the UserId and Attributes */
var user = await eyeofcloudClient.createUserContext(userId: "user-id");
var flagContext = EyeofcloudDecisionContext("flag-1");
var flagAndABTestContext = EyeofcloudDecisionContext("flag-1", "exp-1");
var flagAndDeliveryRuleContext = EyeofcloudDecisionContext("flag-1", "delivery-1");
var variationAForcedDecision = EyeofcloudForcedDecision("variation-a");
var variationBForcedDecision = EyeofcloudForcedDecision("variation-b");
var variationOnForcedDecision = EyeofcloudForcedDecision("on");
// set a forced decision for a flag
var success = await user!.setForcedDecision(flagContext, variationAForcedDecision);
var decision = await user.decide("flag-1");
// set a forced decision for an ab-test rule
success = await user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = await user.decide("flag-1");
// set a forced variation for a delivery rule
success = await user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = await user.decide("flag-1");
// get forced variations
var forcedDecision = await user.getForcedDecision(flagContext);
print("[ForcedDecision] variationKey = ${forcedDecision.variationKey}");
// remove forced variations
success = await user.removeForcedDecision(flagAndABTestContext);
success = await user.removeAllForcedDecisions();
JavaScript (Browser)
import { createInstance } from '@eyeofcloud/eyeofcloud-sdk';
const eyeofcloud = createInstance({
sdkKey: '<YOUR_SDK_KEY>'// Provide the sdkKey of your desired environment here
});
if (eyeofcloud) {
eyeofcloud.onReady().then(({ success, reason }) => {
if (!success) {
throw new Error(reason);
}
const attributes = { logged_in: true };
const user = eyeofcloud.createUserContext('user123', attributes);
if (!user) {
throw new Error('failed to create user context');
}
let result, decision, forcedDecision;
// set a forced decision for a flag
result = user.setForcedDecision({flagKey: 'flag-1'}, {variationKey: 'off'});
decision = user.decide('flag-1');
// set a forced decision for an ab-test rule
result = user.setForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'}, {variationKey: 'variation-b'});
decision = user.decide('flag-2');
// set a forced variation for a delivery rule
result = user.setForcedDecision({flagKey: 'flag-3', ruleKey: 'delivery-1'}, {variationKey: 'on'});
decision = user.decide('flag-3');
// get forced variations
forcedDecision = user.getForcedDecision({flagKey: 'flag-2'});
// remove forced variations
result = user.removeForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'});
user.removeAllForcedDecisions();
user.decideAll();
}).catch((err) => {
console.log(err);
// handle error
}); } else {
// handle instantiation error
}
JavaScript (Node)
const { createInstance } = require('@eyeofcloud/eyeofcloud-sdk');
const eyeofcloud = createInstance({
sdkKey: '<YOUR_SDK_KEY>'// Provide the sdkKey of your desired environment here
});
if (eyeofcloud) {
eyeofcloud.onReady().then(({ success, reason }) => {
if (!success) {
throw new Error(reason);
}
const attributes = { logged_in: true };
const user = eyeofcloud.createUserContext('user123', attributes);
if (!user) {
throw new Error('failed to create user context');
}
let result, decision, forcedDecision;
// set a forced decision for a flag
result = user.setForcedDecision({flagKey: 'flag-1'}, {variationKey: 'off'});
decision = user.decide('flag-1');
// set a forced decision for an ab-test rule
result = user.setForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'}, {variationKey: 'variation-b'});
decision = user.decide('flag-2');
// set a forced variation for a delivery rule
result = user.setForcedDecision({flagKey: 'flag-3', ruleKey: 'delivery-1'}, {variationKey: 'on'});
decision = user.decide('flag-3');
// get forced variations
forcedDecision = user.getForcedDecision({flagKey: 'flag-2'});
// remove forced variations
result = user.removeForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'});
user.removeAllForcedDecisions();
user.decideAll();
}).catch((err) => {
console.log(err);
// handle error
});
} else {
// handle instantiation error
}
React
import React from "react";
import {
createInstance,
EyeofcloudProvider,
useDecision,
withEyeofcloud,
} from "@eyeofcloud/react-sdk";
const eyeofcloud = createInstance({
sdkKey: "<YOUR_SDK_KEY_HERE>",
});
eyeofcloud.onUserUpdate(() => {
// Wait for the user to be available before using forced decision methods.
eyeofcloud.setForcedDecision({ flagKey: "product_sort" }, { variationKey: "treatment" });
});
const PurchaseButton = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.track("purchased");
};
return <div><button onClick={handleClick}>Purchase</button></div>;
});
const RemoveForcedDecision = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.removeForcedDecision({ flagKey: 'product_sort' });
};
return <div><button onClick={handleClick}>Remove Forced Decision</button></div>;
});
const RemoveAllForcedDecisions = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.removeAllForcedDecisions();
};
return <div><button onClick={handleClick}>Remove All Forced Decisions</button></div>;
});
function ProductSort() {
const [decision] = useDecision("product_sort", {
autoUpdate: true
});
const variationKey = decision.variationKey;
const isEnabled = decision.enabled;
const sortMethod = decision.variables["sort_method"];
return (
<div>
{/* If variation is null, display error */}
{variationKey === null && <div className="error">{decision.reasons}</div>}
{/* If feature is enabled, do something with the Sort Method variable */}
{isEnabled && <div>The Sort method is {sortMethod}</div>}
{/* Show relevant component based on the variation key */}
{variationKey === "control" && <div>Control Component</div>}
{variationKey === "treatment" && <div>Treatment Component</div>}
{/* Show Purchase Button to track Purchase event */}
<PurchaseButton />
<RemoveForcedDecision />
<RemoveAllForcedDecisions />
</div>
);
}
function App() {
return (
<EyeofcloudProvider
eyeofcloud={eyeofcloud}
user={{
id: "user123",
}}
>
<ProductSort />
</EyeofcloudProvider>
);
}
export default App;
React Native
import React from "react";
import {
createInstance,
EyeofcloudProvider,
useDecision,
withEyeofcloud,
} from "@eyeofcloud/react-sdk";
const eyeofcloud = createInstance({
sdkKey: "<YOUR_SDK_KEY_HERE>",
});
eyeofcloud.onUserUpdate(() => {
// Wait for the user to be available before using forced decision methods.
eyeofcloud.setForcedDecision({ flagKey: "product_sort" }, { variationKey: "treatment" });
});
const PurchaseButton = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.track("purchased");
};
return <div><button onClick={handleClick}>Purchase</button></div>;
});
const RemoveForcedDecision = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.removeForcedDecision({ flagKey: 'product_sort' });
};
return <div><button onClick={handleClick}>Remove Forced Decision</button></div>;
});
const RemoveAllForcedDecisions = withEyeofcloud((props: any) => {
const handleClick = () => {
const { eyeofcloud } = props;
eyeofcloud.removeAllForcedDecisions();
};
return <div><button onClick={handleClick}>Remove All Forced Decisions</button></div>;
});
function ProductSort() {
const [decision] = useDecision("product_sort", {
autoUpdate: true
});
const variationKey = decision.variationKey;
const isEnabled = decision.enabled;
const sortMethod = decision.variables["sort_method"];
return (
<div>
{/* If variation is null, display error */}
{variationKey === null && <div className="error">{decision.reasons}</div>}
{/* If feature is enabled, do something with the Sort Method variable */}
{isEnabled && <div>The Sort method is {sortMethod}</div>}
{/* Show relevant component based on the variation key */}
{variationKey === "control" && <div>Control Component</div>}
{variationKey === "treatment" && <div>Treatment Component</div>}
{/* Show Purchase Button to track Purchase event */}
<PurchaseButton />
<RemoveForcedDecision />
<RemoveAllForcedDecisions />
</div>
);
}
function App() {
return (
<EyeofcloudProvider
eyeofcloud={eyeofcloud}
user={{
id: "user123",
}}
>
<ProductSort />
</EyeofcloudProvider>
);
}
export default App;
Swift
let eyeofcloud = EyeofcloudClient(sdkKey: “sdk-key”)
eyeofcloud.start(datafile: datafile)
let user = eyeofcloud.createUserContext(userId: “test-user”, attributes: attributes)
let flagContext = EyeofcloudDecisionContext(flagKey: "flag-1")
let flagAndABTestContext = EyeofcloudDecisionContext(flagKey: "flag-1", ruleKey: "ab-test-1")
let flagAndDeliveryRuleContext = EyeofcloudDecisionContext(flagKey: "flag-1", ruleKey: "delivery-1")
let variationAForcedDecision = EyeofcloudForcedDecision(variationKey: "variation-a")
let variationBForcedDecision = EyeofcloudForcedDecision(variationKey: "variation-b")
let variationOnForcedDecision = EyeofcloudForcedDecision(variationKey: "on")
// set a forced decision for a flag
var success = user.setForcedDecision(context: flagContext, decision: variationAForcedDecision)
decision = user.decide(key: "flag-1")
// set a forced decision for an ab-test rule
success = user.setForcedDecision(context: flagAndABTestContext, decision: variationBForcedDecision)
decision = user.decide(key: "flag-1")
// set a forced variation for a delivery rule
success = user.setForcedDecision(context: flagAndDeliveryRuleContext, decision: variationOnForcedDecision)
decision = user.decide(key: "flag-1")
// get forced variations
let forcedDecision = user.getForcedDecision(context: flagContext)
print("[ForcedDecision] variationKey = \(forcedDecision!.variationKey)")
// remove forced variations
success = user.removeForcedDecision(context: flagAndABTestContext)
success = user.removeAllForcedDecisions()
服务器端 SDK 示例
C#
var Eyeofcloud = EyeofcloudFactory.NewDefaultInstance("<your sdk key>");
var attributes = new UserAttributes();
var user = Eyeofcloud.CreateUserContext(RandomUserId(), attributes);
var flagContext = new EyeofcloudDecisionContext("flag-1", null);
var flagAndABTestContext = new EyeofcloudDecisionContext("flag-1", "ab-test-1");
var flagAndDeliveryRuleContext = new EyeofcloudDecisionContext("flag-1", "delivery-1");
var variationAForcedDecision = new EyeofcloudForcedDecision("variation-a");
var variationBForcedDecision = new EyeofcloudForcedDecision("variation-b");
var variationOnForcedDecision = new EyeofcloudForcedDecision("on");
// set a forced decision for a flag
var success = user.SetForcedDecision(flagContext, variationAForcedDecision);
var decision = user.Decide("flag-1");
// set a forced decision for an ab-test rule
success = user.SetForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.Decide("flag-1");
// set a forced variation for a delivery rule
success = user.SetForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.Decide("flag-1");
// get forced variations
var forcedDecision = user.GetForcedDecision(flagContext);
Console.WriteLine(string.Format("ForcedDecision variationKey = {0}", forcedDecision.VariationKey));
// remove forced variations
success = user.RemoveForcedDecision(flagAndABTestContext);
success = user.RemoveAllForcedDecisions();
Go
factory := &client.EyeofcloudFactory{SDKKey: "sdk-key"}
if eyeofcloud, err := factory.StaticClient(); err == nil {
user := eyeofcloud.CreateUserContext("test-user", map[string]interface{}{})
flagContext := decision.EyeofcloudDecisionContext{FlagKey: "flag-1"}
flagAndABTestContext := decision.EyeofcloudDecisionContext{FlagKey: "flag-1", RuleKey: "ab-test-1"}
flagAndDeliveryRuleContext := decision.EyeofcloudDecisionContext{FlagKey: "flag-1", RuleKey: "delivery-1"}
variationAForcedDecision := decision.EyeofcloudForcedDecision{VariationKey: "variation-a"}
variationBForcedDecision := decision.EyeofcloudForcedDecision{VariationKey: "variation-b"}
variationOnForcedDecision := decision.EyeofcloudForcedDecision{VariationKey: "on"}
// set a forced decision for a flag
success := user.SetForcedDecision(flagContext, variationAForcedDecision)
decision := user.Decide("flag-1", nil)
// set a forced decision for an ab-test rule
success = user.SetForcedDecision(flagAndABTestContext, variationBForcedDecision)
decision = user.Decide("flag-1", nil)
// set a forced variation for a delivery rule
success = user.SetForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision)
decision = user.Decide("flag-1", nil)
// get forced variations
if forcedDecision, err := user.GetForcedDecision(flagContext); err == nil {
fmt.Println("[ForcedDecision] variationKey = " + forcedDecision.VariationKey)
}
// remove forced variations
success = user.RemoveForcedDecision(flagAndABTestContext)
success = user.RemoveAllForcedDecisions() }
Java
/* Create the Eyeofcloud instance and provide the sdk-key */
Eyeofcloud eyeofcloud = EyeofcloudFactory.newDefaultInstance("sdk-key");
/* Create the EyeofcloudUserContext, passing in the UserId and Attributes */
EyeofcloudUserContext user = eyeofcloud.createUserContext("user-id", Collections.emptyMap());
EyeofcloudDecisionContext flagContext = new EyeofcloudDecisionContext("flag-1");
EyeofcloudDecisionContext flagAndABTestContext = new EyeofcloudDecisionContext("flag-1", "ab-test-1");
EyeofcloudDecisionContext flagAndDeliveryRuleContext = new EyeofcloudDecisionContext("flag-1", "delivery-1");
EyeofcloudForcedDecision variationAForcedDecision = new EyeofcloudForcedDecision("variation-a");
EyeofcloudForcedDecision variationBForcedDecision = new EyeofcloudForcedDecision("variation-b");
EyeofcloudForcedDecision variationOnForcedDecision = new EyeofcloudForcedDecision("on");
// set a forced decision for a flag
Boolean success = user.setForcedDecision(flagContext, variationAForcedDecision);
EyeofcloudDecision decision = user.decide("flag-1");
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.decide("flag-1");
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.decide("flag-1");
// get forced variations
EyeofcloudForcedDecision forcedDecision = user.getForcedDecision(flagContext);
System.out.println("[ForcedDecision] variationKey = " + forcedDecision.getVariationKey());
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext);
success = user.removeAllForcedDecisions();
PHP
$eyeofcloudClient = EyeofcloudFactory::createDefaultInstance($sdkKey);
$user = $eyeofcloudClient->createUserContext('test_user', $attributes);
$flagContext = new EyeofcloudDecisionContext('flag-1', null);
$flagAndABTestContext = new EyeofcloudDecisionContext('flag-1', 'ab-test-1');
$flagAndDeliveryRuleContext = new EyeofcloudDecisionContext('flag-1', 'delivery-1');
$variationAForcedDecision = new EyeofcloudForcedDecision('variation-a');
$variationBForcedDecision = new EyeofcloudForcedDecision('variation-b');
$variationOnForcedDecision = new EyeofcloudForcedDecision('on');
# set a forced decision for a flag
$success = $user->setForcedDecision($flagContext, $variationAForcedDecision);
$decision = $user->decide('flag-1');
# set a forced decision for an ab-test rule
$success = $user->setForcedDecision($flagAndABTestContext, $variationBForcedDecision);
$decision = $user->decide('flag-1');
# set a forced variation for a delivery rule
$success = $user->setForcedDecision($flagAndDeliveryRuleContext, $variationOnForcedDecision);
$decision = $user->decide('flag-1');
# get forced variations
$forcedDecision = $user->getForcedDecision($flagContext);
echo "[ForcedDecision] variationKey = {$forcedDecision}";
# remove forced variations
$success = $user->removeForcedDecision($flagAndABTestContext);
$success = $user->removeAllForcedDecisions();
Python
from eyeofcloud import eyeofcloud, eyeofcloud_user_context
eyeofcloud_client = eyeofcloud.Eyeofcloud(sdk_key="<YOUR_SDK_KEY>")
user = eyeofcloud_client.create_user_context("test_user", attributes)
flag_context = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudDecisionContext("flag-1",None)
flag_and_ab_test_context = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudDecisionContext("flag-1","ab-test-1")
flag_and_delivery_rule_context = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudDecisionContext("flag-1","delivery-1")
variation_a_forced_decision = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudForcedDecision("variation-a")
variation_b_forced_decision = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudForcedDecision("variation-b")
variation_on_forced_decision = eyeofcloud_user_context.EyeofcloudUserContext.EyeofcloudForcedDecision("on")
# set a forced decision for a flag
success = user.set_forced_decision(flag_context, variation_a_forced_decision)
decision = user.decide("flag-1")
# set a forced decision for an ab-test rule
success = user.set_forced_decision(flag_and_ab_test_context, variation_b_forced_decision)
decision = user.decide("flag-1")
# set a forced variation for a delivery rule
success = user.set_forced_decision(flag_and_delivery_rule_context, variation_on_forced_decision)
decision = user.decide("flag-1")
# get forced variations
forced_decision = user.get_forced_decision(flag_context)
print(f"[ForcedDecision] variation_key = {forced_decision}")
# remove forced variations
success = user.remove_forced_decision(flag_and_ab_test_context)
success = user.remove_all_forced_decision()
Ruby
require 'eyeofcloud'
require 'eyeofcloud/eyeofcloud_factory'
eyeofcloud = Eyeofcloud::EyeofcloudFactory.default_instance('sdk_key')
user = eyeofcloud.create_user_context('test_user', attributes)
flag_context = Eyeofcloud::EyeofcloudUserContext::EyeofcloudDecisionContext.new('flag-1', nil)
flag_and_ab_test_context = Eyeofcloud::EyeofcloudUserContext::EyeofcloudDecisionContext.new('flag-1','ab-test-1')
flag_and_delivery_rule_context = Eyeofcloud::EyeofcloudUserContext::EyeofcloudDecisionContext.new('flag-1','delivery-1')
variation_a_forced_decision = Eyeofcloud::EyeofcloudUserContext::EyeofcloudForcedDecision.new('variation-a')
variation_b_forced_decision = Eyeofcloud::EyeofcloudUserContext::EyeofcloudForcedDecision.new('variation-b')
variation_on_forced_decision = Eyeofcloud::EyeofcloudUserContext::EyeofcloudForcedDecision.new('on')
# set a forced decision for a flag
success = user.set_forced_decision(flag_context, variation_a_forced_decision)
decision = user.decide('flag-1')
# set a forced decision for an ab-test rule
success = user.set_forced_decision(flag_and_ab_test_context, variation_b_forced_decision)
decision = user.decide('flag-1')
# set a forced variation for a delivery rule
success = user.set_forced_decision(flag_and_delivery_rule_context, variation_on_forced_decision)
decision = user.decide('flag-1')
# get forced variations
forced_decision = user.get_forced_decision(flag_context)
puts "[ForcedDecision] variation_key = #{forced_decision}"
# remove forced variations
success = user.remove_forced_decision(flag_and_ab_test_context)
success = user.remove_all_forced_decisions