歡迎來到 DevOpsDay Taipei 2024 共筆
共筆從這開始
因為使用多個branch做開發,有時候有些branch太早開發,但太晚merge進去,中間會有很多其他小開發完成,這樣就會產生merge conflict。
這時候就要去處理這樣的問題
但feature toggle可以有相關的解方。
常常button換顏色的時候要換來換去,這樣也很苦惱
"feature toggle is second best solution. the best solution is to find a way to gradually intergrate without feature branches and feature toggles" by Martin Fowler
LINE Taiwan 開發的,已經開源出來了
有三個特點:
AB testing,用go來撰寫的。performance非常的好。
DevOpsDays Taipei 2024
第一個是未完成Code 的 Merege 問題
第二個是新需求的Adopt,新舊功能都留著
Invisibility
Speed
Experimentation
Safety
Live Update
Realse Toggle : 承上
Ops Toggles : 流量大有另外函數
Permission Toggles : 權限控制
Experiment Toggles : 使用者體驗
toggle測試結束的時候最終要拿掉,不然會累積太多很難處理,會把code跟toggle feature一起拿掉。
基本上會希望非開發人員可以去處理,QA或是project owner可以去改變跟測試
下載專案
sdk and sample code: line/Flagship4j
install library
./gradlew publishToMavenLocal
implementation "com.linecorp.flagship4j:flagship4j-openfeature-spring-boot-starter:0.1.40-SNAPSHOT"
create a controller with openfeature client
create flag setting on the openflagr UI (release toggle)
trun toggle to permission togggle (constraints by role
)
add MutableContext
as a third parameter when call client.getBooleanValue()
@RestController
@RequiredArgsConstructor
public class LayoutController {
private final Client flagrClient;
@GetMapping("/layouts/product")
public ResponseEntity<?> getLayoutProduct() {
return ResponseEntity.ok(buildLayoutProduct());
}
private Map<?, ?> buildLayoutProduct() {
throw new UnsupportedOperationException("Not implemented yet");
}
}
@RestController
@RequiredArgsConstructor
public class LayoutController {
private final Client flagrClient;
@GetMapping("/layouts/product")
public ResponseEntity<?> getLayoutProduct() {
if (flagrClient.getBooleanValue("layout-prdocut-enabled", false)) {
return ResponseEntity.ok(buildLayoutProduct());
}
return ResponseEntity.notFound().build();
}
private Map<?, ?> buildLayoutProduct() {
return Map.of("btnBuyColor", "blue", "btnBuyRadius", "8px", "btnBuyPos", "page");
}
}
@RestController
@RequiredArgsConstructor
public class LayoutController {
private final Client flagrClient;
@GetMapping("/layouts/product")
public ResponseEntity<?> getLayoutProduct(@RequestHeader(name = "x-user-name", required = false) String userName) {
MutableContext context = new MutableContext();
if (userName != null && userName.equals("aki")) {
context.add("entityContext", Structure.mapToStructure(Map.of("role", "ROLE_QA")));
}
if (flagrClient.getBooleanValue("layout-prdocut-enabled", false, context)) {
return ResponseEntity.ok(buildLayoutProduct());
}
return ResponseEntity.notFound().build();
}
private Map<?, ?> buildLayoutProduct() {
return Map.of("btnBuyColor", "blue", "btnBuyRadius", "8px", "btnBuyPos", "page");
}
}
@RestController
@RequiredArgsConstructor
public class LayoutController {
private final Client flagrClient;
@GetMapping("/layouts/product")
public ResponseEntity<?> getLayoutProduct(@RequestHeader(name = "x-user-name", required = false) String userName) {
MutableContext context = new MutableContext();
if (userName != null && userName.equals("aki")) {
context.add("entityContext", Structure.mapToStructure(Map.of("role", "ROLE_QA")));
}
if (flagrClient.getBooleanValue("layout-prdocut-enabled", false, context)) {
String theme = flagrClient.getStringValue("layout-product-theme", "themeA", new MutableContext(userName));
switch (theme) {
case "themeA":
return ResponseEntity.ok(buildThemeALayoutProduct());
case "themeB":
return ResponseEntity.ok(buildThemeBLayoutProduct());
default:
return ResponseEntity.notFound().build();
}
}
return ResponseEntity.notFound().build();
}
private Map<?, ?> buildThemeALayoutProduct() {
return Map.of("btnBuyColor", "blue", "btnBuyRadius", "8px", "btnBuyPos", "page");
}
private Map<?, ?> buildThemeBLayoutProduct() {
return Map.of("btnBuyColor", "green", "btnBuyRadius", "0px", "btnBuyPos", "bottomNav");
}
}
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing