{"action":"created","comment":{"url":"https://api.github.com/repos/vigetlabs/diode/pulls/comments/31435542","id":31435542,"diff_hunk":"@@ -18,15 +25,26 @@ function Diode(target) {\n    * Callbacks are eventually executed, Diode does not promise\n    * immediate consistency so that state propagation can be batched\n    */\n-  var _flush = function() {\n+  var _flush = function(args) {\n     /**\n      * Important: do not cache the length of _callbacks\n      * in the event a callback causes later subscriptions\n      * to disappear\n      */\n     for (var i = 0; i < _callbacks.length; i++) {\n-      _callbacks[i].apply(target, arguments)\n+      _callbacks[i].apply(target, args)\n+    }\n+  }\n+\n+  var _cancel = function() {\n+    var now = +new Date() // IE8 love\n+\n+    if (_lastFire && now - _lastFire < 10) {\n+      cancelAnimationFrame(_tick)","path":"src/diode.js","position":38,"original_position":38,"commit_id":"71d371300e2889bf5e98b964fb2449edec5a37c4","original_commit_id":"71d371300e2889bf5e98b964fb2449edec5a37c4","user":{"login":"greypants","id":647549,"avatar_url":"https://avatars.githubusercontent.com/u/647549?v=3","gravatar_id":"","url":"https://api.github.com/users/greypants","html_url":"https://github.com/greypants","followers_url":"https://api.github.com/users/greypants/followers","following_url":"https://api.github.com/users/greypants/following{/other_user}","gists_url":"https://api.github.com/users/greypants/gists{/gist_id}","starred_url":"https://api.github.com/users/greypants/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greypants/subscriptions","organizations_url":"https://api.github.com/users/greypants/orgs","repos_url":"https://api.github.com/users/greypants/repos","events_url":"https://api.github.com/users/greypants/events{/privacy}","received_events_url":"https://api.github.com/users/greypants/received_events","type":"User","site_admin":false},"body":"Why do you need to cancel? Why can't the _tick method just run whatever the most current information is? Which could be nothing I guess. Something like:\r\n\r\n```\r\nvar currentCallbacks = []\r\n// Update ^ however frequently you need to outside of requestAnimationFrame\r\n\r\nrequestAnimationFrame(function(){\r\n  currentCallbacks.forEach((callback) => callback())\r\n})\r\n```","created_at":"2015-06-01T15:19:25Z","updated_at":"2015-06-01T15:19:25Z","html_url":"https://github.com/vigetlabs/diode/pull/5#discussion_r31435542","pull_request_url":"https://api.github.com/repos/vigetlabs/diode/pulls/5","_links":{"self":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/comments/31435542"},"html":{"href":"https://github.com/vigetlabs/diode/pull/5#discussion_r31435542"},"pull_request":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/5"}}},"pull_request":{"url":"https://api.github.com/repos/vigetlabs/diode/pulls/5","id":36623920,"html_url":"https://github.com/vigetlabs/diode/pull/5","diff_url":"https://github.com/vigetlabs/diode/pull/5.diff","patch_url":"https://github.com/vigetlabs/diode/pull/5.patch","issue_url":"https://api.github.com/repos/vigetlabs/diode/issues/5","number":5,"state":"open","locked":false,"title":"[update] Allow Diode to leak frames every 120FPS","user":{"login":"nhunzaker","id":590904,"avatar_url":"https://avatars.githubusercontent.com/u/590904?v=3","gravatar_id":"","url":"https://api.github.com/users/nhunzaker","html_url":"https://github.com/nhunzaker","followers_url":"https://api.github.com/users/nhunzaker/followers","following_url":"https://api.github.com/users/nhunzaker/following{/other_user}","gists_url":"https://api.github.com/users/nhunzaker/gists{/gist_id}","starred_url":"https://api.github.com/users/nhunzaker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nhunzaker/subscriptions","organizations_url":"https://api.github.com/users/nhunzaker/orgs","repos_url":"https://api.github.com/users/nhunzaker/repos","events_url":"https://api.github.com/users/nhunzaker/events{/privacy}","received_events_url":"https://api.github.com/users/nhunzaker/received_events","type":"User","site_admin":false},"body":"If within an animation loop, it was possible to hit race conditions (I believe this is the right term for it) where requesting another loop before performing work would cause Diode's change event to always cancel. \r\n\r\nThis means that this code would properly animate:\r\n\r\n```javascript\r\nrequestAnimationFrame(function loop () {\r\n  update() // totally fires, I guess because it gets put onto the stack before the next frame?\r\n  requestAnimationFrame(loop)\r\n})\r\n```\r\n\r\nHowever this would not:\r\n\r\n```javascript\r\nrequestAnimationFrame(function loop () {\r\n  requestAnimationFrame(loop)\r\n  update() // magically forgotten\r\n})\r\n```\r\n\r\nI still don't fully understand the mechanisms at play. @greypants: any ideas? \r\n\r\nAt any rate, this PR makes it so that every 120FPS, a frame will \"leak\" out. This allows Diode to blast a firehose of change events, batch them together, however make sure that a change event consistently fires at an expected interval.\r\n\r\nThe result of this is that in Microcosm, you can have an animation loop constantly blast the system with actions and it will properly animate in all cases:\r\n\r\n![logo_after](https://cloud.githubusercontent.com/assets/590904/7912785/567b43b4-0838-11e5-82f7-db02742b8f11.gif)\r\n\r\n```javascript\r\napp.listen(function() {\r\n  React.render(<Viget circle={ app.get('circle')}/>, body)\r\n})\r\n\r\nrequestAnimationFrame(function loop () {\r\n  requestAnimationFrame(loop)\r\n  app.push(updateCircle)\r\n})\r\n```","created_at":"2015-06-01T12:30:30Z","updated_at":"2015-06-01T15:19:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6ecc9e0ee49959b4ce58084dcf7db247e923c93e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/vigetlabs/diode/pulls/5/commits","review_comments_url":"https://api.github.com/repos/vigetlabs/diode/pulls/5/comments","review_comment_url":"https://api.github.com/repos/vigetlabs/diode/pulls/comments{/number}","comments_url":"https://api.github.com/repos/vigetlabs/diode/issues/5/comments","statuses_url":"https://api.github.com/repos/vigetlabs/diode/statuses/71d371300e2889bf5e98b964fb2449edec5a37c4","head":{"label":"vigetlabs:raf-leak","ref":"raf-leak","sha":"71d371300e2889bf5e98b964fb2449edec5a37c4","user":{"login":"vigetlabs","id":4845,"avatar_url":"https://avatars.githubusercontent.com/u/4845?v=3","gravatar_id":"","url":"https://api.github.com/users/vigetlabs","html_url":"https://github.com/vigetlabs","followers_url":"https://api.github.com/users/vigetlabs/followers","following_url":"https://api.github.com/users/vigetlabs/following{/other_user}","gists_url":"https://api.github.com/users/vigetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/vigetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vigetlabs/subscriptions","organizations_url":"https://api.github.com/users/vigetlabs/orgs","repos_url":"https://api.github.com/users/vigetlabs/repos","events_url":"https://api.github.com/users/vigetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/vigetlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":29732313,"name":"diode","full_name":"vigetlabs/diode","owner":{"login":"vigetlabs","id":4845,"avatar_url":"https://avatars.githubusercontent.com/u/4845?v=3","gravatar_id":"","url":"https://api.github.com/users/vigetlabs","html_url":"https://github.com/vigetlabs","followers_url":"https://api.github.com/users/vigetlabs/followers","following_url":"https://api.github.com/users/vigetlabs/following{/other_user}","gists_url":"https://api.github.com/users/vigetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/vigetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vigetlabs/subscriptions","organizations_url":"https://api.github.com/users/vigetlabs/orgs","repos_url":"https://api.github.com/users/vigetlabs/repos","events_url":"https://api.github.com/users/vigetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/vigetlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/vigetlabs/diode","description":"An extremely small, single event emitter","fork":false,"url":"https://api.github.com/repos/vigetlabs/diode","forks_url":"https://api.github.com/repos/vigetlabs/diode/forks","keys_url":"https://api.github.com/repos/vigetlabs/diode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vigetlabs/diode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vigetlabs/diode/teams","hooks_url":"https://api.github.com/repos/vigetlabs/diode/hooks","issue_events_url":"https://api.github.com/repos/vigetlabs/diode/issues/events{/number}","events_url":"https://api.github.com/repos/vigetlabs/diode/events","assignees_url":"https://api.github.com/repos/vigetlabs/diode/assignees{/user}","branches_url":"https://api.github.com/repos/vigetlabs/diode/branches{/branch}","tags_url":"https://api.github.com/repos/vigetlabs/diode/tags","blobs_url":"https://api.github.com/repos/vigetlabs/diode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vigetlabs/diode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vigetlabs/diode/git/refs{/sha}","trees_url":"https://api.github.com/repos/vigetlabs/diode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vigetlabs/diode/statuses/{sha}","languages_url":"https://api.github.com/repos/vigetlabs/diode/languages","stargazers_url":"https://api.github.com/repos/vigetlabs/diode/stargazers","contributors_url":"https://api.github.com/repos/vigetlabs/diode/contributors","subscribers_url":"https://api.github.com/repos/vigetlabs/diode/subscribers","subscription_url":"https://api.github.com/repos/vigetlabs/diode/subscription","commits_url":"https://api.github.com/repos/vigetlabs/diode/commits{/sha}","git_commits_url":"https://api.github.com/repos/vigetlabs/diode/git/commits{/sha}","comments_url":"https://api.github.com/repos/vigetlabs/diode/comments{/number}","issue_comment_url":"https://api.github.com/repos/vigetlabs/diode/issues/comments{/number}","contents_url":"https://api.github.com/repos/vigetlabs/diode/contents/{+path}","compare_url":"https://api.github.com/repos/vigetlabs/diode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vigetlabs/diode/merges","archive_url":"https://api.github.com/repos/vigetlabs/diode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vigetlabs/diode/downloads","issues_url":"https://api.github.com/repos/vigetlabs/diode/issues{/number}","pulls_url":"https://api.github.com/repos/vigetlabs/diode/pulls{/number}","milestones_url":"https://api.github.com/repos/vigetlabs/diode/milestones{/number}","notifications_url":"https://api.github.com/repos/vigetlabs/diode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vigetlabs/diode/labels{/name}","releases_url":"https://api.github.com/repos/vigetlabs/diode/releases{/id}","created_at":"2015-01-23T12:51:25Z","updated_at":"2015-05-04T12:52:13Z","pushed_at":"2015-06-01T12:35:13Z","git_url":"git://github.com/vigetlabs/diode.git","ssh_url":"git@github.com:vigetlabs/diode.git","clone_url":"https://github.com/vigetlabs/diode.git","svn_url":"https://github.com/vigetlabs/diode","homepage":"","size":404,"stargazers_count":4,"watchers_count":4,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":4,"default_branch":"master"}},"base":{"label":"vigetlabs:master","ref":"master","sha":"c55b34aed670396270b90a38c7ee4f7f5443ff17","user":{"login":"vigetlabs","id":4845,"avatar_url":"https://avatars.githubusercontent.com/u/4845?v=3","gravatar_id":"","url":"https://api.github.com/users/vigetlabs","html_url":"https://github.com/vigetlabs","followers_url":"https://api.github.com/users/vigetlabs/followers","following_url":"https://api.github.com/users/vigetlabs/following{/other_user}","gists_url":"https://api.github.com/users/vigetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/vigetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vigetlabs/subscriptions","organizations_url":"https://api.github.com/users/vigetlabs/orgs","repos_url":"https://api.github.com/users/vigetlabs/repos","events_url":"https://api.github.com/users/vigetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/vigetlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":29732313,"name":"diode","full_name":"vigetlabs/diode","owner":{"login":"vigetlabs","id":4845,"avatar_url":"https://avatars.githubusercontent.com/u/4845?v=3","gravatar_id":"","url":"https://api.github.com/users/vigetlabs","html_url":"https://github.com/vigetlabs","followers_url":"https://api.github.com/users/vigetlabs/followers","following_url":"https://api.github.com/users/vigetlabs/following{/other_user}","gists_url":"https://api.github.com/users/vigetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/vigetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vigetlabs/subscriptions","organizations_url":"https://api.github.com/users/vigetlabs/orgs","repos_url":"https://api.github.com/users/vigetlabs/repos","events_url":"https://api.github.com/users/vigetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/vigetlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/vigetlabs/diode","description":"An extremely small, single event emitter","fork":false,"url":"https://api.github.com/repos/vigetlabs/diode","forks_url":"https://api.github.com/repos/vigetlabs/diode/forks","keys_url":"https://api.github.com/repos/vigetlabs/diode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vigetlabs/diode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vigetlabs/diode/teams","hooks_url":"https://api.github.com/repos/vigetlabs/diode/hooks","issue_events_url":"https://api.github.com/repos/vigetlabs/diode/issues/events{/number}","events_url":"https://api.github.com/repos/vigetlabs/diode/events","assignees_url":"https://api.github.com/repos/vigetlabs/diode/assignees{/user}","branches_url":"https://api.github.com/repos/vigetlabs/diode/branches{/branch}","tags_url":"https://api.github.com/repos/vigetlabs/diode/tags","blobs_url":"https://api.github.com/repos/vigetlabs/diode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vigetlabs/diode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vigetlabs/diode/git/refs{/sha}","trees_url":"https://api.github.com/repos/vigetlabs/diode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vigetlabs/diode/statuses/{sha}","languages_url":"https://api.github.com/repos/vigetlabs/diode/languages","stargazers_url":"https://api.github.com/repos/vigetlabs/diode/stargazers","contributors_url":"https://api.github.com/repos/vigetlabs/diode/contributors","subscribers_url":"https://api.github.com/repos/vigetlabs/diode/subscribers","subscription_url":"https://api.github.com/repos/vigetlabs/diode/subscription","commits_url":"https://api.github.com/repos/vigetlabs/diode/commits{/sha}","git_commits_url":"https://api.github.com/repos/vigetlabs/diode/git/commits{/sha}","comments_url":"https://api.github.com/repos/vigetlabs/diode/comments{/number}","issue_comment_url":"https://api.github.com/repos/vigetlabs/diode/issues/comments{/number}","contents_url":"https://api.github.com/repos/vigetlabs/diode/contents/{+path}","compare_url":"https://api.github.com/repos/vigetlabs/diode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vigetlabs/diode/merges","archive_url":"https://api.github.com/repos/vigetlabs/diode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vigetlabs/diode/downloads","issues_url":"https://api.github.com/repos/vigetlabs/diode/issues{/number}","pulls_url":"https://api.github.com/repos/vigetlabs/diode/pulls{/number}","milestones_url":"https://api.github.com/repos/vigetlabs/diode/milestones{/number}","notifications_url":"https://api.github.com/repos/vigetlabs/diode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vigetlabs/diode/labels{/name}","releases_url":"https://api.github.com/repos/vigetlabs/diode/releases{/id}","created_at":"2015-01-23T12:51:25Z","updated_at":"2015-05-04T12:52:13Z","pushed_at":"2015-06-01T12:35:13Z","git_url":"git://github.com/vigetlabs/diode.git","ssh_url":"git@github.com:vigetlabs/diode.git","clone_url":"https://github.com/vigetlabs/diode.git","svn_url":"https://github.com/vigetlabs/diode","homepage":"","size":404,"stargazers_count":4,"watchers_count":4,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/5"},"html":{"href":"https://github.com/vigetlabs/diode/pull/5"},"issue":{"href":"https://api.github.com/repos/vigetlabs/diode/issues/5"},"comments":{"href":"https://api.github.com/repos/vigetlabs/diode/issues/5/comments"},"review_comments":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/5/comments"},"review_comment":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/vigetlabs/diode/pulls/5/commits"},"statuses":{"href":"https://api.github.com/repos/vigetlabs/diode/statuses/71d371300e2889bf5e98b964fb2449edec5a37c4"}}}}