Skip to content

Conversation

@Eskibear
Copy link
Member

@Eskibear Eskibear commented Apr 8, 2024

Same as other language, TargetingFilter will be one of the built-in filters. This PR implements that.

@Eskibear Eskibear marked this pull request as ready for review April 9, 2024 04:49
@Eskibear Eskibear force-pushed the yanzh/targeting-filter branch from fdb45ae to ee83ae8 Compare April 9, 2024 05:58
@Eskibear Eskibear merged commit 53fdca1 into main Apr 16, 2024
@Eskibear Eskibear deleted the yanzh/targeting-filter branch April 16, 2024 05:34
// Cryptographic hashing algorithms ensure adequate entropy across hash values.
const contextMarker = stringToUint32(audienceContextId);
const contextPercentage = (contextMarker / 0xFFFFFFFF) * 100;
return contextPercentage < rolloutPercentage;
Copy link
Member

Choose a reason for hiding this comment

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

@Eskibear Did you validate that this produces the same number as dotnet/python?

if (parameters.Audience.Groups !== undefined) {
for (const group of parameters.Audience.Groups) {
if (group.RolloutPercentage < 0 || group.RolloutPercentage > 100) {
throw new Error(`RolloutPercentage of group ${group.Name} must be a number between 0 and 100.`);
Copy link
Member

Choose a reason for hiding this comment

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

"between 0 and 100" makes it sound like it needs to be 1-99. Could do any of:

  1. "must be no less than 0 and no more than 100."
  2. "must be a number between 0 and 100, inclusive.
  3. "is out of the accepted range." (this is what dotnet says today- but it's less clear)

// Licensed under the MIT license.

import { IFeatureFilter } from "./FeatureFilter";
import { createHash } from "crypto";
Copy link
Member

@rossgrambo rossgrambo Apr 16, 2024

Choose a reason for hiding this comment

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


export interface IFeatureFilter {
name: string; // e.g. Microsoft.TimeWindow
evaluate(context: IFeatureFilterEvaluationContext, appContext?: unknown): Promise<boolean> | boolean;
Copy link
Member

@rossgrambo rossgrambo Apr 16, 2024

Choose a reason for hiding this comment

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

This interface should just return Promise. The calling code is forced to use await anyway since this function might return a Promise. If await is used on a non-promise, it simply wraps it in an immediately resolved Promise anyway.

I believe the implementation can just stay "return true" and things will work fine- as long as the function is marked async.

export class TargetingFilter implements IFeatureFilter {
name: string = "Microsoft.Targeting";

evaluate(context: TargetingFilterEvaluationContext, appContext?: TargetingFilterAppContext): boolean | Promise<boolean> {
Copy link
Member

Choose a reason for hiding this comment

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

This feels like a lie- since we don't ever return Promise. I prefer marking this async and only doing Promise.

Copy link
Member Author

Choose a reason for hiding this comment

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

@rossgrambo Good catch. That was a miss.
According to current impl, it returns a boolean instead of a promise, without any async operations. context is read from feature flags already loaded, and appContext is provided directly in parameter.
I'll create a PR changing it to

    evaluate(context: TargetingFilterEvaluationContext, appContext?: TargetingFilterAppContext): boolean

WDYT?

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