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

Subscriptions: Better platform selection #14004

Merged
merged 21 commits into from Mar 15, 2018

Conversation

prateekbh
Copy link
Member

  • better platform selection with weights
  • default platform selection is always local
  • refactored entitlementStore to PlatformStore

*/
pingback() {}

/** override */
Copy link
Contributor

Choose a reason for hiding this comment

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

@override

Copy link
Member Author

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(),
Copy link
Contributor

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.

Copy link
Member Author

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(),
Copy link
Contributor

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.

Copy link
Member Author

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 */
Copy link
Contributor

Choose a reason for hiding this comment

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

@override

Copy link
Member Author

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) {
Copy link
Contributor

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.

Copy link
Member Author

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)) {
Copy link
Contributor

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.

Copy link
Member Author

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() {
Copy link
Contributor

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".

Copy link
Member Author

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()] =
Copy link
Contributor

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.

Copy link
Member Author

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 = {};
Copy link
Contributor

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

Copy link
Member Author

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());
Copy link
Contributor

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.

Copy link
Member Author

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

Copy link
Contributor

@dvoytenko dvoytenko left a 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}
Copy link
Contributor

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;
Copy link
Contributor

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.

@prateekbh prateekbh merged commit e738264 into ampproject:master Mar 15, 2018
@prateekbh prateekbh deleted the betterPlatformSelection branch March 15, 2018 20:09
dvoytenko pushed a commit that referenced this pull request Mar 16, 2018
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants