Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Initial Pass at Runtime Flag Architecture #579

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KetanReddy
Copy link
Member

Background

Player strives to be as configurable as possible and primarily achieves this through it's plugin architecture. While this does allow almost any aspect of Player's behavior to be configured, there are still some parts of Player's internal working that users of Player don't have access to. These are things like how strict Player is while running and how it should recover from state errors. For the most part the Player team has made assumptions on how users of Player would want Player to work but in pursuit of fulfilling Player's goal of customizability and configurability we should allow this behavior to be customizable.

Implementation Details

[WIP]

Change Type (required)

Indicate the type of change your pull request is:

  • patch
  • minor
  • major
  • N/A

Does your PR have any documentation updates?

  • Updated docs
  • No Update needed
  • Unable to update docs

Release Notes

Add the ability to statically/dynamically configure Player's runtime behavior via "flags". Flags are held in a FlagController class that can either get flag configuration via Player's initial configuration, dynamically at runtime via a function to set new flags, or even more dynamically by tapping a hook on the controller to override the value of any specific flag(s).

@KetanReddy KetanReddy added the minor Increment the minor version when merged label Jan 23, 2025
@KetanReddy KetanReddy self-assigned this Jan 23, 2025
}

public getFlag<T>(flag: Flag): T {
const configuredFlag = dlv(this.flags, flag) as PlayerFlags[Flag];
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: Technically this doesn't need to use dlv but will clean up when a flag format is agreed on.

Comment on lines +4 to +10
export interface PlayerFlags {
/** What log level duplicate ID errors during view resolution should be raised as */
duplicateIDLogLevel: Severity;

/** Log level for when there are cache conflicts in view resolution (usually related to duplicate IDs) */
cacheConflictLogLevel: Severity;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Open to feedback on the flag format. For simplicity this initial pass was built to use flat flags primarily because nested flags would take more logic to merge and operate on and pulling in another dependency would be preferable to writing that logic custom but something like that would add a few kb to Player's size

Copy link
Member

Choose a reason for hiding this comment

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

We have the LocalDataStore and the binding format we could use for nesting. Then do something like:

logs.level.duplicateId

Copy link
Member Author

Choose a reason for hiding this comment

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

I was considering using that but it seemed like overkill complexity-wise and potentially adding some overhead to get a flag if we need to go through binding parsing (even if its cached). I can write some benchmarks for it though to see what the impact would be.

Comment on lines +220 to +235
private logCacheIssue(id: string, type: NodeType): void {
let message: string | undefined;
let loglevel: Severity | undefined;

if (type === NodeType.Asset || type === NodeType.View) {
loglevel = this.options.flagController.getFlag("duplicateIDLogLevel");
message = `Cache conflict: Found Asset/View nodes that have conflicting ids: ${id}, may cause cache issues.`;
} else if (type === NodeType.Value) {
loglevel = this.options.flagController.getFlag("cacheConflictLogLevel");
message = `Cache conflict: Found Value nodes that have conflicting ids: ${id}, may cause cache issues. To improve performance make value node IDs globally unique.`;
}

if (message && loglevel) {
this.logger?.[loglevel]?.(message);
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

While most usages of flags I can think of right now are around logging but in theory some runtime functionality could depend on flags (like errors during expression parsing). Based on the current model a reference to the FlagController would have to be passed around but we could expose some dynamic logging functionality in the logger to take a flag and a message and let it internally figure out the severity to log with which would remove the need to pass around the reference as much.

Copy link

codecov bot commented Jan 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 85.85%. Comparing base (a8f8dd4) to head (07c8a27).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #579      +/-   ##
==========================================
- Coverage   89.76%   85.85%   -3.91%     
==========================================
  Files         331      189     -142     
  Lines       19840    10718    -9122     
  Branches     1949     1950       +1     
==========================================
- Hits        17809     9202    -8607     
+ Misses       2017     1502     -515     
  Partials       14       14              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor Increment the minor version when merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants