Skip to content

Conversation

@Yg-Hong
Copy link
Collaborator

@Yg-Hong Yg-Hong commented Feb 28, 2025

  • Add LightSwitchClient (Core class responsible for feature flagging function)
  • Add LightSwitchClientConfig
  • Add FeatureFlag (model class)
  • Add LightSwitchUser
  • Add test code

@Yg-Hong Yg-Hong requested a review from eunhwa99 February 28, 2025 03:54
throw new LightSwitchCastException(key, value, expectedType);
}
return expectedType.cast(value);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about move all private methods to the bottom?

if (flag == null) return defaultValue;

Object value = flag.evaluate(user);
return castValue(key, value, Boolean.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since 58~62 lines are duplicated to other methods too, it would be better to extract private method for these.


public FeatureFlag(String key, Object defaultValue, Map<Map<String, String>, Object> filters) {
this.key = key;
this.defaultValue = defaultValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't defaultValue also require Null check?


boolean getBooleanFlag(String key, boolean defaultValue, LightSwitchUser user);

int getIntFlag(String key, int defaultValue, LightSwitchUser user);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about why the flag restricts the number type to Int. It seems like there could be many cases where storing a Long would be necessary.

private final String serverUrl;
private final String sdkKey;
private final int reconnectDelay;
private final int connectionTimeout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better if the client could customize the read timeout as well.

Comment on lines +27 to +29
if (serverUrl == null) {
throw new LightSwitchConfigException("Server URL cannot be null");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using StringUtils to check if the server URL is blank as well?

Comment on lines +36 to +45
for (Map.Entry<Map<String, String>, Object> entry : filters.entrySet()) {
Map<String, String> conditions = entry.getKey();
boolean match = conditions.entrySet().stream()
.allMatch(cond -> user.getAttributes().getOrDefault(cond.getKey(), "").equals(cond.getValue()));

if (match) {
return entry.getValue();
}
}
return defaultValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we simplify the logic using Streams, it might be more readable than using a for loop and manually iterating.

return filters.entrySet().stream()
        .filter(entry -> entry.getKey().entrySet().stream()
                .allMatch(cond -> user.getAttributes().getOrDefault(cond.getKey(), "").equals(cond.getValue())))
        .map(Map.Entry::getValue)
        .findFirst()
        .orElse(defaultValue);


private final String key;
private final Object defaultValue;
private final Map<Map<String, String>, Object> filters; // filtering rules
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the filters have been added to flag, it seems like similar modifications should be needed in the backend entity and API spec as well. It would be good to review and align everything before moving forward.

Comment on lines +7 to +10
public class LightSwitchUser {

private final String userId;
private final Map<String, String> attributes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like LightSwitchUser serves a different purpose than the backend's User, where is this data stored?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants