Class: Takagi::Router::MetadataExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/router/metadata_extractor.rb,
sig/takagi/router/metadata_extractor.rbs

Overview

Handles metadata extraction from route handlers at boot time.

Extracted from Router to follow Single Responsibility Principle. Executes route handlers in a special context to capture CoRE Link Format metadata defined via core blocks.

Defined Under Namespace

Classes: MetadataExtractionContext, MetadataExtractionRequest

Instance Method Summary collapse

Constructor Details

#initialize(logger) ⇒ MetadataExtractor

Returns a new instance of MetadataExtractor.

Parameters:

  • logger (Logger)

    Logger instance for debugging



14
15
16
# File 'lib/takagi/router/metadata_extractor.rb', line 14

def initialize(logger)
  @logger = logger
end

Instance Method Details

#extract(entry) ⇒ nil, untyped

Executes route handler in metadata extraction mode to capture core block attributes This allows defining metadata inline with the handler for better DX

Parameters:

  • entry (RouteEntry)

    The route entry to extract metadata from

Returns:

  • (nil, untyped)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/takagi/router/metadata_extractor.rb', line 22

def extract(entry)
  # Skip metadata extraction for discovery routes to avoid deadlock
  # Discovery routes access the router itself, which would cause a deadlock
  # since we're already holding the routes_mutex. These routes declare
  # their metadata explicitly via the metadata: parameter instead.
  if entry.[:discovery]
    @logger.debug "Skipping metadata extraction for discovery route: #{entry.method} #{entry.path}"
    return
  end

  # Create a mock request object that will be passed to the handler
  mock_request = MetadataExtractionRequest.new

  # Create a special extraction context that uses the entry's AttributeSet directly
  # (This is safe because it runs once at boot time, not during concurrent requests)
  context = MetadataExtractionContext.new(entry, mock_request, {}, entry.receiver)

  # Execute the handler block - it may call core { ... } which updates the attribute_set
  begin
    context.run(entry.block)
  rescue StandardError => e
    # If the handler fails during metadata extraction (e.g., tries to access real data),
    # that's okay - we only care about core blocks which should not throw errors
    @logger.debug "Metadata extraction for #{entry.method} #{entry.path} encountered: #{e.message}"
  end

  # Apply any changes made by core blocks
  entry.attribute_set.apply!
end