Class: Takagi::Router::MetadataExtractor

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

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) ⇒ Object

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



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