Skip to content

Commit ed028f1

Browse files
Merge pull request #14 from drone/version_check_and_priority_rules_fix
[MAINT] minor fixes
2 parents 9207d95 + d70d7a6 commit ed028f1

File tree

3 files changed

+102
-4
lines changed

3 files changed

+102
-4
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"flag": {
3+
"defaultServe": { "distribution": null, "variation": "true" },
4+
"environment": "demoenv",
5+
"feature": "AlfaTest",
6+
"kind": "boolean",
7+
"offVariation": "false",
8+
"prerequisites": [],
9+
"project": "FeatureFlagsDemo",
10+
"rules": [
11+
{
12+
"ruleId": "",
13+
"priority": 1000,
14+
"clauses": [
15+
{
16+
"id": "",
17+
"attribute": "identifier",
18+
"op": "equal",
19+
"values": ["harness"]
20+
}
21+
],
22+
"serve": {
23+
"distribution": null,
24+
"variation": "true"
25+
}
26+
},
27+
{
28+
"ruleId": "",
29+
"priority": 999,
30+
"clauses": [
31+
{
32+
"id": "",
33+
"attribute": "identifier",
34+
"op": "equal",
35+
"values": ["harness"]
36+
}
37+
],
38+
"serve": {
39+
"distribution": null,
40+
"variation": "false"
41+
}
42+
}
43+
],
44+
"state": "on",
45+
"variationToTargetMap": null,
46+
"variations": [
47+
{
48+
"description": null,
49+
"identifier": "true",
50+
"name": "Enable Page",
51+
"value": "true"
52+
},
53+
{
54+
"description": null,
55+
"identifier": "false",
56+
"name": "Disable Page",
57+
"value": "false"
58+
}
59+
]
60+
},
61+
"targets": [
62+
{
63+
"identifier": "harness",
64+
"name": "Harness"
65+
},
66+
{
67+
"identifier": "enver",
68+
"attributes": {
69+
"email": "[email protected]"
70+
}
71+
}
72+
],
73+
"expected": {
74+
"_no_target": true,
75+
"harness": false
76+
}
77+
}

src/evaluator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ export class Evaluator {
216216
if (!target || !rules) {
217217
return undefined;
218218
}
219+
220+
rules.sort((a: ServingRule, b: ServingRule) =>
221+
a.priority > b.priority ? 1 : -1,
222+
);
223+
219224
let identifier: string;
220225
for (const rule of rules) {
221226
// if evaluation is false just continue to next rule

src/repository.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export class StorageRepository implements Repository {
2525

2626
setFlag(identifier: string, fc: FeatureConfig): void {
2727
const flagKey = this.formatFlagKey(identifier);
28+
if (this.isFlagOutdated(flagKey, fc)) {
29+
return;
30+
}
2831
if (this.store) {
2932
this.store.set(flagKey, fc);
3033
this.cache.del(flagKey);
@@ -35,6 +38,9 @@ export class StorageRepository implements Repository {
3538

3639
setSegment(identifier: string, segment: Segment): void {
3740
const segmentKey = this.formatSegmentKey(identifier);
41+
if (this.isSegmentOutdated(segmentKey, segment)) {
42+
return;
43+
}
3844
if (this.store) {
3945
this.store.set(segmentKey, segment);
4046
this.cache.del(segmentKey);
@@ -59,38 +65,48 @@ export class StorageRepository implements Repository {
5965
this.cache.del(segmentKey);
6066
}
6167

62-
getFlag(identifier: string): FeatureConfig {
68+
getFlag(identifier: string, cacheable = true): FeatureConfig {
6369
const flagKey = this.formatFlagKey(identifier);
6470
let flag = this.cache.get(flagKey) as FeatureConfig;
6571
if (flag) {
6672
return flag;
6773
}
6874
if (this.store) {
6975
flag = this.store.get(flagKey) as FeatureConfig;
70-
if (flag) {
76+
if (flag && cacheable) {
7177
this.cache.set(flagKey, flag);
7278
}
7379
return flag;
7480
}
7581
return undefined;
7682
}
7783

78-
getSegment(identifier: string): Segment {
84+
getSegment(identifier: string, cacheable = true): Segment {
7985
const segmentKey = this.formatSegmentKey(identifier);
8086
let segment = this.cache.get(segmentKey) as Segment;
8187
if (segment) {
8288
return segment;
8389
}
8490
if (this.store) {
8591
segment = this.store.get(segmentKey) as Segment;
86-
if (segment) {
92+
if (segment && cacheable) {
8793
this.cache.set(segmentKey, segment);
8894
}
8995
return segment;
9096
}
9197
return undefined;
9298
}
9399

100+
private isFlagOutdated(key: string, flag: FeatureConfig): boolean {
101+
const oldFlag = this.getFlag(key, false); // dont set cacheable, we are just checking the version
102+
return oldFlag?.version && oldFlag.version > flag?.version;
103+
}
104+
105+
private isSegmentOutdated(key: string, segment: Segment): boolean {
106+
const oldSegment = this.getSegment(key, false); // dont set cacheable, we are just checking the version
107+
return oldSegment?.version && oldSegment.version > segment?.version;
108+
}
109+
94110
private formatFlagKey(key: string): string {
95111
return `flags/${key}`;
96112
}

0 commit comments

Comments
 (0)