Class: Gritz::Testing::Server

Inherits:
Object
  • Object
show all
Defined in:
/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb

Overview

Starts a single-process server for integration tests.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, logger:) ⇒ Server

Returns a new instance of Server.



29
30
31
32
33
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 29

def initialize(config, logger:)
  @config = config
  @logger = logger
  config.validate_single_process!
end

Instance Attribute Details

#address ⇒ Object (readonly)



10
11
12
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 10

def address
  @address
end

#port ⇒ Object (readonly)



10
11
12
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 10

def port
  @port
end

#transport ⇒ Object (readonly)



10
11
12
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 10

def transport
  @transport
end

Class Method Details

.start(config = nil, controllers: nil, middleware: nil, logger: Logger.new(File::NULL)) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 12

def self.start(config = nil, controllers: nil, middleware: nil, logger: Logger.new(File::NULL))
  config ||= Configuration.new.tap do |settings|
    settings.workers = 0
    settings.bind = "127.0.0.1:0"
  end
  config.controllers = controllers if controllers
  config.middleware = middleware if middleware
  server = new(config, logger:).start
  return server unless block_given?

  begin
    yield server
  ensure
    server.stop
  end
end

Instance Method Details

#start ⇒ Object

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 35

def start
  raise ArgumentError, "Testing::Server is already started or stopped" if @started || @stopped

  @started = true
  begin
    @config.preload! if @config.preload_app?
    router = Router.new(controllers: @config.controllers, strict: @config.strict_routes, logger: @logger)
    @lifecycle_started = true
    @config.run_hooks(:on_worker_boot, 0)
    @recorder = @config.metrics_recorder_factory&.call(worker: 0)
    dispatcher = Dispatcher.new(router:, middleware: @config.middleware, logger: @logger, metrics: @recorder)
    @transport = Transport.const_get(@config.transport.to_s.capitalize).new(config: @config, dispatcher:, logger: @logger)
    @port = transport.bind
    @address = @config.bind.sub(/:\d+\z/, ":#{port}")
    transport.start
    unless @config.health_checks.empty?
      @health_stop = Queue.new
      @health_thread = Thread.new do
        transport.refresh_health until @health_stop.pop(timeout: @config.status_interval)
      end
    end
    self
  rescue StandardError
    stop
    raise
  end
end

#stop ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File '/home/runner/work/gritz/gritz/sources/gritz-core/lib/gritz/testing/server.rb', line 63

def stop
  return if @stopped

  @stopped = true
  deadline = monotonic + @config.shutdown_timeout
  begin
    @health_stop&.push(true)
    if @health_thread && !@health_thread.join([deadline - monotonic, 0].max)
      @health_thread.kill.join
    end
    transport&.stop(deadline: Time.now + [deadline - monotonic, 0].max)
  ensure
    begin
      @config.run_hooks(:on_worker_shutdown, 0) if @lifecycle_started
    ensure
      begin
        @recorder&.observe_rejected(transport.stats.fetch(:rejected_total, 0)) if transport
        @recorder&.observe_worker({ pid: Process.pid, index: 0, state: "stopped" })
      ensure
        @recorder&.close(timeout: [deadline - monotonic, 0].max)
      end
    end
  end
end