{"action":"created","comment":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments/47156892","id":47156892,"diff_hunk":"@@ -0,0 +1,96 @@\n+import { fromJS } from 'immutable';\n+\n+export const EVERY_SECOND = 1000;\n+export const EVERY_FIVE_SECONDS = 5 * 1000;\n+export const EVERY_TEN_SECONDS = 10 * 1000;\n+export const EVERY_THIRTY_SECONDS = 30 * 1000;\n+export const EVERY_MINUTE = 60 * 1000;\n+\n+const initialState = fromJS( {\n+\tnextId: 1,\n+\tperiodTimers: {\n+\t\tEVERY_SECOND: null,\n+\t\tEVERY_FIVE_SECONDS: null,\n+\t\tEVERY_TEN_SECONDS: null,\n+\t\tEVERY_THIRTY_SECONDS: null,\n+\t\tEVERY_MINUTE: null\n+\t},\n+\tactions: []\n+} );\n+let state = initialState;\n+\n+const increment = a => a + 1;\n+const push = item => list => list.push( item );\n+const pull = id => list => list.filterNot( o => o.get( 'id' ) === id );\n+\n+export const resetForTesting = () => {\n+\tstate\n+\t\t.get( 'periodTimers' )\n+\t\t.forEach( clearTimeout );\n+\n+\tstate = initialState;\n+};\n+\n+export function add( period, onTick ) {\n+\tconst id = state.get( 'nextId' );\n+\n+\tstoreNewAction( { id, period, onTick } );\n+\tscheduleNextRun();\n+\n+\treturn id;\n+}\n+\n+function storeNewAction( { id, period, onTick } ) {\n+\tstate = state\n+\t\t.update( 'actions', push( fromJS( { id, period, onTick } ) ) )\n+\t\t.update( 'nextId', increment );\n+\n+\treturn state.get( 'nextId' );\n+}\n+\n+export function remove( id ) {\n+\tremoveStoredAction( id );\n+\tscheduleNextRun();\n+}\n+\n+function removeStoredAction( id ) {\n+\tstate = state.update( 'actions', pull( id ) );\n+}\n+\n+function getPeriodActions( period ) {\n+\treturn state\n+\t\t.get( 'actions' )\n+\t\t.filter( a => a.get( 'period' ) === period );\n+}\n+\n+function hasPeriodActions( period ) {\n+\treturn state\n+\t\t.get( 'actions' )\n+\t\t.some( a => a.get( 'period' ) === period );\n+}\n+\n+function executePeriodActions( period ) {\n+\tgetPeriodActions( period )\n+\t\t// since onTick() could explicitly return `false` and\n+\t\t// that would terminate the iteration from forEach(),\n+\t\t// we need to make sure we don't allow that to happen\n+\t\t.forEach( a => a.get( 'onTick' ).call() || true );\n+\n+\tstate = state.setIn( [ 'periodTimers', period ], null );\n+\n+\tscheduleNextRun();\n+}\n+\n+function scheduleNextRun() {\n+\t[ EVERY_SECOND, EVERY_FIVE_SECONDS, EVERY_TEN_SECONDS, EVERY_THIRTY_SECONDS, EVERY_MINUTE ]\n+\t\t.forEach( p => {\n+\t\t\tif ( ! hasPeriodActions( p ) ) {\n+\t\t\t\tstate = state.updateIn( [ 'periodTimers', p ], clearTimeout );\n+\t\t\t\treturn;\n+\t\t\t}\n+\n+\t\t\tif ( ! state.get( 'periodTimers' ).get( p ) ) {\n+\t\t\t\tstate = state.setIn( [ 'periodTimers', p ], setTimeout( () => executePeriodActions( p ), p ) );","path":"client/lib/interval/runner.js","position":null,"original_position":93,"commit_id":"1357d2cdbfda368975903ebcf52dc89c527017a3","original_commit_id":"0ca7c2967e6c36329f6219510215736da3193def","user":{"login":"dmsnell","id":5431237,"avatar_url":"https://avatars.githubusercontent.com/u/5431237?v=3","gravatar_id":"","url":"https://api.github.com/users/dmsnell","html_url":"https://github.com/dmsnell","followers_url":"https://api.github.com/users/dmsnell/followers","following_url":"https://api.github.com/users/dmsnell/following{/other_user}","gists_url":"https://api.github.com/users/dmsnell/gists{/gist_id}","starred_url":"https://api.github.com/users/dmsnell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmsnell/subscriptions","organizations_url":"https://api.github.com/users/dmsnell/orgs","repos_url":"https://api.github.com/users/dmsnell/repos","events_url":"https://api.github.com/users/dmsnell/events{/privacy}","received_events_url":"https://api.github.com/users/dmsnell/received_events","type":"User","site_admin":false},"body":"habit? I guess I tend to use timeouts because it's conceptually simpler for me to understand plus we get automattic overload protection against slow processes. In other words, if someone puts something in `EVERY_SECOND` but that function takes two seconds to run, with `setTimeout` we'll get fewer calls than we'd expect but each two calls should be separated by one second. With `setInterval` we start stacking up concurrent calls with no interval. I like the safety of knowing that if I don't touch it, things will stop.\r\n\r\nIf you prefer Intervals, it's not a big change, but I don't see any problem with timeouts.","created_at":"2015-12-09T21:46:11Z","updated_at":"2015-12-09T21:46:11Z","html_url":"https://github.com/Automattic/wp-calypso/pull/1083#discussion_r47156892","pull_request_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083","_links":{"self":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments/47156892"},"html":{"href":"https://github.com/Automattic/wp-calypso/pull/1083#discussion_r47156892"},"pull_request":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083"}}},"pull_request":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083","id":52203857,"html_url":"https://github.com/Automattic/wp-calypso/pull/1083","diff_url":"https://github.com/Automattic/wp-calypso/pull/1083.diff","patch_url":"https://github.com/Automattic/wp-calypso/pull/1083.patch","issue_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/1083","number":1083,"state":"open","locked":false,"title":"Adds a new action-only poller","user":{"login":"dmsnell","id":5431237,"avatar_url":"https://avatars.githubusercontent.com/u/5431237?v=3","gravatar_id":"","url":"https://api.github.com/users/dmsnell","html_url":"https://github.com/dmsnell","followers_url":"https://api.github.com/users/dmsnell/followers","following_url":"https://api.github.com/users/dmsnell/following{/other_user}","gists_url":"https://api.github.com/users/dmsnell/gists{/gist_id}","starred_url":"https://api.github.com/users/dmsnell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmsnell/subscriptions","organizations_url":"https://api.github.com/users/dmsnell/orgs","repos_url":"https://api.github.com/users/dmsnell/repos","events_url":"https://api.github.com/users/dmsnell/events{/privacy}","received_events_url":"https://api.github.com/users/dmsnell/received_events","type":"User","site_admin":false},"body":"This polling component can wrap another component in a polling mechanism\r\nthat runs a given function at a given interval and will optionally stop\r\npolling if the component enters a hidden visibility state to save on\r\nbandwidth.\r\n\r\nIf specified to pause when hidden, there is an optional parameter\r\ndescribing whether or not the action should fire immediately upon coming\r\nback into view. If not, it will fire after the given interval.\r\n\r\nThis component was inspired by the data-poller component but attempts to\r\nbe a more lightweight and readable component.","created_at":"2015-12-01T01:18:06Z","updated_at":"2015-12-09T21:46:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1b27d971aeac911f267d07f50396b860d9ec21be","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083/commits","review_comments_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083/comments","review_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/1083/comments","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/1357d2cdbfda368975903ebcf52dc89c527017a3","head":{"label":"Automattic:add/importer-poller","ref":"add/importer-poller","sha":"1357d2cdbfda368975903ebcf52dc89c527017a3","user":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"repo":{"id":45936895,"name":"wp-calypso","full_name":"Automattic/wp-calypso","owner":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Automattic/wp-calypso","description":"The new JavaScript- and API-powered WordPress.com","fork":false,"url":"https://api.github.com/repos/Automattic/wp-calypso","forks_url":"https://api.github.com/repos/Automattic/wp-calypso/forks","keys_url":"https://api.github.com/repos/Automattic/wp-calypso/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Automattic/wp-calypso/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Automattic/wp-calypso/teams","hooks_url":"https://api.github.com/repos/Automattic/wp-calypso/hooks","issue_events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/events{/number}","events_url":"https://api.github.com/repos/Automattic/wp-calypso/events","assignees_url":"https://api.github.com/repos/Automattic/wp-calypso/assignees{/user}","branches_url":"https://api.github.com/repos/Automattic/wp-calypso/branches{/branch}","tags_url":"https://api.github.com/repos/Automattic/wp-calypso/tags","blobs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Automattic/wp-calypso/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/refs{/sha}","trees_url":"https://api.github.com/repos/Automattic/wp-calypso/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/{sha}","languages_url":"https://api.github.com/repos/Automattic/wp-calypso/languages","stargazers_url":"https://api.github.com/repos/Automattic/wp-calypso/stargazers","contributors_url":"https://api.github.com/repos/Automattic/wp-calypso/contributors","subscribers_url":"https://api.github.com/repos/Automattic/wp-calypso/subscribers","subscription_url":"https://api.github.com/repos/Automattic/wp-calypso/subscription","commits_url":"https://api.github.com/repos/Automattic/wp-calypso/commits{/sha}","git_commits_url":"https://api.github.com/repos/Automattic/wp-calypso/git/commits{/sha}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/comments{/number}","issue_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments{/number}","contents_url":"https://api.github.com/repos/Automattic/wp-calypso/contents/{+path}","compare_url":"https://api.github.com/repos/Automattic/wp-calypso/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Automattic/wp-calypso/merges","archive_url":"https://api.github.com/repos/Automattic/wp-calypso/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Automattic/wp-calypso/downloads","issues_url":"https://api.github.com/repos/Automattic/wp-calypso/issues{/number}","pulls_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls{/number}","milestones_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones{/number}","notifications_url":"https://api.github.com/repos/Automattic/wp-calypso/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/labels{/name}","releases_url":"https://api.github.com/repos/Automattic/wp-calypso/releases{/id}","created_at":"2015-11-10T20:00:16Z","updated_at":"2015-12-09T19:18:39Z","pushed_at":"2015-12-09T21:45:00Z","git_url":"git://github.com/Automattic/wp-calypso.git","ssh_url":"git@github.com:Automattic/wp-calypso.git","clone_url":"https://github.com/Automattic/wp-calypso.git","svn_url":"https://github.com/Automattic/wp-calypso","homepage":"https://developer.wordpress.com/calypso/","size":12155,"stargazers_count":6019,"watchers_count":6019,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":648,"mirror_url":null,"open_issues_count":854,"forks":648,"open_issues":854,"watchers":6019,"default_branch":"master"}},"base":{"label":"Automattic:master","ref":"master","sha":"1e6f05acbd88d847227ebf87fd08a212767ac415","user":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"repo":{"id":45936895,"name":"wp-calypso","full_name":"Automattic/wp-calypso","owner":{"login":"Automattic","id":887802,"avatar_url":"https://avatars.githubusercontent.com/u/887802?v=3","gravatar_id":"","url":"https://api.github.com/users/Automattic","html_url":"https://github.com/Automattic","followers_url":"https://api.github.com/users/Automattic/followers","following_url":"https://api.github.com/users/Automattic/following{/other_user}","gists_url":"https://api.github.com/users/Automattic/gists{/gist_id}","starred_url":"https://api.github.com/users/Automattic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Automattic/subscriptions","organizations_url":"https://api.github.com/users/Automattic/orgs","repos_url":"https://api.github.com/users/Automattic/repos","events_url":"https://api.github.com/users/Automattic/events{/privacy}","received_events_url":"https://api.github.com/users/Automattic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Automattic/wp-calypso","description":"The new JavaScript- and API-powered WordPress.com","fork":false,"url":"https://api.github.com/repos/Automattic/wp-calypso","forks_url":"https://api.github.com/repos/Automattic/wp-calypso/forks","keys_url":"https://api.github.com/repos/Automattic/wp-calypso/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Automattic/wp-calypso/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Automattic/wp-calypso/teams","hooks_url":"https://api.github.com/repos/Automattic/wp-calypso/hooks","issue_events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/events{/number}","events_url":"https://api.github.com/repos/Automattic/wp-calypso/events","assignees_url":"https://api.github.com/repos/Automattic/wp-calypso/assignees{/user}","branches_url":"https://api.github.com/repos/Automattic/wp-calypso/branches{/branch}","tags_url":"https://api.github.com/repos/Automattic/wp-calypso/tags","blobs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Automattic/wp-calypso/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Automattic/wp-calypso/git/refs{/sha}","trees_url":"https://api.github.com/repos/Automattic/wp-calypso/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Automattic/wp-calypso/statuses/{sha}","languages_url":"https://api.github.com/repos/Automattic/wp-calypso/languages","stargazers_url":"https://api.github.com/repos/Automattic/wp-calypso/stargazers","contributors_url":"https://api.github.com/repos/Automattic/wp-calypso/contributors","subscribers_url":"https://api.github.com/repos/Automattic/wp-calypso/subscribers","subscription_url":"https://api.github.com/repos/Automattic/wp-calypso/subscription","commits_url":"https://api.github.com/repos/Automattic/wp-calypso/commits{/sha}","git_commits_url":"https://api.github.com/repos/Automattic/wp-calypso/git/commits{/sha}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/comments{/number}","issue_comment_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments{/number}","contents_url":"https://api.github.com/repos/Automattic/wp-calypso/contents/{+path}","compare_url":"https://api.github.com/repos/Automattic/wp-calypso/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Automattic/wp-calypso/merges","archive_url":"https://api.github.com/repos/Automattic/wp-calypso/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Automattic/wp-calypso/downloads","issues_url":"https://api.github.com/repos/Automattic/wp-calypso/issues{/number}","pulls_url":"https://api.github.com/repos/Automattic/wp-calypso/pulls{/number}","milestones_url":"https://api.github.com/repos/Automattic/wp-calypso/milestones{/number}","notifications_url":"https://api.github.com/repos/Automattic/wp-calypso/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/labels{/name}","releases_url":"https://api.github.com/repos/Automattic/wp-calypso/releases{/id}","created_at":"2015-11-10T20:00:16Z","updated_at":"2015-12-09T19:18:39Z","pushed_at":"2015-12-09T21:45:00Z","git_url":"git://github.com/Automattic/wp-calypso.git","ssh_url":"git@github.com:Automattic/wp-calypso.git","clone_url":"https://github.com/Automattic/wp-calypso.git","svn_url":"https://github.com/Automattic/wp-calypso","homepage":"https://developer.wordpress.com/calypso/","size":12155,"stargazers_count":6019,"watchers_count":6019,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":648,"mirror_url":null,"open_issues_count":854,"forks":648,"open_issues":854,"watchers":6019,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083"},"html":{"href":"https://github.com/Automattic/wp-calypso/pull/1083"},"issue":{"href":"https://api.github.com/repos/Automattic/wp-calypso/issues/1083"},"comments":{"href":"https://api.github.com/repos/Automattic/wp-calypso/issues/1083/comments"},"review_comments":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083/comments"},"review_comment":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Automattic/wp-calypso/pulls/1083/commits"},"statuses":{"href":"https://api.github.com/repos/Automattic/wp-calypso/statuses/1357d2cdbfda368975903ebcf52dc89c527017a3"}}}}