{"action":"created","issue":{"url":"https://api.github.com/repos/runelite/runelite/issues/1240","repository_url":"https://api.github.com/repos/runelite/runelite","labels_url":"https://api.github.com/repos/runelite/runelite/issues/1240/labels{/name}","comments_url":"https://api.github.com/repos/runelite/runelite/issues/1240/comments","events_url":"https://api.github.com/repos/runelite/runelite/issues/1240/events","html_url":"https://github.com/runelite/runelite/pull/1240","id":310449531,"node_id":"MDExOlB1bGxSZXF1ZXN0MTc4ODEzMDE5","number":1240,"title":"Replace timer-based usages of Instant.now() with System.nanoTime()","user":{"login":"SoyChai","id":37604308,"node_id":"MDQ6VXNlcjM3NjA0MzA4","avatar_url":"https://avatars2.githubusercontent.com/u/37604308?v=4","gravatar_id":"","url":"https://api.github.com/users/SoyChai","html_url":"https://github.com/SoyChai","followers_url":"https://api.github.com/users/SoyChai/followers","following_url":"https://api.github.com/users/SoyChai/following{/other_user}","gists_url":"https://api.github.com/users/SoyChai/gists{/gist_id}","starred_url":"https://api.github.com/users/SoyChai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SoyChai/subscriptions","organizations_url":"https://api.github.com/users/SoyChai/orgs","repos_url":"https://api.github.com/users/SoyChai/repos","events_url":"https://api.github.com/users/SoyChai/events{/privacy}","received_events_url":"https://api.github.com/users/SoyChai/received_events","type":"User","site_admin":false},"labels":[{"id":366780279,"node_id":"MDU6TGFiZWwzNjY3ODAyNzk=","url":"https://api.github.com/repos/runelite/runelite/labels/bug","name":"bug","color":"ee0701","default":true}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-04-02T10:18:50Z","updated_at":"2018-08-11T11:08:46Z","closed_at":"2018-08-11T11:08:46Z","author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/runelite/runelite/pulls/1240","html_url":"https://github.com/runelite/runelite/pull/1240","diff_url":"https://github.com/runelite/runelite/pull/1240.diff","patch_url":"https://github.com/runelite/runelite/pull/1240.patch"},"body":"This resolves #999. Don't be scared by the title, the code changes are actually very simple.\r\n\r\nSummary of the problem:\r\n> Several plugins currently make use of Instants to store past or future moments, and then later compare those Instants against `Instant.now()` for things like timers, idle warnings, etc. This is a risky design choice because it assumes the user will never change their system time, and as FrozenState pointed out, can cause timing misbehaviour and even exceptions.\r\n\r\n>Instead of referring to the system clock, we can use `System.nanoTime()` to return the elapsed system uptime in nanoseconds, which can be relied upon to not jump forwards or backwards unexpectedly. `System.currentTimeInMillis()` can't be used for this purpose since it returns epoch time, which suffers from the same problem.\r\n\r\nI've replaced all timer-based `Instant` fields with a `long` representing a moment in system nanoseconds. Any code which checked whether an `instant == null` now simply checks if a `nanoTime == 0`, and lengths of nanoseconds are generally abstracted into Duration objects."},"comment":{"url":"https://api.github.com/repos/runelite/runelite/issues/comments/412268358","html_url":"https://github.com/runelite/runelite/pull/1240#issuecomment-412268358","issue_url":"https://api.github.com/repos/runelite/runelite/issues/1240","id":412268358,"node_id":"MDEyOklzc3VlQ29tbWVudDQxMjI2ODM1OA==","user":{"login":"deathbeam","id":5115805,"node_id":"MDQ6VXNlcjUxMTU4MDU=","avatar_url":"https://avatars3.githubusercontent.com/u/5115805?v=4","gravatar_id":"","url":"https://api.github.com/users/deathbeam","html_url":"https://github.com/deathbeam","followers_url":"https://api.github.com/users/deathbeam/followers","following_url":"https://api.github.com/users/deathbeam/following{/other_user}","gists_url":"https://api.github.com/users/deathbeam/gists{/gist_id}","starred_url":"https://api.github.com/users/deathbeam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deathbeam/subscriptions","organizations_url":"https://api.github.com/users/deathbeam/orgs","repos_url":"https://api.github.com/users/deathbeam/repos","events_url":"https://api.github.com/users/deathbeam/events{/privacy}","received_events_url":"https://api.github.com/users/deathbeam/received_events","type":"User","site_admin":false},"created_at":"2018-08-11T11:08:46Z","updated_at":"2018-08-11T11:08:46Z","author_association":"MEMBER","body":"Closing as this is very old PR now and has a lot of merge conflicts, reopen if you want to re-implement it."}}
{"actor":{"display_login":"deathbeam"}}