88
99def main_worker_process_function (request_queue , result_queue ):
1010 """
11- Runs in a separate process, handling requests in dict form.
12- Supported actions include:
13- - 'complete': triggers code completion
14- - 'calltip': fetches calltip/signature info
15- - 'check': fetches code check/ linting info
16- - 'setting': updates settings in the 'settings' module
17- - 'quit': shuts down the worker
11+ Main worker process for handling editor backend requests.
12+
13+ Runs in a separate process, continuously processing requests from a queue
14+ and sending results back through another queue. Supports code completion,
15+ calltips, symbol extraction, code checking, and settings management.
16+
17+ Parameters
18+ ----------
19+ request_queue : multiprocessing.Queue
20+ Queue containing request dictionaries to process
21+ result_queue : multiprocessing.Queue
22+ Queue where results are sent back to the main process
23+
24+ Request Format
25+ --------------
26+ Each request must be a dictionary with the following structure:
27+
28+ Required fields:
29+ action : str
30+ The action to perform. One of: 'complete', 'calltip', 'symbols',
31+ 'check', 'set_settings', 'quit'
32+
33+ Optional fields (depending on action):
34+ language : str, default 'text'
35+ Programming language for syntax-aware processing
36+ code : str, default ''
37+ Source code content to analyze
38+ cursor_pos : int, default 0
39+ Character position of cursor in the code
40+ path : str, optional
41+ File path for context-aware processing
42+ multiline : bool, default False
43+ Whether to enable multiline completion mode
44+ full : bool, default False
45+ Whether to return full completion details
46+ env_path : str, optional
47+ Path to Python environment for context
48+ prefix : str, optional
49+ Prefix string for filtering results
50+ settings : dict, optional
51+ Settings to update (only for 'set_settings' action)
52+
53+ Response Format
54+ ---------------
55+ Results are dictionaries placed on result_queue with action-specific content:
56+
57+ For 'complete' action:
58+ {
59+ 'action': 'complete',
60+ 'completions': list or None,
61+ 'cursor_pos': int,
62+ 'multiline': bool,
63+ 'full': bool
64+ }
65+
66+ For 'calltip' action:
67+ {
68+ 'action': 'calltip',
69+ 'signatures': list or None,
70+ 'cursor_pos': int
71+ }
72+
73+ For 'symbols' action:
74+ {
75+ 'action': 'symbols',
76+ 'symbols': list
77+ }
78+
79+ For 'check' action:
80+ {
81+ 'action': 'check',
82+ 'messages': dict
83+ }
84+
85+ Behavior
86+ --------
87+ - Runs indefinitely until receiving a 'quit' action
88+ - Dynamically loads language-specific worker modules on first use
89+ - Caches imported worker modules for efficiency
90+ - Falls back to generic worker functions if language-specific module unavailable
91+ - Skips invalid requests (None, non-dict, or missing 'action' field)
92+ - Logs all major operations and errors
93+ - For 'set_settings' action, updates the settings module attributes directly
94+ - Worker modules must provide functions: complete, calltip, symbols, check
95+ (functions can be None if not supported for that language)
96+
97+ Notes
98+ -----
99+ This function is designed to run in a separate process to avoid blocking
100+ the main editor thread during potentially slow operations like code analysis.
101+ Language-specific worker modules are expected to be in the 'languages'
102+ subpackage.
18103 """
19104 logger .info ("Started completion worker." )
20105 while True :
@@ -25,13 +110,21 @@ def main_worker_process_function(request_queue, result_queue):
25110 if request is None :
26111 logger .info ("Received None request (possibly legacy or invalid). Skipping." )
27112 continue
28-
29113 # Expect a dict with at least an 'action' field
30114 if not isinstance (request , dict ):
31115 logger .info (f"Invalid request type: { type (request )} . Skipping." )
32- continue
33-
116+ continue
117+ # Most of the parameters apply to multiple actions, so we extract them
118+ # here.
34119 action = request .get ('action' , None )
120+ language = request .get ('language' , 'text' )
121+ code = request .get ('code' , '' )
122+ cursor_pos = request .get ('cursor_pos' , 0 )
123+ path = request .get ('path' , None )
124+ multiline = request .get ('multiline' , False )
125+ full = request .get ('full' , False )
126+ env_path = request .get ('env_path' , None )
127+ prefix = request .get ('prefix' , None )
35128 if action is None :
36129 logger .info ("Request is missing 'action' field. Skipping." )
37130 continue
@@ -46,8 +139,7 @@ def main_worker_process_function(request_queue, result_queue):
46139 break
47140
48141 # Load the worker functions depending on the language. We store the
49- # imported module in a cache for efficiency
50- language = request .get ('language' , 'text' )
142+ # imported module in a cache for efficiency
51143 if language not in worker_functions_cache :
52144 try :
53145 worker_functions = importlib .import_module (
@@ -66,16 +158,10 @@ def main_worker_process_function(request_queue, result_queue):
66158 if worker_functions .complete is None :
67159 completions = None
68160 else :
69- code = request .get ('code' , '' )
70- cursor_pos = request .get ('cursor_pos' , 0 )
71- path = request .get ('path' , None )
72- multiline = request .get ('multiline' , False )
73- full = request .get ('full' , False )
74- env_path = request .get ('env_path' , None )
75161 logger .info (f"Performing code completion: language='{ language } ', multiline={ multiline } , path={ path } , env_path={ env_path } " )
76162 completions = worker_functions .complete (
77163 code , cursor_pos , path = path , multiline = multiline , full = full ,
78- env_path = env_path )
164+ env_path = env_path , prefix = prefix )
79165 if not completions :
80166 logger .info ("No completions" )
81167 else :
@@ -89,16 +175,13 @@ def main_worker_process_function(request_queue, result_queue):
89175 })
90176
91177 elif action == 'calltip' :
92- cursor_pos = request .get ('cursor_pos' , 0 )
93178 if worker_functions .calltip is None :
94179 signatures = None
95180 else :
96- code = request .get ('code' , '' )
97- path = request .get ('path' , None )
98- env_path = request .get ('env_path' , None )
99181 logger .info (f"Performing calltip: language='{ language } ', path={ path } , env_path={ env_path } " )
100182 signatures = worker_functions .calltip (
101- code , cursor_pos , path = path , env_path = env_path )
183+ code , cursor_pos , path = path , env_path = env_path ,
184+ prefix = prefix )
102185 if signatures is None :
103186 logger .info ("No calltip signatures. Sending result back." )
104187 else :
@@ -113,7 +196,6 @@ def main_worker_process_function(request_queue, result_queue):
113196 if worker_functions .symbols is None :
114197 symbols_results = []
115198 else :
116- code = request .get ('code' , '' )
117199 symbols_results = worker_functions .symbols (code )
118200 result_queue .put ({
119201 'action' : 'symbols' ,
@@ -124,11 +206,10 @@ def main_worker_process_function(request_queue, result_queue):
124206 if worker_functions .check is None :
125207 check_results = {}
126208 else :
127- code = request .get ('code' , '' )
128- check_results = worker_functions .check (code )
209+ check_results = worker_functions .check (code , prefix = prefix )
129210 result_queue .put ({
130211 'action' : 'check' ,
131212 'messages' : check_results
132213 })
133214
134- logger .info ("Completion worker has shut down." )
215+ logger .info ("Completion worker has shut down." )
0 commit comments