Loading lib/labkit/covered_experience/experience.rb +8 −15 Original line number Diff line number Diff line Loading @@ -24,8 +24,8 @@ module Labkit private :initialize class << self # Factory method to create a new Covered Experience # It will also rehydrate the state from the current context # Factory method to create a new Covered Experience. # It will rehydrate the state from the current context # if it exists. # # @param definition [Labkit::CoveredExperience::Definition] Loading @@ -35,6 +35,10 @@ module Labkit instance.instance_eval { load_from_context } instance end def aggregation_context Thread.current[:covered_experiences] ||= {} end end # Start the Covered Experience. Loading Loading @@ -234,11 +238,6 @@ module Labkit log_data end def aggregation_context aggregation_key = Labkit::Context::COVERED_EXPERIENCE_AGG_KEY Labkit::Context.current&.get_attribute(aggregation_key) || {} end def to_proc(**extra) lambda do checkpoint(checkpoint_category: "push_to_context", **extra) Loading @@ -247,24 +246,18 @@ module Labkit end def push_to_context(**extra) covered_experiences = aggregation_context # Pushing the experience to the context as a Proc to be lazy evaluated. # This allows the checkpoint event to be triggered only when context # is being serialized sidekiq jobs, and eventually HTTP headers. covered_experiences[@definition.covered_experience] = to_proc(**extra) Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => covered_experiences) self.class.aggregation_context[@definition.covered_experience] = to_proc(**extra) end def load_from_context covered_experiences = aggregation_context experience_data = covered_experiences[@definition.covered_experience] experience_data = self.class.aggregation_context[@definition.covered_experience] processed_data = case experience_data when Proc then experience_data.call when String then experience_data else experience_data || {} end Loading spec/labkit/covered_experience/experience_spec.rb +14 −21 Original line number Diff line number Diff line Loading @@ -85,19 +85,18 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do end it 'pushes covered experience data to context' do expect(Labkit::Context.current.get_attribute("covered_experiences")).to be_nil expect { experience.start }.not_to checkpoint_covered_experience(:testing_sample) covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) # proc should trigger a checkpoint event when called # Proc should trigger a checkpoint event when called expect(Labkit::CoveredExperience.configuration.logger).to receive(:info) .with(hash_including(checkpoint: 'intermediate', checkpoint_category: 'push_to_context')) .ordered .and_call_original expect do expect(covered_experiences["testing_sample"].call).to match("start_time" => a_kind_of(String)) end.to checkpoint_covered_experience(:testing_sample) Loading Loading @@ -160,16 +159,17 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do it 'pushes covered experience data to context' do start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) # proc should trigger a checkpoint event when called # Proc should trigger a checkpoint event when called expect(Labkit::CoveredExperience.configuration.logger).to receive(:info) .with(hash_including(checkpoint: 'intermediate', checkpoint_category: 'push_to_context')) .ordered .and_call_original expect do expect(covered_experiences["testing_sample"].call).to eq("start_time" => experience.start_time.iso8601(3)) end.to checkpoint_covered_experience(:testing_sample) Loading @@ -180,11 +180,11 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do existing_experiences = { "other_experience" => { "start_time" => (Time.now.utc - 10).iso8601(3) } } Labkit::Context.push("covered_experiences" => existing_experiences) Thread.current[:covered_experiences] = existing_experiences start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("other_experience", "testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) Loading @@ -193,12 +193,11 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do end it 'handles empty context gracefully' do # Clear any existing context Labkit::Context.push("covered_experiences" => nil) Thread.current[:covered_experiences] = nil start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) Loading Loading @@ -643,10 +642,9 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do before do # Set up existing covered experience in context covered_experiences = { Thread.current[:covered_experiences] = { "testing_sample" => { "start_time" => start_time.iso8601(3) } } Labkit::Context.push("covered_experiences" => covered_experiences) end subject(:loaded_experience) { described_class.load(definition) } Loading Loading @@ -682,10 +680,7 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do before do # Set up existing covered experience as a Proc in context covered_experiences = { "testing_sample" => proc_data } Labkit::Context.push("covered_experiences" => covered_experiences) Thread.current[:covered_experiences] = { "testing_sample" => proc_data } end subject(:loaded_experience) { described_class.load(definition) } Loading Loading @@ -715,14 +710,12 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do context 'when no experience data exists in context' do before do # Ensure no covered experiences in context Labkit::Context.push("covered_experiences" => nil) Thread.current[:covered_experiences] = nil end subject(:loaded_experience) { described_class.load(definition) } it 'returns an Experience instance' do expect(loaded_experience).to be_a(described_class) end it { is_expected.to be_a(described_class) } it 'does not set start_time' do expect(loaded_experience.start_time).to be_nil Loading spec/labkit/covered_experience_spec.rb +2 −2 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ RSpec.describe Labkit::CoveredExperience, :with_metrics_config do let(:experience_data) { { "start_time" => Time.now.utc.iso8601(3) } } before do Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => { 'testing_sample' => experience_data }) Thread.current[:covered_experiences] = { 'testing_sample' => experience_data } end context 'when block is given' do Loading Loading @@ -331,7 +331,7 @@ RSpec.describe Labkit::CoveredExperience, :with_metrics_config do let(:experience_proc) { -> { { "start_time" => Time.now.utc.iso8601(3) } } } before do Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => { 'testing_sample' => experience_proc }) Thread.current[:covered_experiences] = { 'testing_sample' => experience_proc } end it 'calls the proc to get experience data' do Loading spec/spec_helper.rb +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ RSpec.configure do |config| # Ignore logs by default in tests config.logger = Labkit::Logging::JsonLogger.new("/dev/null") end Thread.current[:covered_experiences] = nil example.run Loading Loading
lib/labkit/covered_experience/experience.rb +8 −15 Original line number Diff line number Diff line Loading @@ -24,8 +24,8 @@ module Labkit private :initialize class << self # Factory method to create a new Covered Experience # It will also rehydrate the state from the current context # Factory method to create a new Covered Experience. # It will rehydrate the state from the current context # if it exists. # # @param definition [Labkit::CoveredExperience::Definition] Loading @@ -35,6 +35,10 @@ module Labkit instance.instance_eval { load_from_context } instance end def aggregation_context Thread.current[:covered_experiences] ||= {} end end # Start the Covered Experience. Loading Loading @@ -234,11 +238,6 @@ module Labkit log_data end def aggregation_context aggregation_key = Labkit::Context::COVERED_EXPERIENCE_AGG_KEY Labkit::Context.current&.get_attribute(aggregation_key) || {} end def to_proc(**extra) lambda do checkpoint(checkpoint_category: "push_to_context", **extra) Loading @@ -247,24 +246,18 @@ module Labkit end def push_to_context(**extra) covered_experiences = aggregation_context # Pushing the experience to the context as a Proc to be lazy evaluated. # This allows the checkpoint event to be triggered only when context # is being serialized sidekiq jobs, and eventually HTTP headers. covered_experiences[@definition.covered_experience] = to_proc(**extra) Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => covered_experiences) self.class.aggregation_context[@definition.covered_experience] = to_proc(**extra) end def load_from_context covered_experiences = aggregation_context experience_data = covered_experiences[@definition.covered_experience] experience_data = self.class.aggregation_context[@definition.covered_experience] processed_data = case experience_data when Proc then experience_data.call when String then experience_data else experience_data || {} end Loading
spec/labkit/covered_experience/experience_spec.rb +14 −21 Original line number Diff line number Diff line Loading @@ -85,19 +85,18 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do end it 'pushes covered experience data to context' do expect(Labkit::Context.current.get_attribute("covered_experiences")).to be_nil expect { experience.start }.not_to checkpoint_covered_experience(:testing_sample) covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) # proc should trigger a checkpoint event when called # Proc should trigger a checkpoint event when called expect(Labkit::CoveredExperience.configuration.logger).to receive(:info) .with(hash_including(checkpoint: 'intermediate', checkpoint_category: 'push_to_context')) .ordered .and_call_original expect do expect(covered_experiences["testing_sample"].call).to match("start_time" => a_kind_of(String)) end.to checkpoint_covered_experience(:testing_sample) Loading Loading @@ -160,16 +159,17 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do it 'pushes covered experience data to context' do start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) # proc should trigger a checkpoint event when called # Proc should trigger a checkpoint event when called expect(Labkit::CoveredExperience.configuration.logger).to receive(:info) .with(hash_including(checkpoint: 'intermediate', checkpoint_category: 'push_to_context')) .ordered .and_call_original expect do expect(covered_experiences["testing_sample"].call).to eq("start_time" => experience.start_time.iso8601(3)) end.to checkpoint_covered_experience(:testing_sample) Loading @@ -180,11 +180,11 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do existing_experiences = { "other_experience" => { "start_time" => (Time.now.utc - 10).iso8601(3) } } Labkit::Context.push("covered_experiences" => existing_experiences) Thread.current[:covered_experiences] = existing_experiences start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("other_experience", "testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) Loading @@ -193,12 +193,11 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do end it 'handles empty context gracefully' do # Clear any existing context Labkit::Context.push("covered_experiences" => nil) Thread.current[:covered_experiences] = nil start covered_experiences = Labkit::Context.current.get_attribute("covered_experiences") covered_experiences = Thread.current[:covered_experiences] expect(covered_experiences).to include("testing_sample") expect(covered_experiences["testing_sample"]).to be_a(Proc) Loading Loading @@ -643,10 +642,9 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do before do # Set up existing covered experience in context covered_experiences = { Thread.current[:covered_experiences] = { "testing_sample" => { "start_time" => start_time.iso8601(3) } } Labkit::Context.push("covered_experiences" => covered_experiences) end subject(:loaded_experience) { described_class.load(definition) } Loading Loading @@ -682,10 +680,7 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do before do # Set up existing covered experience as a Proc in context covered_experiences = { "testing_sample" => proc_data } Labkit::Context.push("covered_experiences" => covered_experiences) Thread.current[:covered_experiences] = { "testing_sample" => proc_data } end subject(:loaded_experience) { described_class.load(definition) } Loading Loading @@ -715,14 +710,12 @@ RSpec.describe Labkit::CoveredExperience::Experience, :with_metrics_config do context 'when no experience data exists in context' do before do # Ensure no covered experiences in context Labkit::Context.push("covered_experiences" => nil) Thread.current[:covered_experiences] = nil end subject(:loaded_experience) { described_class.load(definition) } it 'returns an Experience instance' do expect(loaded_experience).to be_a(described_class) end it { is_expected.to be_a(described_class) } it 'does not set start_time' do expect(loaded_experience.start_time).to be_nil Loading
spec/labkit/covered_experience_spec.rb +2 −2 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ RSpec.describe Labkit::CoveredExperience, :with_metrics_config do let(:experience_data) { { "start_time" => Time.now.utc.iso8601(3) } } before do Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => { 'testing_sample' => experience_data }) Thread.current[:covered_experiences] = { 'testing_sample' => experience_data } end context 'when block is given' do Loading Loading @@ -331,7 +331,7 @@ RSpec.describe Labkit::CoveredExperience, :with_metrics_config do let(:experience_proc) { -> { { "start_time" => Time.now.utc.iso8601(3) } } } before do Labkit::Context.push(Labkit::Context::COVERED_EXPERIENCE_AGG_KEY => { 'testing_sample' => experience_proc }) Thread.current[:covered_experiences] = { 'testing_sample' => experience_proc } end it 'calls the proc to get experience data' do Loading
spec/spec_helper.rb +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ RSpec.configure do |config| # Ignore logs by default in tests config.logger = Labkit::Logging::JsonLogger.new("/dev/null") end Thread.current[:covered_experiences] = nil example.run Loading