-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path48.DesignDynamicFeatureFlagManager.java
More file actions
166 lines (137 loc) · 5.17 KB
/
48.DesignDynamicFeatureFlagManager.java
File metadata and controls
166 lines (137 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// ---------------- FEATURE FLAG MANAGER: SINGLE-FILE LLD DEMO (JAVA) -------------------
import java.util.*;
import java.util.concurrent.locks.*;
class FeatureFlag {
// Name of the flag
private String name; // stores the flag's name
private boolean enabled; // global ON/OFF
private Set<Integer> perUser; // users who should explicitly get the feature
private int rolloutPercentage; // % rollout
// Constructor initializes empty feature flag
public FeatureFlag(String name) {
this.name = name; // assign name
this.enabled = false; // default: disabled
this.perUser = new HashSet<>(); // set for user-specific overrides
this.rolloutPercentage = 0; // default 0% rollout
}
// Determine if feature is enabled for the given user
public boolean isEnabled(int userId) {
if (perUser.contains(userId)) { // explicit override?
return true;
}
if (enabled) { // global enable?
return true;
}
return (userId % 100) < rolloutPercentage; // percentage rollout logic
}
// Setters for manager
public void setEnabled(boolean state) {
this.enabled = state;
}
public void addUser(int userId) {
this.perUser.add(userId);
}
public void removeUser(int userId) {
this.perUser.remove(userId);
}
public void setRollout(int pct) {
this.rolloutPercentage = pct;
}
}
// ------------------------------ SINGLETON MANAGER -------------------------------------
class FeatureFlagManager {
// Singleton instance
private static FeatureFlagManager instance = null;
// Lock for thread safety
private static final ReentrantLock instanceLock = new ReentrantLock();
private final ReentrantLock flagLock = new ReentrantLock();
// In-memory store for all flags
private Map<String, FeatureFlag> flags;
// Private constructor
private FeatureFlagManager() {
this.flags = new HashMap<>(); // store flags in hashmap for O(1) lookup
}
// Singleton getter
public static FeatureFlagManager getInstance() {
instanceLock.lock(); // lock to ensure single instance creation
try {
if (instance == null) { // create instance if not created
instance = new FeatureFlagManager();
}
return instance; // return global manager
} finally {
instanceLock.unlock(); // release lock
}
}
// Create a new flag
public void createFlag(String name) {
flagLock.lock(); // lock write operations
try {
flags.put(name, new FeatureFlag(name)); // insert new flag
} finally {
flagLock.unlock();
}
}
// Update global state
public void updateFlagState(String name, boolean state) {
flagLock.lock();
try {
flags.get(name).setEnabled(state); // set on/off
} finally {
flagLock.unlock();
}
}
// Enable specific user
public void enableUser(String name, int userId) {
flagLock.lock();
try {
flags.get(name).addUser(userId); // add user override
} finally {
flagLock.unlock();
}
}
// Disable specific user
public void disableUser(String name, int userId) {
flagLock.lock();
try {
flags.get(name).removeUser(userId); // remove override
} finally {
flagLock.unlock();
}
}
// Set rollout %
public void setRollout(String name, int pct) {
flagLock.lock();
try {
flags.get(name).setRollout(pct); // set rollout percentage
} finally {
flagLock.unlock();
}
}
// Public method to check flag state
public boolean isEnabled(String name, int userId) {
return flags.get(name).isEnabled(userId); // delegate check to FeatureFlag
}
}
// ------------------------------ DEMO MAIN CLASS ---------------------------------------
public class FeatureFlagDemo {
public static void main(String[] args) {
FeatureFlagManager mgr = FeatureFlagManager.getInstance(); // get singleton
// Create first flag
mgr.createFlag("new_ui"); // create a flag
mgr.updateFlagState("new_ui", true); // globally enable it
// Create second flag (beta)
mgr.createFlag("beta_feature"); // create another flag
mgr.setRollout("beta_feature", 30); // enable 30% rollout
mgr.enableUser("beta_feature", 101); // explicit override for user 101
// Test users
int[] users = {10, 25, 50, 101};
System.out.println("Feature Checks:");
for (int u : users) {
boolean newUI = mgr.isEnabled("new_ui", u); // check new_ui
boolean beta = mgr.isEnabled("beta_feature", u); // check beta flag
System.out.println("User " + u + ": new_ui=" + newUI +
" beta_feature=" + beta);
}
}
}