Class UsageMeter
Internal Use Only.
The usage meter of a cloud-licensed process: the machining steps counted since the last flush – each a step the
step pipeline took, granted by the licence and queued, not one refused before or after its grant – which the
cloud lease client books onto the chain's stepsTotal (the account's step ledger, the data the service
needs), and, when the account's analytics switch is on, the usage reports (UsageReportDraft:
steps, play, workpiece size, resolutions and feature counts per period) the client queues and sends with
its syncs. Process-global and static like LicenseCaps; no file I/O – the files are the
client's.
Enabled is false by default and every producer entry point (StepGranted(), PlayReset(), NotePlay(UsagePlaySnapshot), Count(string, TimeSpan?)) reads it first and returns: a Sentinel-licensed process pays one volatile read per step and nothing else. The cloud lease client enables it at its start and disables it at its shutdown, after the last take. CollectReports is the analytics switch: off, the steps are still counted (the ledger) and nothing else is -- no report opens, no count, no snapshot.
A report opens at the first event after none is open and closes at the runner's reset (PlayReset(), when the play saw a step or an NC run), at the first event more than 60 minutes after it opened (the server refuses a longer period; the next report carries the play's ordinal and snapshot on), and at the shutdown's take. Its period runs from the event that opened it to its last event. The play ordinal (PlaySeq) is the closed plays that saw a step or an NC run, plus one, given to the open report at its first step or NC run; two resets without a play in between keep it.
Threads: StepGranted() runs on the machining thread of every session
(MachiningParallelProc.RunStep, once per step the pipeline took), NotePlay(UsagePlaySnapshot) there once per play,
PlayReset() on the runner's reset, Count(string, TimeSpan?) on whichever thread finishes a feature --
a session's thread, the webservice's request thread; TakePending(bool),
ReopenOnFailure(UsagePending) and ClearCollected() on the cloud lease client's threads (the
holder's loop, a secondary's poll, the shutdown) under the client's gate; Snapshot() on a
controller's thread. The step count is an interlocked counter outside any lock; everything about the
reports is under one meter lock. The meter lock is a leaf: it holds no file I/O, reads no clock (the time
is taken before it), calls nothing outside the meter and raises no event, so it never waits on another
lock, and a call under any lock of the client -- the file lock included -- cannot deadlock. The lock order
with the client is stickGate -> gate -> the meter lock -> usage.lock -> the client's
consent lock (a leaf of its own: file I/O on consent.json alone, waiting on nothing): a
flush takes the file lock after TakePending(bool) returned.
Every time is UTC at whole seconds from UtcNow, the seam the facts move.
public static class UsageMeter
- Inheritance
-
UsageMeter
- Inherited Members
Properties
AppSessionIdB64u
Internal Use Only. The app session id of this process: 16 random bytes, base64url without padding, drawn at the first enable (or at the first read, if that comes first) and shared by every report of the process until ResetForTest().
public static string AppSessionIdB64u { get; }
Property Value
CollectReports
Internal Use Only. The account's analytics switch as the client knows it: true by default; false = no report opens, no count, no snapshot, while the steps are still counted for the ledger. The client sets it at its start and when the user changes the switch, and drops what was collected with ClearCollected().
public static bool CollectReports { get; set; }
Property Value
Enabled
Internal Use Only. Whether the meter counts: false by default (a Sentinel-licensed process; every producer entry point returns at once), true from the cloud lease client's start to its shutdown, which takes the last pending first. Enabling draws AppSessionIdB64u when none is drawn yet.
public static bool Enabled { get; set; }
Property Value
UtcNow
Internal Use Only. The clock of the periods: UtcNow by default; the facts put a clock of their own here (null puts the default back). Its answer is taken as UTC (a local time is converted, an unspecified one taken as UTC) and cut to whole seconds.
public static Func<DateTime> UtcNow { get; set; }
Property Value
Methods
ClearCollected()
Internal Use Only. Drops what analytics collected and did not hand out yet, when the user turns the switch off: the closed reports not yet taken, and the open report's counts, workpiece box and resolutions; the open report stays open with its steps and play ordinal, and the pending steps stand (the ledger is not analytics). The client drops its queue file beside it.
public static void ClearCollected()
Count(string, TimeSpan?)
Internal Use Only.
One use of a feature: the open report – cut at 60 minutes, opened when none – counts the id once more
and adds the seconds of duration, rounded up, when one is given; an NC run
(NcRun) also makes the report a played one (its ordinal given, the next
reset closes it). An id outside All is ignored and touches no report (a Debug
assertion: the vocabulary is fixed with the server). Nothing when CollectReports is off.
public static void Count(string id, TimeSpan? duration = null)
Parameters
idstringA UsageFeature id.
durationTimeSpan?How long the use took; null when the caller measures nothing.
NotePlay(UsagePlaySnapshot)
Internal Use Only. What the runner notes once per play, after the play's first StepGranted(): the open report takes the workpiece box and the resolutions when it holds none yet (a report that saw two plays keeps the first one's), and counts each flag id once, as Count(string, TimeSpan?) does. Nothing when CollectReports is off.
public static void NotePlay(UsagePlaySnapshot snapshot)
Parameters
snapshotUsagePlaySnapshotThe play's box, resolutions and switch ids; null does nothing.
PlayReset()
Internal Use Only.
The runner's reset (MachiningActRunner.ResetStateAndClStrip, which may run twice per reset):
when the play saw a step or an NC run since the last reset, the open report closes with
PlayClosed and the closed plays are one more; otherwise nothing moves –
the open report, if any, stays open and the next play keeps the ordinal.
public static void PlayReset()
ReopenOnFailure(UsagePending)
Internal Use Only. Gives a take back after the flush failed (the file lock not taken in time): the steps are added back to the pending counter – never counted twice, the take zeroed it – and the reports go back in front of the closed ones, so the oldest still leaves first.
public static void ReopenOnFailure(UsagePending pending)
Parameters
pendingUsagePendingWhat TakePending(bool) returned; null does nothing.
ResetForTest()
Internal Use Only. Clears everything for the next fact: the pending steps, the open and the closed reports, the play ordinal, the app session id (the next enable or read draws a new one), and puts CollectReports and UtcNow back to their defaults. Enabled is left as it is: the fact that set it clears it.
public static void ResetForTest()
Snapshot()
Internal Use Only. A copy of the meter's state for the product's usage page: the pending steps, a copy of the open report, the play ordinal in force and the closed reports not yet taken. Nothing in it is shared with the meter.
public static UsageMeterSnapshot Snapshot()
Returns
- UsageMeterSnapshot
The snapshot.
StepGranted()
Internal Use Only. One machining step counted: the runner calls it once per step the step pipeline took – granted by ConsumeStep(int) and queued; not for a step refused before or after its grant, nor for one whose submit was not queued, whatever the licence's cap and the lease's grant counted for it. The pending steps are one more; when CollectReports, the open report – cut at 60 minutes, opened when none – takes the step, its play ordinal given when it has none yet, and its period end moves to now.
public static void StepGranted()
TakePending(bool)
Internal Use Only.
Moves the pending out for a flush: the steps counted since the last take (the counter is zeroed in one
interlocked exchange) and the closed reports, oldest first (the list is emptied). With
closeOpen – the shutdown – the open report closes first when it holds anything (a
step, a count, a snapshot or the play), as a closed play when the play saw a step or an NC run; an
empty one is dropped. Takes the meter lock only; no file I/O inside.
public static UsagePending TakePending(bool closeOpen)
Parameters
closeOpenboolTrue to close the open report too (the last flush of the process).
Returns
- UsagePending
The steps and the reports moved out; never null, the list never null.