Class: Gruf::Server

Inherits:
Object
  • Object
show all
Includes:
Loggable
Defined in:
lib/gruf/server.rb

Overview

Represents a gRPC server. Automatically loads and augments gRPC handlers and services based on configuration values.

Defined Under Namespace

Classes: ServerAlreadyStartedError

Constant Summary collapse

KILL_SIGNALS =
%w[INT TERM QUIT].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Loggable

#logger

Constructor Details

#initialize(opts = {}) ⇒ Server

Initialize the server and load and setup the services

Parameters:

  • opts (Hash) (defaults to: {})


42
43
44
45
46
47
48
49
50
# File 'lib/gruf/server.rb', line 42

def initialize(opts = {})
  @options = opts || {}
  @interceptors = opts.fetch(:interceptor_registry, Gruf.interceptors)
  @interceptors = Gruf::Interceptors::Registry.new unless @interceptors.is_a?(Gruf::Interceptors::Registry)
  @services = nil
  @started = false
  @hostname = opts.fetch(:hostname, Gruf.server_binding_url)
  @event_listener_proc = opts.fetch(:event_listener_proc, Gruf.event_listener_proc)
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



35
36
37
# File 'lib/gruf/server.rb', line 35

def options
  @options
end

#portObject (readonly)

Returns the value of attribute port.



32
33
34
# File 'lib/gruf/server.rb', line 32

def port
  @port
end

Instance Method Details

#add_interceptor(klass, opts = {}) ⇒ Object

Add an interceptor to the server

Parameters:

  • klass (Class)

    The Interceptor to add to the registry

  • opts (Hash) (defaults to: {})

    A hash of options for the interceptor

Raises:



128
129
130
131
132
# File 'lib/gruf/server.rb', line 128

def add_interceptor(klass, opts = {})
  raise ServerAlreadyStartedError if @started

  @interceptors.use(klass, opts)
end

#add_service(klass) ⇒ Object

Add a gRPC service stub to be served by gruf

Parameters:

  • klass (Class)

Raises:



115
116
117
118
119
# File 'lib/gruf/server.rb', line 115

def add_service(klass)
  raise ServerAlreadyStartedError if @started

  @services << klass unless services.include?(klass)
end

#clear_interceptorsObject

Clear the interceptor registry of interceptors



183
184
185
186
187
# File 'lib/gruf/server.rb', line 183

def clear_interceptors
  raise ServerAlreadyStartedError if @started

  @interceptors.clear
end

#insert_interceptor_after(after_class, interceptor_class, opts = {}) ⇒ Object

Insert an interceptor after another in the currently registered order of execution

Parameters:

  • after_class (Class)

    The interceptor that you want to add the new interceptor after

  • interceptor_class (Class)

    The Interceptor to add to the registry

  • opts (Hash) (defaults to: {})

    A hash of options for the interceptor

Raises:



154
155
156
157
158
# File 'lib/gruf/server.rb', line 154

def insert_interceptor_after(after_class, interceptor_class, opts = {})
  raise ServerAlreadyStartedError if @started

  @interceptors.insert_after(after_class, interceptor_class, opts)
end

#insert_interceptor_before(before_class, interceptor_class, opts = {}) ⇒ Object

Insert an interceptor before another in the currently registered order of execution

Parameters:

  • before_class (Class)

    The interceptor that you want to add the new interceptor before

  • interceptor_class (Class)

    The Interceptor to add to the registry

  • opts (Hash) (defaults to: {})

    A hash of options for the interceptor

Raises:



141
142
143
144
145
# File 'lib/gruf/server.rb', line 141

def insert_interceptor_before(before_class, interceptor_class, opts = {})
  raise ServerAlreadyStartedError if @started

  @interceptors.insert_before(before_class, interceptor_class, opts)
end

#list_interceptorsArray<Class>

Return the current list of added interceptor classes

Returns:

  • (Array<Class>)


165
166
167
# File 'lib/gruf/server.rb', line 165

def list_interceptors
  @interceptors.list
end

#remove_interceptor(klass) ⇒ Object

Remove an interceptor from the server

Parameters:

  • klass (Class)

Raises:



174
175
176
177
178
# File 'lib/gruf/server.rb', line 174

def remove_interceptor(klass)
  raise ServerAlreadyStartedError if @started

  @interceptors.remove(klass)
end

#serverGRPC::RpcServer

Returns The GRPC server running.

Returns:

  • (GRPC::RpcServer)

    The GRPC server running



55
56
57
58
59
60
61
62
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 'lib/gruf/server.rb', line 55

def server
  server_mutex do
    @server ||= begin
      # For backward compatibility, we allow these options to be passed directly
      # in the Gruf::Server options, or via Gruf.rpc_server_options.
      server_options = {
        pool_size: options.fetch(:pool_size, Gruf.rpc_server_options[:pool_size]),
        max_waiting_requests: options.fetch(:max_waiting_requests, Gruf.rpc_server_options[:max_waiting_requests]),
        poll_period: options.fetch(:poll_period, Gruf.rpc_server_options[:poll_period]),
        pool_keep_alive: options.fetch(:pool_keep_alive, Gruf.rpc_server_options[:pool_keep_alive]),
        connect_md_proc: options.fetch(:connect_md_proc, Gruf.rpc_server_options[:connect_md_proc]),
        server_args: options.fetch(:server_args, Gruf.rpc_server_options[:server_args])
      }

      server = if @event_listener_proc
                 server_options[:event_listener_proc] = @event_listener_proc
                 Gruf::InstrumentableGrpcServer.new(**server_options)
               else
                 GRPC::RpcServer.new(**server_options)
               end

      @port = server.add_http2_port(@hostname, ssl_credentials)
      # do not reference `services` any earlier than this method, as it allows autoloading to take effect
      # and load services into `Gruf.services` as late as possible, which gives us flexibility with different
      # execution paths (such as vanilla ruby, grape, multiple Rails versions, etc). The autoloaders are
      # initially loaded in `Gruf::Cli::Executor` _directly_ before the gRPC services are loaded into the gRPC
      # server, to allow for loading services as late as possible in the execution chain.
      services.each { |s| server.handle(s) }
      server
    end
  end
end

#start!Object

Start the gRPC server

:nocov:



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/gruf/server.rb', line 92

def start!
  update_proc_title(:starting)

  server_thread = Thread.new do
    logger.info { "[gruf] Starting gruf server at #{@hostname}..." }
    server.run_till_terminated_or_interrupted(KILL_SIGNALS)
  end
  @started = true
  update_proc_title(:serving)
  server_thread.join
  @started = false

  update_proc_title(:stopped)
  logger.info { '[gruf] Goodbye!' }
end