# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Utils # ThreadTracker allows tracking of singleton objects across threads class ThreadTracker def initialize logger = nil @logger = logger end # Note about Ruby -- thread#[] is fiber-local, # #thread_variables is not. def get key, default = nil log(key) Thread.current[key] || default end def set key, value Thread.current[key] = value end def delete key Thread.current[key] = nil end def lifespan obj set(:current_context, obj) response = yield(obj) delete(:current_context) response end def current get(:current_context) end def update_current_context context set(:current_context, context) end # logger may be nil so use this utility method instead def log key return unless @logger return unless @logger.debug? @logger.debug('Accessing object in Thread Tracker', name: key, p_id: Process.pid, thread_id: Thread.current.object_id) rescue StandardError false # NOOP end end end end