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

Better timeout handling #1642

Closed
wants to merge 17 commits into from
Closed

Better timeout handling #1642

wants to merge 17 commits into from

Conversation

mmcc
Copy link
Member

@mmcc mmcc commented Nov 5, 2014

Right now, each time we create a timeout or interval within an instance of the player, we must also set up dispose listeners to clean up those timers. This PR adds a setTimeout and setInterval method on the player that behaves exactly the same as those native functions except they automatically add the dispose listener.

@@ -1127,6 +1127,7 @@ vjs.Component.prototype.enableTouchActivity = function() {

// listener for reporting that the user is active
report = vjs.bind(this.player(), this.player().reportUserActivity);
interval = vjs.bind(this.player(), this.player().setInterval);
Copy link
Member

Choose a reason for hiding this comment

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

we probably should just capture player() as a variable, it's silly to call this function 4 times in two lines.

* @return {Number} Returns the timeout ID
*/
vjs.Player.prototype.setTimeout = function(fn, timeout) {
var timeoutId = setTimeout(fn, timeout);
Copy link
Member

Choose a reason for hiding this comment

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

let's say window.setTimout here to be verbose

Copy link
Member

Choose a reason for hiding this comment

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

let's bind the function to this by default. Otherwise it will execute in the window scope, which is less useful. Also event listeners work that way.

Copy link
Member

Choose a reason for hiding this comment

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

binding to this will change the semantics of our setTimeout compared to the global window.setTimeout.

Copy link
Member

Choose a reason for hiding this comment

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

Depends on how you look at it. With window.setTimeout the scope is window. With player.setTimeout I would expect the scope to be player.

Copy link
Member

Choose a reason for hiding this comment

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

Yep, just pointing it out.

@heff
Copy link
Member

heff commented Nov 7, 2014

Pasting the code we fleshed out for adding the this.clearTimeout equivalent, that also removes the dispose listener.

vjs.Player.prototype.setInterval = function(fn, interval) {
  fn = vjs.bind(this, fn);

  var intervalId = setInterval(fn, interval);

  var disposeFn = function() {
    clearInterval(intervalId);
  };

  disposeFn.guid = 'vjs-interval-'+intervalId;

  this.on('dispose', disposeFn);

  return intervalId;
};

vjs.Player.prototype.clearInterval = function(intervalId) {
  window.clearInterval(intervalId);

  var disposeFn = function(){};
  disposeFn.guid = 'vjs-interval-'+intervalId;

  this.off('dispose', disposeFn);

  return intervalId;
};

@mmcc
Copy link
Member Author

mmcc commented Nov 17, 2014

Just to note what the current status of this is, the PR is good to go in terms of getting us back to the original functionality, but we're still seeing a bug on dispose when a chapter track is involved.

@gkatsev
Copy link
Member

gkatsev commented Nov 17, 2014

@mmcc I've solved that issue in my PR (#1656) and the commit is: gkatsev@85249f6

@mmcc
Copy link
Member Author

mmcc commented Nov 17, 2014

you're the man

@mmcc
Copy link
Member Author

mmcc commented Nov 17, 2014

Then this should be good to go. I was convinced I'd missed a timer somewhere...

@@ -1118,7 +1118,7 @@ vjs.Component.prototype.emitTapEvents = function(){
* want touch events to act differently.
*/
vjs.Component.prototype.enableTouchActivity = function() {
var report, touchHolding, touchEnd;
var report, interval, touchHolding, touchEnd;
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like interval is used anywhere here.

@heff
Copy link
Member

heff commented Nov 25, 2014

Aside from a few notes this looks great. It cleans a bunch of things up nicely, including some areas where we weren't already cleaning up intervals.

So tests...
You can use the recent event listener tests as a starting model, and then Sinon timers will come in handy for this. We can pair on this if you want.

@mmcc
Copy link
Member Author

mmcc commented Nov 26, 2014

I was about to get all indignant about tests because I remembered the time-to-green struggle.

...but that was to fix the weird sinon timeout issue with the current tests. These should be pretty easy, I'll take care of them + the changes in the next few days.

@mmcc mmcc mentioned this pull request Dec 1, 2014

module('Component', {
'setup': function() {
componentClock = sinon.useFakeTimers();
Copy link
Member

Choose a reason for hiding this comment

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

In think there's a way you could do this.componentClock here, and use that in the tests, if you wanted to avoid the global.

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 cool, I was just blindly following what we did in other tests. I'll give it a try.

@mmcc
Copy link
Member Author

mmcc commented Dec 2, 2014

I went ahead and removed a few globals that I remember seeing in other tests in case you're wondering where those changes came from.

}, 1000);

componentClock.tick(100);

Copy link
Member

Choose a reason for hiding this comment

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

You probably want a ok(timeoutsFired === 1, 'One timeout should have fired'); here also, just in case the first one fails but a later one succeeds

@heff
Copy link
Member

heff commented Dec 2, 2014

Tests look good to me!

@heff
Copy link
Member

heff commented Dec 3, 2014

Could you merge this with master? There's some noops that are breaking in test/unit/media.js after merging.

@mmcc mmcc closed this in 1f6c517 Dec 3, 2014
@mmcc mmcc mentioned this pull request Oct 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants