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



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