17 import sys |
17 import sys |
18 import threading |
18 import threading |
19 from zlib import adler32 |
19 from zlib import adler32 |
20 |
20 |
21 from PyQt4.QtCore import QProcess, pyqtSignal |
21 from PyQt4.QtCore import QProcess, pyqtSignal |
|
22 from PyQt4.QtGui import QApplication |
22 from PyQt4.QtNetwork import QTcpServer, QHostAddress |
23 from PyQt4.QtNetwork import QTcpServer, QHostAddress |
23 |
24 |
24 import Preferences |
25 import Preferences |
25 import Utilities |
26 import Utilities |
26 from Utilities.BackgroundClient import BackgroundClient |
27 from Utilities.BackgroundClient import BackgroundClient |
52 else: |
53 else: |
53 self.hostAddress = '::1' |
54 self.hostAddress = '::1' |
54 self.listen(QHostAddress(self.hostAddress)) |
55 self.listen(QHostAddress(self.hostAddress)) |
55 |
56 |
56 self.newConnection.connect(self.on_newConnection) |
57 self.newConnection.connect(self.on_newConnection) |
|
58 |
57 port = self.serverPort() |
59 port = self.serverPort() |
58 ## NOTE: Need the port if started external in debugger: |
60 ## NOTE: Need the port if started external in debugger: |
59 print('BackgroundService listening on: %i' % port) |
61 print('BackgroundService listening on: %i' % port) |
60 if sys.platform == 'win32': |
62 if sys.platform == 'win32': |
61 interpreterCompare = Utilities.samefilepath |
63 interpreterCompare = Utilities.samefilepath |
168 if fx == 'INIT': |
170 if fx == 'INIT': |
169 pass |
171 pass |
170 elif fx == 'EXCEPTION': |
172 elif fx == 'EXCEPTION': |
171 # Call sys.excepthook(type, value, traceback) to emulate the |
173 # Call sys.excepthook(type, value, traceback) to emulate the |
172 # exception which was caught on the client |
174 # exception which was caught on the client |
173 #sys.excepthook(*data) |
175 sys.excepthook(*data) |
174 print(data) |
176 QApplication.processEvents() |
175 elif data == 'Unknown service.': |
177 elif data == 'Unknown service.': |
176 callback = self.services.get((fx, lang)) |
178 callback = self.services.get((fx, lang)) |
177 if callback: |
179 if callback: |
178 callback[3](fx, lang, fn, data) |
180 callback[3](fx, lang, fn, data) |
179 else: |
181 else: |
255 if self.isWorking == lang: |
257 if self.isWorking == lang: |
256 self.isWorking = None |
258 self.isWorking = None |
257 self.connections[lang] = connection |
259 self.connections[lang] = connection |
258 connection.readyRead.connect( |
260 connection.readyRead.connect( |
259 lambda x=lang: self.__receive(x)) |
261 lambda x=lang: self.__receive(x)) |
260 |
262 connection.disconnected.connect( |
|
263 lambda x=lang: self.on_disconnectSocket(x)) |
|
264 |
261 for (fx, lng), args in self.services.items(): |
265 for (fx, lng), args in self.services.items(): |
262 if lng == lang: |
266 if lng == lang: |
263 # Register service with modulepath and module |
267 # Register service with modulepath and module |
264 self.enqueueRequest('INIT', lng, fx, args[:2]) |
268 self.enqueueRequest('INIT', lng, fx, args[:2]) |
265 |
269 |
|
270 def on_disconnectSocket(self, lang): |
|
271 """ |
|
272 Slot when connection to a client is lost. |
|
273 |
|
274 @param lang client language which connection is lost (str) |
|
275 """ |
|
276 self.connections.pop(lang) |
|
277 # Maybe the task is killed while ideling |
|
278 if self.isWorking == lang: |
|
279 self.isWorking = None |
|
280 # Remove pending jobs and send warning to the waiting caller |
|
281 # Make a copy of the list because it's modified in the loop |
|
282 for args in self.__queue[:]: |
|
283 fx, lng, fn, data = args |
|
284 if lng == lang: |
|
285 # Call onErrorCallback with error message |
|
286 self.__queue.remove(args) |
|
287 self.services[(fx, lng)][3](fx, fn, lng, self.tr( |
|
288 'Error in Erics background service stopped service.')) |
|
289 |
266 def shutdown(self): |
290 def shutdown(self): |
267 """ |
291 """ |
268 Cleanup the connections and processes when Eric is shuting down. |
292 Cleanup the connections and processes when Eric is shuting down. |
269 """ |
293 """ |
270 for connection in self.connections.values(): |
294 for connection in self.connections.values(): |