Repository: spyder-ide/spyder

Issue:
Spyder 3.0 Beta 3 crashing or freezing because of zmq problems
## Description of your problem

**What steps will reproduce the problem?**
1. Open spyder 3.0 b3, code for a bit.
2. Close laptop lid
3. Open laptop lid a few hours later
4. Observe spinning color wheel and unresponsive application.

**What is the expected output? What do you see instead?**
Spyder should let me continue working as before. Instead, it is frozen and must be force quit to continue.

**Please provide any additional information below**

[spyder crash.txt](https://github.com/spyder-ide/spyder/files/314084/spyder.crash.txt)
## Versions and main components
- Spyder Version: 3.0.0dev0
- Python Version: 3.5.1 64 bits
- Operating system: OSX 10.11.5
## Dependencies

Please go to the menu entry `Help > Optional Dependencies` (or
`Help > Dependencies`), press the button `Copy to clipboard`
and paste the contents below:



Discussion:
Looks like a problem with threads and zmq. @blink1073 ?

Looks that way.  Note for self: http://stackoverflow.com/a/32051472

We need to solve this for Beta4. It also affects Linux.

I have a similar problem: After launching spyder 3.0.0b3 it freezes after a handful of minutes.
Also for some reason I have three QtWebEngineProcess appearing on my OSX dock.
I tried to find out where this was coming from and my investigations gave the following:
-execute "python3 -m pdb bootstrap.py"
-ctrl + c when app crashes
-the result is displayed in the internal console of spyder (Even though the app is frozen for some reason)
-As I can't copy-paste (frozen app), I took a screenshot

![error](https://cloud.githubusercontent.com/assets/6740194/16050997/becde5d2-3255-11e6-80ff-053d34e7715b.png)
If this is different I can open a separate issue


Resolving patch:
diff --git a/spyderlib/utils/introspection/plugin_client.py b/spyderlib/utils/introspection/plugin_client.py
--- a/spyderlib/utils/introspection/plugin_client.py
+++ b/spyderlib/utils/introspection/plugin_client.py
@@ -132,6 +132,9 @@ def close(self):
         """
         self.closing = True
         self.timer.stop()
+        self.notifier.activated.disconnect(self._on_msg_received)
+        self.notifier.setEnabled(False)
+        del self.notifier
         self.request('server_quit')
         self.process.waitForFinished(1000)
         self.context.destroy(0)
diff --git a/spyderlib/utils/introspection/plugin_server.py b/spyderlib/utils/introspection/plugin_server.py
--- a/spyderlib/utils/introspection/plugin_server.py
+++ b/spyderlib/utils/introspection/plugin_server.py
@@ -5,6 +5,7 @@
 # (see spyderlib/__init__.py for details)
 
 import sys
+import time
 import traceback
 
 import zmq
@@ -39,21 +40,33 @@ def run(self):
         """
         while 1:
             # Poll for events, handling a timeout.
-            events = self.socket.poll(TIMEOUT)
+            try:
+                events = self.socket.poll(TIMEOUT)
+            except KeyboardInterrupt:
+                time.sleep(0.1)
+                continue
             if events == 0:
                 print('Timed out')
                 return
             # Drain all exising requests, handling quit and heartbeat.
             requests = []
             while 1:
-                request = self.socket.recv_pyobj()
+                try:
+                    request = self.socket.recv_pyobj()
+                except KeyboardInterrupt:
+                    time.sleep(0.1)
+                    continue
                 if request['func_name'] == 'server_quit':
                     print('Quitting')
                     sys.stdout.flush()
                     return
                 elif request['func_name'] != 'server_heartbeat':
                     requests.append(request)
-                events = self.socket.poll(0)
+                try:
+                    events = self.socket.poll(0)
+                except KeyboardInterrupt:
+                    time.sleep(0.1)
+                    continue
                 if events == 0:
                     break
             # Select the most recent request.


Test patch: