Class: ThemeCheck::LanguageServer::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/theme_check/language_server/server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(messenger:, should_raise_errors: false, number_of_threads: 2) ⇒ Server

Returns a new instance of Server.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/theme_check/language_server/server.rb', line 15

def initialize(
  messenger:,
  should_raise_errors: false,
  number_of_threads: 2
)
  # This is what does the IO
  @messenger = messenger

  # This is what you use to communicate with the language client
  @bridge = Bridge.new(@messenger)

  # The handler handles messages from the language client
  @handler = Handler.new(@bridge)

  # The queue holds the JSON RPC messages
  @queue = Queue.new

  # The JSON RPC thread pushes messages onto the queue
  @json_rpc_thread = nil

  # The handler threads read messages from the queue
  @number_of_threads = number_of_threads
  @handlers = []

  # The error queue holds blocks the main thread. When filled, we exit the program.
  @error = SizedQueue.new(number_of_threads)

  @should_raise_errors = should_raise_errors
end

Instance Attribute Details

#handlerObject (readonly)

Returns the value of attribute handler.



12
13
14
# File 'lib/theme_check/language_server/server.rb', line 12

def handler
  @handler
end

#should_raise_errorsObject (readonly)

Returns the value of attribute should_raise_errors.



13
14
15
# File 'lib/theme_check/language_server/server.rb', line 13

def should_raise_errors
  @should_raise_errors
end

Instance Method Details

#listenObject



45
46
47
48
49
50
51
52
# File 'lib/theme_check/language_server/server.rb', line 45

def listen
  start_handler_threads
  start_json_rpc_thread
  status_code = status_code_from_error(@error.pop)
  cleanup(status_code)
rescue SignalException
  0
end

#start_handler_threadsObject



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/theme_check/language_server/server.rb', line 74

def start_handler_threads
  @number_of_threads.times do
    @handlers << Thread.new do
      loop do
        message = @queue.pop
        break if @queue.closed? && @queue.empty?
        handle_message(message)
      rescue Exception => e # rubocop:disable Lint/RescueException
        break @error << e
      end
    end
  end
end

#start_json_rpc_threadObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/theme_check/language_server/server.rb', line 54

def start_json_rpc_thread
  @json_rpc_thread = Thread.new do
    loop do
      message = @bridge.read_message
      if message[:method] == 'initialize'
        handle_message(message)
      elsif message.key?(:result)
        # Responses are handled on the main thread to prevent
        # a potential deadlock caused by all handlers waiting
        # for a responses.
        handle_response(message)
      else
        @queue << message
      end
    rescue Exception => e # rubocop:disable Lint/RescueException
      break @error << e
    end
  end
end

#status_code_from_error(e) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/theme_check/language_server/server.rb', line 88

def status_code_from_error(e)
  raise e

# support ctrl+c and stuff
rescue SignalException, DoneStreaming
  0

rescue Exception => e # rubocop:disable Lint/RescueException
  raise e if should_raise_errors
  @bridge.log("#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}")
  2
end