Class: RubySkynet::Server

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

Constant Summary collapse

@@server =
nil
@@services =
ThreadSafe::Hash.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start_port = nil, ip_address = nil) ⇒ Server

Start the server so that it can start taking RPC calls Returns false if the server is already running



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ruby_skynet/server.rb', line 82

def initialize(start_port = nil, ip_address = nil)
  ip_address ||= RubySkynet.local_ip_address
  start_port = (start_port || RubySkynet.server_port).to_i
  raise InvalidConfigurationException.new("Invalid Starting Port number: #{start_port}") unless start_port > 0

  # If port is in use, try the next port in sequence
  port_count = 0
  begin
    @server   = ::TCPServer.new(ip_address, start_port + port_count)
    @hostname = ip_address
    @port     = start_port + port_count
  rescue Errno::EADDRINUSE => exc
    if port_count < 999
      port_count += 1
      retry
    end
    raise exc
  end

  # Start Server listener thread
  @listener_thread = Thread.new { run }

  # Register services hosted by this server
  self.class.services.each_value {|klass| register_service(klass)}
end

Instance Attribute Details

#hostnameObject (readonly)

The actual port the server is running at



78
79
80
# File 'lib/ruby_skynet/server.rb', line 78

def hostname
  @hostname
end

#portObject (readonly)

The actual port the server is running at



78
79
80
# File 'lib/ruby_skynet/server.rb', line 78

def port
  @port
end

Class Method Details

.deregister_service(klass) ⇒ Object

De-register service



60
61
62
63
64
65
# File 'lib/ruby_skynet/server.rb', line 60

def self.deregister_service(klass)
  raise InvalidServiceException.new("#{klass.inspect} is not a RubySkynet::Service") unless klass.respond_to?(:skynet_name) && klass.respond_to?(:skynet_version) && klass.respond_to?(:skynet_region)

  @@server.deregister_service(klass) if @@server
  @@services.delete(klass.skynet_name)
end

.load_servicesObject

Load and register all services found in the supplied path and it’s sub-directories



68
69
70
71
72
73
74
75
# File 'lib/ruby_skynet/server.rb', line 68

def self.load_services
  RubySkynet::Server.logger.benchmark_info "Loaded Skynet Services" do
    # Load services
    Dir.glob("#{RubySkynet.services_path}/**/*.rb").each do |path|
      load path
    end
  end
end

.register_service(klass) ⇒ Object

Registers a Service Class as being available at this host and port



48
49
50
51
52
53
54
55
56
57
# File 'lib/ruby_skynet/server.rb', line 48

def self.register_service(klass)
  raise InvalidServiceException.new("#{klass.inspect} is not a RubySkynet::Service") unless klass.respond_to?(:skynet_name) && klass.respond_to?(:skynet_version) && klass.respond_to?(:skynet_region)

  previous_klass = @@services[klass.skynet_name]
  if previous_klass && (previous_klass.name != klass.name)
    logger.warn("Service with name: #{klass.skynet_name} is already registered to a different implementation:#{previous_klass.name}")
  end
  @@services[klass.skynet_name] = klass
  @@server.register_service(klass) if @@server
end

.running?Boolean

Is the single instance of the server running

Returns:

  • (Boolean)


33
34
35
# File 'lib/ruby_skynet/server.rb', line 33

def self.running?
  (@@server != nil) && @@server.running?
end

.servicesObject

Services currently loaded and available at this server when running



43
44
45
# File 'lib/ruby_skynet/server.rb', line 43

def self.services
  @@services
end

.start(start_port = nil, ip_address = nil) ⇒ Object

Start a single instance of the server



16
17
18
19
20
21
22
23
24
# File 'lib/ruby_skynet/server.rb', line 16

def self.start(start_port = nil, ip_address = nil)
  @@server ||= new(start_port, ip_address)

  # Stop the skynet server on shutdown
  # To ensure services are de-registered in the service registry
  at_exit do
    ::RubySkynet::Server.stop
  end
end

.stopObject

Stop the single instance of the server



27
28
29
30
# File 'lib/ruby_skynet/server.rb', line 27

def self.stop
  @@server.finalize if @@server
  @@server = nil
end

.wait_until_server_stopsObject

Wait forever until the running server stops



38
39
40
# File 'lib/ruby_skynet/server.rb', line 38

def self.wait_until_server_stops
  (@@server != nil) && @@server.wait_until_server_stops
end

Instance Method Details

#deregister_service(klass) ⇒ Object

De-register service from this server



136
137
138
139
# File 'lib/ruby_skynet/server.rb', line 136

def deregister_service(klass)
  logger.info "De-registering Service: #{klass.name} with name: #{klass.skynet_name}"
  ::RubySkynet.service_registry.deregister_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
end

#finalizeObject



108
109
110
111
112
113
114
115
116
117
# File 'lib/ruby_skynet/server.rb', line 108

def finalize
  @server.close if @server
  logger.info "Skynet Server Stopped"

  # Deregister services hosted by this server
  self.class.services.each_value do |klass|
    deregister_service(klass) rescue nil
  end
  logger.info "Skynet Services De-registered"
end

#register_service(klass) ⇒ Object

Registers a Service Class as being available at this server



130
131
132
133
# File 'lib/ruby_skynet/server.rb', line 130

def register_service(klass)
  logger.info "Registering Service: #{klass.name} with name: #{klass.skynet_name}"
  ::RubySkynet.service_registry.register_service(klass.skynet_name, klass.skynet_version || 1, klass.skynet_region, @hostname, @port)
end

#running?Boolean

Returns whether the server is running

Returns:

  • (Boolean)


120
121
122
# File 'lib/ruby_skynet/server.rb', line 120

def running?
  (@server != nil) && !@server.closed?
end

#wait_until_server_stopsObject

Wait forever until the running server stops



125
126
127
# File 'lib/ruby_skynet/server.rb', line 125

def wait_until_server_stops
  @listener_thread.join
end