Skip to content

Commit

Permalink
copy context_provider and context from ddtrace-rb to start experiment…
Browse files Browse the repository at this point in the history
…ing with it
  • Loading branch information
anmarchenko committed Nov 3, 2023
1 parent 9b704af commit 3525a0d
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
25 changes: 25 additions & 0 deletions lib/datadog/ci/context.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require "datadog/core/utils/forking"

module Datadog
module CI
class Context
include Core::Utils::Forking

attr_reader \
:active_test

def initialize(test: nil)
@active_test = test
end

# Creates a copy of the context, when forked.
def fork_clone
# forked_session = @active_session && @active_session.fork_clone
# do not preserves the active test across forks
self.class.new
end
end
end
end
62 changes: 62 additions & 0 deletions lib/datadog/ci/context_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require "datadog/core/utils/sequence"

require_relative "context"

module Datadog
module CI
# Provider is a default context provider that retrieves
# all contexts from the current fiber-local storage. It is suitable for
# synchronous programming.
#
# @see https://ruby-doc.org/core-3.1.2/Thread.html#method-i-5B-5D Thread attributes are fiber-local
class ContextProvider
# Initializes the default context provider with a fiber-bound context.
def initialize
@context = FiberLocalContext.new
end

# Sets the current context.
def context=(ctx)
@context.local = ctx
end

# Return the local context.
def context(key = nil)
current_context = key.nil? ? @context.local : @context.local(key)

current_context.after_fork! do
current_context = self.context = current_context.fork_clone
end

current_context
end
end

class FiberLocalContext
def initialize
@key = "datadog_ci_context_#{FiberLocalContext.next_instance_id}".to_sym

self.local = Context.new
end

# Override the fiber-local context with a new context.
def local=(ctx)
Thread.current[@key] = ctx
end

# Return the fiber-local context.
def local(storage = Thread.current)
storage[@key] ||= Context.new
end

UNIQUE_INSTANCE_MUTEX = Mutex.new
UNIQUE_INSTANCE_GENERATOR = Datadog::Core::Utils::Sequence.new

private_constant :UNIQUE_INSTANCE_MUTEX, :UNIQUE_INSTANCE_GENERATOR

def self.next_instance_id
UNIQUE_INSTANCE_MUTEX.synchronize { UNIQUE_INSTANCE_GENERATOR.next }
end
end
end
end
14 changes: 14 additions & 0 deletions sig/datadog/ci/context.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module Datadog
module CI
class Context
@active_test: untyped

include Core::Utils::Forking

attr_reader active_test: untyped

def initialize: (?test: untyped?) -> void
def fork_clone: () -> untyped
end
end
end
24 changes: 24 additions & 0 deletions sig/datadog/ci/context_provider.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Datadog
module CI
class ContextProvider
@context: untyped
def initialize: () -> void
def context=: (untyped ctx) -> untyped
def context: (?untyped? key) -> untyped
end

class FiberLocalContext
@key: untyped

def initialize: () -> void
def local=: (untyped ctx) -> untyped
def local: (?untyped storage) -> untyped

UNIQUE_INSTANCE_MUTEX: untyped

UNIQUE_INSTANCE_GENERATOR: untyped

def self.next_instance_id: () -> untyped
end
end
end

0 comments on commit 3525a0d

Please sign in to comment.