A couple of mentions 1. We need to add a finally block to the fetchAllFeatures invocation to reset the fetchInstance to null so that we can use the set the next promises. 2. We can skip "Array.shift" during unload and simple iterate over the array. Our check would change from `keys.length` to `index in keys`. This would help us optimise the solution as Array.shift would be an O(n) operation. Question link: devtools.tech/questions/s/how-to-implement-feature-flag-functionality-atlassian-frontend-interview-question---qid---af1JERRj92CZPrEyLl5z Practice with us: topmate.io/yomeshgupta Best coding practices: th-cam.com/video/9g1rYWJvvzY/w-d-xo.htmlsi=3KR-lnNf7GCcE_RU Other top questions -- Atlassian: th-cam.com/video/-wow5ApdZ0Y/w-d-xo.html Uber: th-cam.com/video/DCoIeGt4g7M/w-d-xo.html&start_radio=1 LinkedIn: th-cam.com/video/6euTBVDCD6o/w-d-xo.html Facebook: th-cam.com/video/7DJCpgc6V94/w-d-xo.html Atlassian: th-cam.com/video/3OxMsnP78zg/w-d-xo.html Klarna: th-cam.com/video/Py_bXjSMyTc/w-d-xo.html MakeMyTrip: th-cam.com/video/yHg0bvNqJEQ/w-d-xo.html Microsoft: th-cam.com/video/Iv1gZN900uc/w-d-xo.html AWS: th-cam.com/video/PFo1ZQBv4hA/w-d-xo.html Custom Loader: th-cam.com/video/E01XdDQgzDM/w-d-xo.html
The reason for using cookies is as cookies can be sent over request to server which is not in case of other client side storage . Also from server we can set cookies this makes cookies an ideal choice here.
At 5:20 Why we are using cookie? Cookies are used here because it automatically get send back to server with every request and we can control it from server-side. Yes, we can use local storage and indexDB but it will require manually sending necessary key to server and then storing it in the browser. Not very practical. Session storage data is specific to the current window or tab. Any data stored in session storage is only accessible to the web pages within the same window or tab. So it not preferred because user might see different UI on another tab/window considering that server has no way to guess use preference.
Shouldn't *fetchInstance* store the promise returned from *fetchAllFeatures()* ? at 18:24 *fetchInstance* is storing *fetchAllFeatures().then(featureFlags () => {})* So further calls won't receive the *featureFlags* and will return default value. Please correct me if I am missing something.
@@DevtoolsTech Can you log and check the value of *featureFlags* inside the *if (fetchInstance instanceof Promise)* block? I think it's not returning the object but rather the previous boolean value
We need to reset the the fetchInstance in the finally block like fetchAllFeatutes.finally(...). This would reset the value and next time fetchInstance would assigned a new promise when cache is stale. I will try what are you saying.
FetchInstance is always resolving their promises... Resolving a promise means It always calls the API from the BE...instead we can cache return data from fetchAllFlags
It is not always resolving. We are checking if there is cache data then return from cache. Resolving doesn't mean API call. If a promise already resolved and we attach then callbacks then they are executed right away without API call or state change. We only make a call to API if cache is invalid.
Wouldn't putting a large amount of feature flags into a cookie be a bad idea as this is always sent back to the server? (unnecessary sending a large amount of data)
We only put current running feature flags with values into the cookie. Each feature flag would be a separate cookie. The amount of cookies sent back to the server depends upon the no. of experiments currently running. It is always advised to run experiments for a fixed time and timely clean up once we are done.
Very nice question and solution. I think you missed to tell the fact that why you chose not to declare the fetch instance with any keyword(var, let, and const) which is important in this case as I think it will create a new fetchInstance again and again if you had used any of the keywords and in this case it will declared as a global variable.. thats why its working correctly if I am not mistaken.
What if I do this ? return featureFlags?.[featureName] ?? defaultValue It will go to the default value only if the left expression value is either null or undefined.
That can be added if required. However, it is better to fetch in bulk in such cases because fetching individual flags by millions of users might overwhelm the server. It is better to make as little calls as possible.
A couple of mentions
1. We need to add a finally block to the fetchAllFeatures invocation to reset the fetchInstance to null so that we can use the set the next promises.
2. We can skip "Array.shift" during unload and simple iterate over the array. Our check would change from `keys.length` to `index in keys`. This would help us optimise the solution as Array.shift would be an O(n) operation.
Question link: devtools.tech/questions/s/how-to-implement-feature-flag-functionality-atlassian-frontend-interview-question---qid---af1JERRj92CZPrEyLl5z
Practice with us: topmate.io/yomeshgupta
Best coding practices: th-cam.com/video/9g1rYWJvvzY/w-d-xo.htmlsi=3KR-lnNf7GCcE_RU
Other top questions --
Atlassian: th-cam.com/video/-wow5ApdZ0Y/w-d-xo.html
Uber: th-cam.com/video/DCoIeGt4g7M/w-d-xo.html&start_radio=1
LinkedIn: th-cam.com/video/6euTBVDCD6o/w-d-xo.html
Facebook: th-cam.com/video/7DJCpgc6V94/w-d-xo.html
Atlassian: th-cam.com/video/3OxMsnP78zg/w-d-xo.html
Klarna: th-cam.com/video/Py_bXjSMyTc/w-d-xo.html
MakeMyTrip: th-cam.com/video/yHg0bvNqJEQ/w-d-xo.html
Microsoft: th-cam.com/video/Iv1gZN900uc/w-d-xo.html
AWS: th-cam.com/video/PFo1ZQBv4hA/w-d-xo.html
Custom Loader: th-cam.com/video/E01XdDQgzDM/w-d-xo.html
The reason for using cookies is as cookies can be sent over request to server which is not in case of other client side storage . Also from server we can set cookies this makes cookies an ideal choice here.
Correct! 👏🏼
At 5:20 Why we are using cookie?
Cookies are used here because it automatically get send back to server with every request and we can control it from server-side.
Yes, we can use local storage and indexDB but it will require manually sending necessary key to server and then storing it in the browser. Not very practical.
Session storage data is specific to the current window or tab. Any data stored in session storage is only accessible to the web pages within the same window or tab. So it not preferred because user might see different UI on another tab/window considering that server has no way to guess use preference.
Right. 🙌🏼
Thanks Yomesh was waiting for this.
Do share your feedback! Also, do share he videos with others. Thanks! 🙏🏻
Shouldn't *fetchInstance* store the promise returned from *fetchAllFeatures()* ?
at 18:24 *fetchInstance* is storing *fetchAllFeatures().then(featureFlags () => {})*
So further calls won't receive the *featureFlags* and will return default value.
Please correct me if I am missing something.
It is storing the return promise.
One thing I missed is that we should add a finally block and set fetchInstance to null.
@@DevtoolsTech Can you log and check the value of *featureFlags* inside the *if (fetchInstance instanceof Promise)* block?
I think it's not returning the object but rather the previous boolean value
We need to reset the the fetchInstance in the finally block like fetchAllFeatutes.finally(...). This would reset the value and next time fetchInstance would assigned a new promise when cache is stale.
I will try what are you saying.
FetchInstance is always resolving their promises... Resolving a promise means It always calls the API from the BE...instead we can cache return data from fetchAllFlags
It is not always resolving. We are checking if there is cache data then return from cache. Resolving doesn't mean API call. If a promise already resolved and we attach then callbacks then they are executed right away without API call or state change. We only make a call to API if cache is invalid.
Wouldn't putting a large amount of feature flags into a cookie be a bad idea as this is always sent back to the server? (unnecessary sending a large amount of data)
We only put current running feature flags with values into the cookie. Each feature flag would be a separate cookie. The amount of cookies sent back to the server depends upon the no. of experiments currently running. It is always advised to run experiments for a fixed time and timely clean up once we are done.
Very nice question and solution. I think you missed to tell the fact that why you chose not to declare the fetch instance with any keyword(var, let, and const) which is important in this case as I think it will create a new fetchInstance again and again if you had used any of the keywords and in this case it will declared as a global variable.. thats why its working correctly if I am not mistaken.
Thanks for the sharing your feedback. I added in the comments that it would be better to add a finally block to reset the the fetchInstance to null.
Very informative 👏👏
Thank you. More coming soon! 🙌🏼
What if I do this ?
return featureFlags?.[featureName] ?? defaultValue
It will go to the default value only if the left expression value is either null or undefined.
Yes. This works too. Nullish coalescing operator is a good choice too. Thanks for sharing. 🙌🏼
I was thinking the same.. this can definitely work
lets say if ttl needs to be set for each feature flag? and add ff to cache in lazy manner rather than eager loading? Any thought on this
You can add ttl to each feature flag. Can use something like a Map for it.
Why would you to want add it in lazy manner? What is the use-case?
i feel each feature name should have a separate timestamp while storing in cache
That can be added if required. However, it is better to fetch in bulk in such cases because fetching individual flags by millions of users might overwhelm the server. It is better to make as little calls as possible.
Cool. I have solved this question earlier.
Do share your solution and provide feedback on mine.