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
Subscriptions: Better platform selection #14004
Subscriptions: Better platform selection #14004
Conversation
…ullEntitlements
*/ | ||
pingback() {} | ||
|
||
/** override */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@override
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
if (this.viewTrackerPromise_) { | ||
this.viewTrackerPromise_.then(() => { | ||
const localPlatform = /** @type {!LocalSubscriptionPlatform} */ ( | ||
user().assert(this.platformStore_.getLocalPlatform(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the user().assert()
should just go to getLocalPlatform
implementation itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, it already is, should just remove from here
@@ -327,7 +321,7 @@ export class SubscriptionService { | |||
*/ | |||
delegateActionToLocal(action) { | |||
const localPlatform = /** @type {LocalSubscriptionPlatform} */ ( | |||
dev().assert(this.subscriptionPlatforms_['local'], | |||
dev().assert(this.platformStore_.getLocalPlatform(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then this goes away as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, it already is, should just remove from here
@@ -218,6 +218,11 @@ export class LocalSubscriptionPlatform { | |||
}); | |||
}); | |||
} | |||
|
|||
/** override */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@override
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
* @param {string} servideId | ||
* @returns {!./subscription-platform.SubscriptionPlatform} | ||
*/ | ||
getPlatform(servideId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method seems a bit dangerous. It looks like it's fine for local
platform, but not for others. I recommend you make it private. Eventually if we need something like this for non-local platforms, we'll add a new method with promise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
getAllResolvedPlatforms() { | ||
const platforms = []; | ||
for (const platformKey in this.subscriptionPlatforms_) { | ||
if (this.subscriptionPlatforms_.hasOwnProperty(platformKey)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for hasOwnProperty here. But if you'd like, you should use hasOwn
from object.js
utils to avoid compatibility issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
* Returns all the platforms; | ||
* @returns {!Array<!./subscription-platform.SubscriptionPlatform>} | ||
*/ | ||
getAllResolvedPlatforms() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it need to be public? The name is also confused - this is a registered platform, not resolved since "resolved" further used to mean "entitlements are known".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nups, and yes bad name as well. Changed
|
||
// If supports the current viewer, gains weight 9 | ||
if (platform.supportsCurrentViewer()) { | ||
platformWeights[platform.getServiceId()] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calculate via local var and assign to the map in the end when the score is ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont really understand this one completely but, I guess i have flattened the algo a bit
const localPlatform = this.getLocalPlatform(); | ||
|
||
/** @type {!Object<string, number>} */ | ||
const platformWeights = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just build weightSorted
array right away? Instead of building a temp map and then copying it over? Further, you keep looking up by serviceId, but you already have platform instances. You can do this:
/** @type {!Array<{platform: Platform, weight: number}>} */
const platformWeights = [];
forEach(platform => {
const weight = calculayeWeight(platform, entitlement);
platformWeights.push({platform, weight});
});
platformWeights.sort((p1, p2) {
return p2.weight - p1.weight;
});
// the rest as you have
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
|
||
this.getAllResolvedPlatforms().forEach(platform => { | ||
const entitlement = | ||
this.getResolvedEntitlementFor(platform.getServiceId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are iterating here over getAllResolvedPlatforms(), while calling getResolvedEntitlemntFor. But they are not resolved in tandem (one simply depends on subscriptionplatforms_ var, the other on entitlements_ var). Thus you are spilling too much asynchronous state via synchronous and, it looks to me, bugs are very likely.
Also, we need to minimize public methods returning synchronous/resolved stuff - there shouldn't be any need for them. It's ok to have some minimal API for local platform, but everything else should be async.
To fix this particular issue, however, it looks like you can simply need to ignore a platform that doesn't have entitlements yet. Or you can wait until all platforms have been resolved, but that's not what getAllResolvedPlatforms
does know as far as I can tell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getAllResolvedPlatforms()
is just wrongly named and is more like an iteration over the resolved ones.
Also the entire thing starts after getAllPlatformsEntitlements_
so it should be safe to assume, we might not run into race condition thingy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with couple comments.
* | ||
* In the end candidate with max weight is selected. | ||
* However if candidate's weight is equal to local platform, then local platform is selected. | ||
* @returns {!./subscription-platform.SubscriptionPlatform} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add @private
|
||
/** @override */ | ||
supportsCurrentViewer() { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please return this.isGoogleViewer_
here since that PR is merged now.
…etterPlatformSelection
* adding pingback * adding test * adding viewer tracker * adding tests for viewer tracker * adding more tests * fixing tests * fixing tests * fixing tests * adding undefined for entitlements * fixing all subscriptions denied use case * Building platformStore * adding parameters over platform selection * adding tests for select platform * fixing comments * type fixes * adding assert in select platform * fixing scope * fixing types
entitlementStore
toPlatformStore