Async::UtilizationSourceAsyncUtilizationMetric

class Metric

A cached metric reference that avoids hash lookups on the fast path.

This class caches all the details needed to write directly to shared memory, including the buffer, offset, and type. When the observer changes, the cache is invalidated and rebuilt on the next access.

Definitions

def self.for(field, observer)

Create a new metric for the given field and observer.

Signature

parameter field Symbol

The field name for this metric.

parameter observer Observer | Nil

The observer to associate with this metric.

returns Metric

A new metric instance.

Implementation

def self.for(field, observer)
	self.new(field).tap do |metric|
		metric.observer = observer
	end
end

def initialize(name)

Initialize a new metric.

Signature

parameter name Symbol

The field name for this metric.

Implementation

def initialize(name)
	@name = name.to_sym
	@value = 0
	
	@observer = nil
	@cached_field = nil
	@cached_buffer = nil
	@guard = Mutex.new
end

attr :name

Signature

attribute Symbol

The field name for this metric.

attr :value

Signature

attribute Numeric

The current value of this metric.

attr :guard

Signature

attribute Mutex

The mutex for thread safety.

def observer=(observer)

Set the observer and rebuild cache.

This is called when the registry assigns a new observer (or removes it). The cache is invalidated and then immediately recomputed so that the fast write path doesn't need to re-check the observer on the first write.

Signature

parameter observer Observer | Nil

The new observer (or nil).

Implementation

def observer=(observer)
	@guard.synchronize do
		@observer = observer
		
		if @observer
			if field = @observer.schema[@name]
				if buffer = @observer.buffer
					@cached_field = field
					@cached_buffer = buffer
					
					return write_direct(@value)
				end
			end
		end
		
		@cached_field = nil
		@cached_buffer = nil
	end
end

def increment

Increment the metric value.

Signature

returns Integer

The new value of the field.

Implementation

def increment
	@guard.synchronize do
		@value += 1
		write_direct(@value)
	end
	
	@value
end

def track(&block)

Track an operation: increment before the block, decrement after it completes.

Returns the block's return value. Use for active/count metrics that should reflect the number of operations currently in progress.

Signature

returns Object

The block's return value.

Implementation

def track(&block)
	raise ArgumentError, "block required" unless block_given?
	
	increment
	begin
		yield
	ensure
		decrement
	end
end

def decrement

Decrement the metric value.

Uses the fast path (direct buffer write) when cache is valid and observer is available.

Signature

returns Integer

The new value of the field.

Implementation

def decrement
	@guard.synchronize do
		@value -= 1
		write_direct(@value)
	end
	
	@value
end

def set(value)

Set the metric value.

Uses the fast path (direct buffer write) when cache is valid and observer is available.

Signature

parameter value Numeric

The value to set.

Implementation

def set(value)
	@guard.synchronize do
		@value = value
		write_direct(@value)
	end
end

def write_direct(value)

Write directly to the cached buffer if available.

This is the fast path that avoids hash lookups. Always ensures cache is valid first. If there's no observer or buffer, silently does nothing.

Signature

parameter value Numeric

The value to write.

returns Boolean

Whether the write succeeded.

Implementation

def write_direct(value)
	if @cached_buffer
		@cached_buffer.set_value(@cached_field.type, @cached_field.offset, value)
	end
	
	return true
rescue => error
	Console.warn(self, "Failed to write metric value!", metric: {name: @name, value: value}, exception: error)
	
	return false
end