Я работаю над большим количеством кода, который состоит из множества различных классов, и я хочу встроить средства сбора некоторой статистики во время ее работы. В идеале я хочу, чтобы внутренние классы могли запускать что-то вроде
record_stat(:api_requests, 1)
Весь процесс запускается из одной точки входа (движка), но в идеале я бы хотел избежать передачи этого экземпляра всем внутренним классам. Наиболее очевидные решения (но те, которых я бы хотел избежать):
- Передать экземпляр самого движка всем дочерним экземплярам. Двигатель имеет метод
record_stat
- Возвращает все характеристики каждого дочернего экземпляра и объединяет их в движке
Первоначально я искал второй вариант, потому что у меня уже есть класс возвращаемого значения для некоторых внутренних объектов, но я просто думаю, что было бы намного чище иметь просто метод, который обрабатывал бы это, не прибегая к разметке. все время.
В настоящее время у меня есть что-то похожее с ведением журнала, где я могу запустить ::Engine::Logger.debug('...')
, но я использую Thread.current
для вещей, и это никогда не кажется правильным, поэтому не уверен, что мне следует сделать это и для этого.
Существуют ли способы сделать метод record_stat
доступным только для этого процесса или глобальным для блока, может быть, чтобы все внутренние устройства могли получить к нему доступ и иметь его уникальным для этой работы двигателя?
Редактировать: Предоставление примера
Двигатель
class Engine
...
def sync
remote = fetch_remote_data
records = map_remote_to_records(remote)
save_records(records)
end
def fetch_remote_data
@types.map do |type|
DataFetcher.new(type).fetch
end
end
def map_remote_to_records(remote)
remote.map do |r|
RecordMapper.new.map(r)
end
end
def save_records(records)
records.each do |record|
RecordSaver.new(record).save!
end
end
end
DataFetcher
class DataFetcher
def fetch(query = nil)
provider.fetch(query)
end
end
Средний
class SomeRemoteServerProvider
def fetch(query)
make_api_request.map do |remote|
<convert to internal format>
end
end
end
RecordMapper
class RecordMapper
def map
local = find_or_build(@remote)
assign_attributes(local, @remote)
local
end
end
RecordSaver
class RecordSaver
def save!
@records.each do |record|
save_record!
save_associations!
...
end
end
end
хорошо, так что это довольно упрощенный упрощенный пример, но в этом сценарии я хочу, чтобы классы, такие как SomeRemoteServerProvider
, сообщали о количестве вызовов API, которые он совершил, или RecordMapper
, чтобы сообщать о том, сколько локальных записей он действительно нашел, и сколько он должен был создать. Нечто подобное