Class: Steep::Server::CommandSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/server/command_socket.rb

Overview

Accepts connections on a UNIX socket and forwards the received requests to the master

Started by steep langserver so that CLI commands like steep query and steep check can talk to the language server the IDE is running, instead of a standalone daemon process.

Defined Under Namespace

Classes: Session

Constant Summary collapse

LSP =
LanguageServer::Protocol

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(master:, configuration:) ⇒ CommandSocket

Returns a new instance of CommandSocket.



51
52
53
54
55
56
# File 'lib/steep/server/command_socket.rb', line 51

def initialize(master:, configuration:)
  @master = master
  @configuration = configuration
  @server = nil
  @accept_thread = nil
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



49
50
51
# File 'lib/steep/server/command_socket.rb', line 49

def configuration
  @configuration
end

#masterObject (readonly)

Returns the value of attribute master.



49
50
51
# File 'lib/steep/server/command_socket.rb', line 49

def master
  @master
end

Instance Method Details

#socket_pathObject



58
59
60
# File 'lib/steep/server/command_socket.rb', line 58

def socket_path
  configuration.socket_path
end

#startObject

Binds the UNIX socket and starts accepting connections in a background thread

Returns false without binding when another process (a standalone steep server daemon or another language server) is already serving on the socket.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/steep/server/command_socket.rb', line 67

def start
  if File.exist?(socket_path)
    if socket_alive?
      Steep.logger.warn { "Command socket is already served by another process: #{socket_path}" }
      return false
    end

    unless File.socket?(socket_path)
      Steep.logger.error { "#{socket_path} exists but is not a socket, skipping command socket setup" }
      return false
    end

    File.delete(socket_path)
  end

  @server = UNIXServer.new(socket_path)
  File.chmod(0o600, socket_path)

  @accept_thread = Thread.new do
    Thread.current.abort_on_exception = false
    accept_loop()
  end

  Steep.logger.info { "Command socket is ready: #{socket_path}" }

  true
rescue Errno::EADDRINUSE
  Steep.logger.warn { "Command socket is already served by another process: #{socket_path}" }
  false
end

#stopObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/steep/server/command_socket.rb', line 98

def stop
  server = @server
  @server = nil

  if server
    begin
      server.close
    rescue IOError
      # Already closed
    end

    @accept_thread&.join(1)

    begin
      File.delete(socket_path)
    rescue Errno::ENOENT
      # Already deleted
    end
  end
end