module ActiveSupport::ExecutionContext

def []=(key, value)

def []=(key, value)
  store[key.to_sym] = value
  @after_change_callbacks.each(&:call)
end

def after_change(&block)

def after_change(&block)
  @after_change_callbacks << block
end

def clear

def clear
  store.clear
end

def set(**options)

previous value once the block exits.
Updates the execution context. If a block is given, it resets the provided keys to their
def set(**options)
  options.symbolize_keys!
  keys = options.keys
  store = self.store
  previous_context = keys.zip(store.values_at(*keys)).to_h
  store.merge!(options)
  @after_change_callbacks.each(&:call)
  if block_given?
    begin
      yield
    ensure
      store.merge!(previous_context)
      @after_change_callbacks.each(&:call)
    end
  end
end

def store

def store
  IsolatedExecutionState[:active_support_execution_context] ||= {}
end

def to_h

def to_h
  store.dup
end