Class: Terminalwire::V2::Server::StreamRouter

Inherits:
Object
  • Object
show all
Defined in:
lib/terminalwire/v2/server/stream_router.rb

Overview

A stand-in for a global IO stream ($stdout/$stderr/$stdin) that dispatches every call to a fiber-local target, falling back to the real stream when no command is currently redirecting on this fiber.

This is what makes redirection concurrency-safe: instead of mutating the process-global $stdout per command (which interleaves when two run at once), we install ONE router as $stdout for the whole process and let each fiber point its own target at its own client. Thread.current[] is fiber-local in Ruby, so this isolates both threaded servers (Puma) and fiber-per-request servers (Falcon).

Instance Method Summary collapse

Constructor Details

#initialize(key, fallback) ⇒ StreamRouter

Returns a new instance of StreamRouter.

Parameters:

  • key (Symbol)

    fiber-local key, e.g. :terminalwire_stdout

  • fallback (IO)

    the real stream to use when no redirect is active



18
19
20
21
# File 'lib/terminalwire/v2/server/stream_router.rb', line 18

def initialize(key, fallback)
  @key = key
  @fallback = fallback
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/terminalwire/v2/server/stream_router.rb', line 50

def method_missing(name, *args, &block)
  target = __target__
  if target.respond_to?(name)
    target.public_send(name, *args, &block)
  else
    super
  end
end

Instance Method Details

#__bind__(target) ⇒ Object

Set/clear the fiber-local target. Returns the previous value so callers can restore exactly (supporting nesting).



28
29
30
31
32
# File 'lib/terminalwire/v2/server/stream_router.rb', line 28

def __bind__(target)
  previous = Thread.current[@key]
  Thread.current[@key] = target
  previous
end

#__restore__(previous) ⇒ Object



34
# File 'lib/terminalwire/v2/server/stream_router.rb', line 34

def __restore__(previous) = Thread.current[@key] = previous

#__target__Object

The stream this fiber's calls should go to right now.



24
# File 'lib/terminalwire/v2/server/stream_router.rb', line 24

def __target__ = Thread.current[@key] || @fallback

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/terminalwire/v2/server/stream_router.rb', line 46

def respond_to_missing?(name, include_private = false)
  __target__.respond_to?(name, include_private) || super
end