Class: Nonnative::Server

Inherits:
Runner
  • Object
show all
Defined in:
lib/nonnative/server.rb

Overview

Runtime runner that manages an in-process Ruby server.

A server runner:

  • starts a Ruby thread that runs #perform_start,
  • waits briefly (via the runner wait), and
  • participates in readiness/shutdown via TCP port checks orchestrated by Pool.

Concrete server implementations are expected to subclass Server and implement:

  • #perform_start (to bind/listen and begin serving), and
  • #perform_stop (to gracefully shut down).

#stop calls the stop hook once for every successfully constructed lifecycle, even if startup never created a worker thread. This lets rollback release resources acquired by a constructor.

The underlying configuration is a ConfigurationServer.

Direct Known Subclasses

GRPCServer, HTTPServer

Instance Method Summary collapse

Methods inherited from Runner

#name

Constructor Details

#initialize(service) ⇒ Server

Returns a new instance of Server.

Parameters:



24
25
26
27
28
29
# File 'lib/nonnative/server.rb', line 24

def initialize(service)
  super

  @timeout = Nonnative::Timeout.new(service.timeout)
  @cleanup_required = true
end

Instance Method Details

#startArray<(Integer, TrueClass)>

Starts the server thread if it is not already running.

A thread retained from a stop that exceeded its timeout is treated as not running, so a server can be restarted even if a prior #stop never observed that thread's actual termination.

Returns:

  • (Array<(Integer, TrueClass)>)

    a tuple of:

    • a stable identifier for this server instance (object_id)
    • true (thread creation itself is considered started; readiness is checked separately)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/nonnative/server.rb', line 40

def start
  unless thread&.alive?
    @error = nil
    @cleanup_required = true
    @thread = Thread.new do
      perform_start
    rescue StandardError => e
      @error = e
      raise
    end
    @thread.report_on_exception = true

    wait_start

    Nonnative.logger.info "started server '#{service.name}'"
  end

  [object_id, true]
end

#stopInteger, Array<(Integer, FalseClass)>

Stops the server if its current lifecycle still requires cleanup.

Calls #perform_stop even if startup never created a worker thread, then waits up to the configured timeout for any owned thread to finish. A thread that exceeds the timeout is terminated and reported through Pool. A later stop retries draining a retained thread without calling #perform_stop again.

Returns:

  • (Integer, Array<(Integer, FalseClass)>)

    the server identifier when cleanup finishes, or the identifier and false when the owned thread exceeds the configured timeout



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/nonnative/server.rb', line 69

def stop
  owned_thread = thread
  return object_id unless @cleanup_required || owned_thread

  perform_cleanup
  stopped = drain_thread(owned_thread) == :drained
  wait_stop
  @thread = nil unless owned_thread&.alive?

  Nonnative.logger.info "stopped server '#{service.name}'" if stopped

  stopped ? object_id : [object_id, false]
end

#terminationString?

Describes how the server thread terminated before becoming ready, for lifecycle diagnostics.

Returns nil while the thread is still alive, so callers can distinguish a dead thread from a live server that merely missed its readiness window.

Returns:

  • (String, nil)

    termination detail (clean early return or uncaught exception), or nil



89
90
91
92
93
94
95
# File 'lib/nonnative/server.rb', line 89

def termination
  return if thread.nil? || thread.alive?

  return "server thread raised #{error.class}: #{error.message}" if error

  'server thread exited before readiness'
end