Skip to content

Commit

Permalink
Kotlin: Dispatch metric recording for event, object and timing distri…
Browse files Browse the repository at this point in the history
…bution on the task queue

This allows us to delay executing those until Glean gets initialized and
thus the core library is loaded.
This is important for Fenix startup where we use `libxul` from Gecko,
but want it to be loaded by GeckoView code before Glean accesses it.

The three metric types for which this is currently implemented are the
three metric types that are currently recorded early during Fenix' startup (by Nimbus).

For the timing distribution this task dispatching is ONLY used for the
`accumulate` methods.
We can't do that for start/stop, because the timings are handled within glean-core.
  • Loading branch information
badboy committed Aug 23, 2024
1 parent cc73b7a commit e2f350c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package mozilla.telemetry.glean.private
import androidx.annotation.VisibleForTesting
import mozilla.telemetry.glean.internal.EventMetric
import mozilla.telemetry.glean.testing.ErrorType
import mozilla.telemetry.glean.Dispatchers

/**
* A class that can be converted into key-value pairs of event extras.
Expand Down Expand Up @@ -42,14 +43,11 @@ class NoExtras : EventExtras {
* The Events API only exposes the [record] method, which takes care of validating the input
* data and making sure that limits are enforced.
*/
class EventMetricType<ExtraObject> internal constructor(
private var inner: EventMetric,
class EventMetricType<ExtraObject> constructor(
private var meta: CommonMetricData,
private var allowedExtraKeys: List<String>
) where ExtraObject : EventExtras {
/**
* The public constructor used by automatically generated metrics.
*/
constructor(meta: CommonMetricData, allowedExtraKeys: List<String>) :
this(inner = EventMetric(meta, allowedExtraKeys))
val inner: EventMetric by lazy { EventMetric(meta, allowedExtraKeys) }

/**
* Record an event by using the information provided by the instance of this class.
Expand All @@ -63,7 +61,9 @@ class EventMetricType<ExtraObject> internal constructor(
* If no `extra` data is passed the above function will be invoked correctly.
*/
fun record(extra: ExtraObject? = null) {
inner.record(extra?.toExtraRecord() ?: emptyMap())
Dispatchers.Queue.launch {
inner.record(extra?.toExtraRecord() ?: emptyMap())
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import mozilla.telemetry.glean.internal.ObjectMetric
import mozilla.telemetry.glean.Dispatchers
import mozilla.telemetry.glean.testing.ErrorType

/**
Expand All @@ -28,22 +29,20 @@ interface ObjectSerialize {
* The object API only exposes the [set] method.
* Only the associated object structure can be recorded.
*/
class ObjectMetricType<K> internal constructor(
private var inner: ObjectMetric,
class ObjectMetricType<K> constructor(
private var meta: CommonMetricData
) where K : ObjectSerialize {
/**
* The public constructor used by automatically generated metrics.
*/
constructor(meta: CommonMetricData) :
this(inner = ObjectMetric(meta))
val inner: ObjectMetric by lazy { ObjectMetric(meta) }

/**
* Sets to the associated structure.
*
* @param obj The object to set.
*/
fun set(obj: K) {
inner.setString(obj.intoSerializedObject())
Dispatchers.Queue.launch {
inner.setString(obj.intoSerializedObject())
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting
import mozilla.telemetry.glean.GleanTimerId
import mozilla.telemetry.glean.internal.TimingDistributionMetric
import mozilla.telemetry.glean.testing.ErrorType
import mozilla.telemetry.glean.Dispatchers

/**
* This implements the developer facing API for recording timing distribution metrics.
Expand All @@ -16,7 +17,7 @@ import mozilla.telemetry.glean.testing.ErrorType
* allowing developers to record values that were previously registered in the metrics.yaml file.
*/
class TimingDistributionMetricType(meta: CommonMetricData, timeUnit: TimeUnit) : HistogramBase {
val inner = TimingDistributionMetric(meta, timeUnit)
val inner: TimingDistributionMetric by lazy { TimingDistributionMetric(meta, timeUnit) }

/**
* Delegate common methods to the underlying type directly.
Expand All @@ -30,8 +31,17 @@ class TimingDistributionMetricType(meta: CommonMetricData, timeUnit: TimeUnit) :
* Additional functionality
*/

fun accumulateSingleSample(sample: Long) = inner.accumulateSingleSample(sample)
override fun accumulateSamples(samples: List<Long>) = inner.accumulateSamples(samples)
fun accumulateSingleSample(sample: Long) {
Dispatchers.Queue.launch {
inner.accumulateSingleSample(sample)
}
}

override fun accumulateSamples(samples: List<Long>) {
Dispatchers.Queue.launch {
inner.accumulateSamples(samples)
}
}

/**
* Convenience method to simplify measuring a function or block of code.
Expand Down

0 comments on commit e2f350c

Please sign in to comment.