Implement Components.utils.now() to match Performance.now() for non-window chrome code

RESOLVED FIXED in mozilla35

Status

()

defect
RESOLVED FIXED
5 years ago
3 months ago

People

(Reporter: Irving, Assigned: bzbarsky)

Tracking

({dev-doc-needed})

unspecified
mozilla35
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

+++ This bug was initially created as a clone of Bug #908390 +++

Telemetry, and probably other clients, need better timing that we get from Date.now(). Telemetry probes don't always run in a window context, so we would like an equivalent to window.performance.now() that works for non-window chrome.
Do you care what the timebase is?  In particular, do you want a shared timebase across all chrome, or is a pretty much random timebase per-global (e.g. stored in the per-global performance object itself) sufficient?
Most of the current timestamp collection in Telemetry assumes a shared timebase (interval since application launch). Switching those uses to a per-global time base would cause quite a few headaches.

There are some uses where we're explicitly collecting time intervals; those would be fine with per-global (or even per-interval-collector) bases.
Alright.

Note that window.performance.now() has a per-window timebase.  Is that going to be a problem, given the "don't always" (as opposed to "don't") in comment 0?
Hmm. Thinking about that more, the best approach may be to expose StartupTimeline (probably with a few tweaks) to JS for recording events relative to application startup with a consistent time base, and use performance.now() (or perhaps a less error-prone "timer = performance.startTimer(); ... timer.now()") for recording intervals.

The main problem *I'm* trying to fix is that we see enough negative time intervals in our current telemetry data that it's sometimes obscuring the signal. Higher precision would be nice, but my first goal is to avoid having our data messed up by bogus time comparisons, whether from system clock skew or inconsistent time bases.
Ah, nice.

We can certainly add a chrome-only (e.g. Components.now() or Components.performance.now()) API that returns the number of milleseconds from StartupTimeline::Get(PROCESS_CREATION), say.  Bobby, any better places to hang this off of?

How fast do you want the timer calls to be?  Components.now() would probably take about 1us per call.  We could make performance.now() about 50ns per call if you already have the "performance" object and aren't actually getting it off anywhere as part of the call.  Otherwise you're probably back to 1us.
Component: DOM: Workers → DOM
Bobby, how do you feel about Components.now()?
Flags: needinfo?(bobbyholley)
Telemetry use cases don't need to be super fast; we're mostly interested in milliseconds. 1μs would be fine, though if it's not much work, less overhead is always nice.
(In reply to Boris Zbarsky [:bz] from comment #6)
> Bobby, how do you feel about Components.now()?

Directly on Components is a no-go, but Components.utils.now would be fine as long as nobody minds the XPConnect call overhead.
Flags: needinfo?(bobbyholley)
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Comment on attachment 8483863 [details] [diff] [review]
Add a Components.utils.now() that provides access in system JS to a monotonic timer, returning a fractional number milliseconds since process creation

Review of attachment 8483863 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/xpconnect/src/XPCComponents.cpp
@@ +3553,5 @@
>      return NS_OK;
>  }
>  
> +NS_IMETHODIMP
> +nsXPCComponents_Utils::Now(double* aRetval)

* goes on the right.
Attachment #8483863 - Flags: review?(bobbyholley) → review+
Summary: Implement Performance.now() for non-window chrome code → Implement Components.utils.now() to match Performance.now() for non-window chrome code
https://hg.mozilla.org/mozilla-central/rev/6ed2082c2e48
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
I hadn't noticed this before so I'll just leave a comment FYI. When I addressed bug 793735 I modified the getStartupInfo() call to return an adjusted value of the Date that would be relative to Date.now(). That was made to prevent cases where Date.now() would appear before the data gathered via getStartupInfo(). This also means that doing something like this in chrome code:

function uptime() {
  return Date.now() - Services.startup.getStartupInfo().process;
}

will yield a monotonic timer that always returns the number of ms elapsed since startup. The change here provides equivalent functionality in a cleaner way than what I did there:

http://hg.mozilla.org/mozilla-central/file/db7212847c14/toolkit/components/startup/nsAppStartup.cpp#l124
http://hg.mozilla.org/mozilla-central/file/db7212847c14/toolkit/components/startup/nsAppStartup.cpp#l778
Depends on: 1064424
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.