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

Support recurrence for TimeWindowFilter #266

Merged
merged 63 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
92e8a08
improvement & target on main branch
zhiyuanliang-ms Nov 14, 2023
a732a24
remove duplicated null check
zhiyuanliang-ms Nov 14, 2023
290e96c
remove redundant if
zhiyuanliang-ms Nov 14, 2023
0e3e1e4
improvement
zhiyuanliang-ms Nov 15, 2023
353c025
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Nov 20, 2023
3cdcc56
resolve comments
zhiyuanliang-ms Nov 20, 2023
9600e7a
fix typo
zhiyuanliang-ms Dec 11, 2023
64904ec
update
zhiyuanliang-ms Dec 11, 2023
7bd2844
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Dec 11, 2023
bf2e2eb
use enum
zhiyuanliang-ms Jan 15, 2024
3041b06
Update testcases
zhiyuanliang-ms Jan 16, 2024
ba89364
fix bug
zhiyuanliang-ms Jan 16, 2024
1403934
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Jan 16, 2024
d8c1790
update
zhiyuanliang-ms Jan 18, 2024
e2b3d84
update the logic of FindWeeklyPreviousOccurrence
zhiyuanliang-ms Jan 18, 2024
e2fccc2
fix bug
zhiyuanliang-ms Jan 18, 2024
25ff14f
add comments
zhiyuanliang-ms Jan 18, 2024
bee8718
update
zhiyuanliang-ms Jan 18, 2024
ce5dfae
fix bug & add testcases
zhiyuanliang-ms Jan 18, 2024
724292b
update
zhiyuanliang-ms Jan 18, 2024
a3b8fa4
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Jan 18, 2024
63c7343
update comment
zhiyuanliang-ms Jan 18, 2024
d78d844
test
zhiyuanliang-ms Jan 18, 2024
2136562
update comments
zhiyuanliang-ms Jan 22, 2024
c0ab54c
Merge branch 'zhiyuanliang/recurring-time-window' of https://github.c…
zhiyuanliang-ms Jan 22, 2024
ab9961c
update
zhiyuanliang-ms Jan 23, 2024
252b5c3
update
zhiyuanliang-ms Jan 23, 2024
9fc5bcc
add testcase
zhiyuanliang-ms Jan 24, 2024
b9f5ab2
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Jan 29, 2024
29efb5d
remove monthly/yearly recurrence pattern
zhiyuanliang-ms Jan 29, 2024
421ec48
do not mention monthly and yearly pattern
zhiyuanliang-ms Feb 10, 2024
4eca45d
Merge branch 'main' of https://github.com/microsoft/FeatureManagement…
zhiyuanliang-ms Feb 10, 2024
e78a0f6
add more comments
zhiyuanliang-ms Feb 20, 2024
b7eb586
update the algorithm to find weekly previous occurrence
zhiyuanliang-ms Feb 20, 2024
c653198
update
zhiyuanliang-ms Feb 20, 2024
f9537d4
fix typo
zhiyuanliang-ms Feb 20, 2024
9c7ec7d
update
zhiyuanliang-ms Feb 20, 2024
2187121
rename variable
zhiyuanliang-ms Feb 20, 2024
fd098f1
Merge branch 'main' of https://github.com/microsoft/FeatureManagement…
zhiyuanliang-ms Feb 26, 2024
934784c
cache added & do validation for only once
zhiyuanliang-ms Feb 28, 2024
77b24b1
add comments
zhiyuanliang-ms Feb 28, 2024
f1eefe9
add more testcases
zhiyuanliang-ms Feb 29, 2024
0645a25
add more test
zhiyuanliang-ms Feb 29, 2024
acdc16b
not include the end of a time window
zhiyuanliang-ms Mar 7, 2024
ace075c
move recurrence validation to RecurrenceValidator
zhiyuanliang-ms Mar 20, 2024
096d136
resolve conflicts
zhiyuanliang-ms Mar 20, 2024
856e183
README updated
zhiyuanliang-ms Mar 22, 2024
b1c06ad
update readme
zhiyuanliang-ms Apr 7, 2024
0bb8017
update CalculateSurroundingOccurrences method
zhiyuanliang-ms Apr 7, 2024
b5b37f0
add CalculateClosestStart method
zhiyuanliang-ms Apr 9, 2024
4fa9002
testcase updated
zhiyuanliang-ms Apr 9, 2024
6196e21
update
zhiyuanliang-ms Apr 10, 2024
188ce44
use ISystemClock for testing & add limit on time window duration
zhiyuanliang-ms Apr 10, 2024
cd94d26
add testcase for timezone
zhiyuanliang-ms Apr 10, 2024
6abaa0d
update
zhiyuanliang-ms Apr 11, 2024
341f78f
update comments
zhiyuanliang-ms Apr 15, 2024
ac8f8f4
Merge branch 'main' into zhiyuanliang/recurring-time-window
zhiyuanliang-ms Apr 15, 2024
39149c6
Merge branch 'main' of https://github.com/microsoft/FeatureManagement…
zhiyuanliang-ms Apr 17, 2024
1a04153
change method type
zhiyuanliang-ms Apr 22, 2024
8e9f893
remove unused reference
zhiyuanliang-ms Apr 22, 2024
7deda05
rename variable
zhiyuanliang-ms Apr 22, 2024
bf992ff
remove used reference
zhiyuanliang-ms Apr 22, 2024
e1616a6
remove empty lines
zhiyuanliang-ms Apr 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 140 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The feature management library supports appsettings.json as a feature flag sourc
"Name": "TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 July 2019 00:00:00 GMT"
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
Expand Down Expand Up @@ -131,7 +131,7 @@ A `RequirementType` of `All` changes the traversal. First, if there are no filte
"Name": "TimeWindow",
"Parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 July 2023 00:00:00 GMT"
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
},
{
Expand Down Expand Up @@ -163,7 +163,7 @@ The feature management library also supports the usage of the [`Microsoft Featur
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 July 2023 00:00:00 GMT"
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
}
]
Expand Down Expand Up @@ -565,13 +565,149 @@ This filter provides the capability to enable a feature based on a time window.
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 July 2019 00:00:00 GMT"
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
```

The time window can be configured to recur periodically. This can be useful for the scenarios where one may need to turn on a feature during a low or high traffic period of a day or certain days of a week. To expand the individual time window to recurring time windows, the recurrence rule should be specified in the `Recurrence` parameter.

**Note:** `Start` and `End` must be both specified to enable `Recurrence`.
rossgrambo marked this conversation as resolved.
Show resolved Hide resolved

``` JavaScript
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "Fri, 22 Mar 2024 20:00:00 GMT",
"End": "Sat, 23 Mar 2024 02:00:00 GMT",
"Recurrence": {
"Pattern": {
"Type": "Daily",
"Interval": 1
},
"Range": {
"Type": "NoEnd"
}
}
}
}
]
}
```

The `Recurrence` settings is made up of two parts: `Pattern` (how often the time window will repeat) and `Range` (for how long the recurrence pattern will repeat).

#### Recurrence Pattern

There are two possible recurrence pattern types: `Daily` and `Weekly`. For example, a time window could repeat "every day", "every 3 days", "every Monday" or "on Friday per 2 weeks".

Depending on the type, certain fields of the `Pattern` are required, optional, or ignored.

- `Daily`

The daily recurrence pattern causes the time window to repeat based on a number of days between each occurrence.

| Property | Relevance | Description |
|----------|-----------|-------------|
| **Type** | Required | Must be set to `Daily`. |
| **Interval** | Optional | Specifies the number of days between each occurrence. Default value is 1. |

- `Weekly`

The weekly recurrence pattern causes the time window to repeat on the same day or days of the week, based on the number of weeks between each set of occurrences.

| Property | Relevance | Description |
|----------|-----------|-------------|
| **Type** | Required | Must be set to `Weekly`. |
| **DaysOfWeek** | Required | Specifies on which day(s) of the week the event occurs. |
| **Interval** | Optional | Specifies the number of weeks between each set of occurrences. Default value is 1. |
| **FirstDayOfWeek** | Optional | Specifies which day is considered the first day of the week. Default value is `Sunday`. |

The following example will repeat the time window every other Monday and Tuesday

``` javascript
"Pattern": {
"Type": "Weekly",
"Interval": 2,
"DaysOfWeek": ["Monday", "Tuesday"]
}
```

**Note:** `Start` must be a valid first occurrence which fits the recurrence pattern. Additionally, the duration of the time window cannot be longer than how frequently it occurs. For example, it is invalid to have a 25-hour time window recur every day.

#### Recurrence Range

There are three possible recurrence range type: `NoEnd`, `EndDate` and `Numbered`.

- `NoEnd`

The `NoEnd` range causes the recurrence to occur indefinitely.

| Property | Relevance | Description |
|----------|-----------|-------------|
| **Type** | Required | Must be set to `NoEnd`. |

- `EndDate`

The `EndDate` range causes the time window to occur on all days that fit the applicable pattern until the end date.

| Property | Relevance | Description |
|----------|-----------|-------------|
| **Type** | Required | Must be set to `EndDate`. |
| **EndDate** | Required | Specifies the date time to stop applying the pattern. Note that as long as the start time of the last occurrence falls before the end date, the end time of that occurrence is allowed to extend beyond it. |

The following example will repeat the time window every day until the last occurrence happens on April 1st, 2024.

``` javascript
"Start": "Fri, 22 Mar 2024 18:00:00 GMT",
"End": "Fri, 22 Mar 2024 20:00:00 GMT",
"Recurrence":{
"Pattern": {
"Type": "Daily",
"Interval": 1
},
"Range": {
"Type": "EndDate",
"EndDate": "Mon, 1 Apr 2024 20:00:00 GMT"
}
}
```

- `Numbered`
jimmyca15 marked this conversation as resolved.
Show resolved Hide resolved

The `Numbered` range causes the time window to occur a fixed number of times (based on the pattern).

| Property | Relevance | Description |
|----------|-----------|-------------|
| **Type** | Required | Must be set to `Numbered`. |
| **NumberOfOccurrences** | Required | Specifies the number of occurrences. |

The following example will repeat the time window on Monday and Tuesday until the there are 3 occurrences, which respectively happens on April 1st(Mon), April 2nd(Tue) and April 8th(Mon).

``` javascript
"Start": "Mon, 1 Apr 2024 18:00:00 GMT",
"End": "Mon, 1 Apr 2024 20:00:00 GMT",
"Recurrence":{
"Pattern": {
"Type": "Weekly",
"Interval": 1
"DaysOfWeek": ["Monday", "Tuesday"],
},
"Range": {
"Type": "Numbered",
"NumberOfOccurrences": 3
}
}
```

To create a recurrence rule, you must specify both `Pattern` and `Range`. Any pattern type can work with any range type.

**Advanced:** The time zone offset of the `Start` property will apply to the recurrence settings.

### Microsoft.Targeting

This filter provides the capability to enable a feature for a target audience. An in-depth explanation of targeting is explained in the [targeting](./README.md#Targeting) section below. The filter parameters include an audience object which describes users, groups, excluded users/groups, and a default percentage of the user base that should have access to the feature. Each group object that is listed in the target audience must also specify what percentage of the group's members should have access. If a user is specified in the exclusion section, either directly or if the user is in an excluded group, the feature will be disabled. Otherwise, if a user is specified in the users section directly, or if the user is in the included percentage of any of the group rollouts, or if the user falls into the default rollout percentage then that user will have the feature enabled.
Expand Down
20 changes: 20 additions & 0 deletions src/Microsoft.FeatureManagement/FeatureFilters/ISystemClock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//

using System;

namespace Microsoft.FeatureManagement.FeatureFilters
{
/// <summary>
/// Abstracts the system clock to facilitate testing.
/// .NET8 offers an abstract class TimeProvider. After we stop supporting .NET version less than .NET8, this ISystemClock should retire.
/// </summary>
internal interface ISystemClock
{
/// <summary>
/// Retrieves the current system time in UTC.
/// </summary>
public DateTimeOffset UtcNow { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
namespace Microsoft.FeatureManagement.FeatureFilters
{
/// <summary>
/// A recurrence definition describing how time window recurs
/// </summary>
public class Recurrence
{
/// <summary>
/// The recurrence pattern specifying how often the time window repeats
/// </summary>
public RecurrencePattern Pattern { get; set; }

/// <summary>
/// The recurrence range specifying how long the recurrence pattern repeats
/// </summary>
public RecurrenceRange Range { get; set; }
}
}
Loading