##// END OF EJS Templates
Refactor and simplification of zmqterminal.
Thomas Kluyver -
Show More
@@ -1,51 +1,42 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 import readline
2 import readline
3 import time
3 from Queue import Empty
4 import sys
5 stdout = sys.stdout
6
7 class TimeoutError(Exception):
8 pass
9
4
10 class ClientCompleter2p(object):
5 class ClientCompleter2p(object):
11 """Client-side completion machinery.
6 """Client-side completion machinery.
12
7
13 How it works: self.complete will be called multiple times, with
8 How it works: self.complete will be called multiple times, with
14 state=0,1,2,... When state=0 it should compute ALL the completion matches,
9 state=0,1,2,... When state=0 it should compute ALL the completion matches,
15 and then return them for each value of state."""
10 and then return them for each value of state."""
16
11
17 def __init__(self,client, km):
12 def __init__(self,client, km):
18 self.km = km
13 self.km = km
19 self.matches = []
14 self.matches = []
20 self.client = client
15 self.client = client
21
16
22 def complete_request(self,text):
17 def complete_request(self,text):
23 line = readline.get_line_buffer()
18 line = readline.get_line_buffer()
24 #msg_id = self.km.xreq_channel.complete(text=text,line=line)#this method is not working, the code not continue
19 #msg_id = self.km.xreq_channel.complete(text=text,line=line)#this method is not working, the code not continue
25 msg = self.km.session.send(self.km.xreq_channel.socket,
20 msg = self.km.session.send(self.km.xreq_channel.socket,
26 'complete_request',
21 'complete_request',
27 dict(text=text, line=line))
22 dict(text=text, line=line))
28 # send completion request to kernel
23 # send completion request to kernel
29 # Give the kernel up to 0.5s to respond
24 # Give the kernel up to 0.5s to respond
30 for i in range(5):
25 msg_xreq = self.km.xreq_channel.get_msg(timeout=0.5)
31 if self.km.xreq_channel.was_called():
26 if msg["header"]['session'] == msg_xreq["parent_header"]['session'] and \
32 msg_xreq = self.km.xreq_channel.get_msg()
27 msg_xreq["content"]["status"] == 'ok' and \
33 if msg["header"]['session'] == msg_xreq["parent_header"]['session'] and \
28 msg_xreq["msg_type"] == "complete_reply" :
34 msg_xreq["content"]["status"] == 'ok' and \
29 return msg_xreq["content"]["matches"]
35 msg_xreq["msg_type"] == "complete_reply" :
30 return []
36 return msg_xreq["content"]["matches"]
37
38 time.sleep(0.1)
39 raise TimeoutError
40
31
41 def complete(self, text, state):
32 def complete(self, text, state):
42 if state == 0:
33 if state == 0:
43 try:
34 try:
44 self.matches = self.complete_request(text)
35 self.matches = self.complete_request(text)
45 except TimeoutError:
36 except Empty:
46 print('WARNING: Kernel timeout on tab completion.')
37 print('WARNING: Kernel timeout on tab completion.')
47
38
48 try:
39 try:
49 return self.matches[state]
40 return self.matches[state]
50 except IndexError:
41 except IndexError:
51 return None
42 return None
@@ -1,280 +1,266 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Frontend of ipython working with python-zmq
2 """Frontend of ipython working with python-zmq
3
3
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
4 Ipython's frontend, is a ipython interface that send request to kernel and proccess the kernel's outputs.
5
5
6 For more details, see the ipython-zmq design
6 For more details, see the ipython-zmq design
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2010 The IPython Development Team
9 # Copyright (C) 2010 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import __builtin__
19 import __builtin__
20 from contextlib import nested
21 import time
22 import sys
20 import sys
23 import os
21 import os
24 import signal
22 from Queue import Empty
25 import uuid
26 import cPickle as pickle
27 import code
28 import zmq
29 import readline
23 import readline
30 import rlcompleter
24 import rlcompleter
31 import time
32
25
33 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
34 # Imports from ipython
27 # Imports from ipython
35 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
36 from IPython.external.argparse import ArgumentParser
29 from IPython.external.argparse import ArgumentParser
37 from IPython.utils.traitlets import (
38 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
39 )
40 from IPython.core.interactiveshell import get_default_colors
41 from IPython.core.excolors import exception_colors
42 from IPython.utils import PyColorize
43 from IPython.core.inputsplitter import IPythonInputSplitter
30 from IPython.core.inputsplitter import IPythonInputSplitter
44 from IPython.frontend.zmqterminal.kernelmanager import KernelManager2p as KernelManager
31 from IPython.zmq.blockingkernelmanager import BlockingKernelManager as KernelManager
45 from IPython.zmq.session import Session
46 from IPython.frontend.zmqterminal.completer import ClientCompleter2p
32 from IPython.frontend.zmqterminal.completer import ClientCompleter2p
47
33
48 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
49 # Network Constants
35 # Network Constants
50 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
51
37
52 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
38 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
53 class Frontend(object):
39 class Frontend(object):
54 """This class is a simple frontend to ipython-zmq
40 """This class is a simple frontend to ipython-zmq
55
41
56 NOTE: this class uses kernelmanager to manipulate sockets
42 NOTE: this class uses kernelmanager to manipulate sockets
57
43
58 Parameters:
44 Parameters:
59 -----------
45 -----------
60 kernelmanager : object
46 kernelmanager : object
61 instantiated object from class KernelManager in module kernelmanager
47 instantiated object from class KernelManager in module kernelmanager
62
48
63 """
49 """
64
50
65 def __init__(self, kernelmanager):
51 def __init__(self, kernelmanager):
66 self.km = kernelmanager
52 self.km = kernelmanager
67 self.session = kernelmanager.session
53 self.session = kernelmanager.session
68 self.request_socket = self.km.xreq_channel.socket
54 self.request_socket = self.km.xreq_channel.socket
69 self.sub_socket = self.km.sub_channel.socket
55 self.sub_socket = self.km.sub_channel.socket
70 self.reply_socket = self.km.rep_channel.socket
56 self.reply_socket = self.km.rep_channel.socket
71 self.msg_header = self.km.session.msg_header()
57 self.msg_header = self.km.session.msg_header()
72 self.completer = ClientCompleter2p(self,self.km)
58 self.completer = ClientCompleter2p(self, self.km)
73 readline.parse_and_bind("tab: complete")
59 readline.parse_and_bind("tab: complete")
74 readline.parse_and_bind('set show-all-if-ambiguous on')
60 readline.parse_and_bind('set show-all-if-ambiguous on')
75 readline.set_completer(self.completer.complete)
61 readline.set_completer(self.completer.complete)
76
62
77 history_path = os.path.expanduser('~/.ipython/history')
63 history_path = os.path.expanduser('~/.ipython/history')
78 if os.path.isfile(history_path):
64 if os.path.isfile(history_path):
79 rlcompleter.readline.read_history_file(history_path)
65 rlcompleter.readline.read_history_file(history_path)
80 else:
66 else:
81 print("history file cannot be read.")
67 print("history file cannot be read.")
82
68
83 self.messages = {}
69 self.messages = {}
84
70
85 self._splitter = IPythonInputSplitter()
71 self._splitter = IPythonInputSplitter()
86 self.code = ""
72 self.code = ""
87
73
88 self.prompt_count = 0
74 self.prompt_count = 0
89 self._get_initial_prompt()
75 self._get_initial_prompt()
90
76
91 def _get_initial_prompt(self):
77 def _get_initial_prompt(self):
92 self._execute('', hidden=True)
78 self._execute('', hidden=True)
93
79
94 def interact(self):
80 def interact(self):
95 """Gets input from console using inputsplitter, then
81 """Gets input from console using inputsplitter, then
96 while you enter code it can indent and set index id to any input
82 while you enter code it can indent and set index id to any input
97 """
83 """
98
84
99 try:
85 try:
100 self._splitter.push(raw_input('In[%i]:'%self.prompt_count+self.code))
86 self._splitter.push(raw_input('In[%i]:'%self.prompt_count+self.code))
101 while self._splitter.push_accepts_more():
87 while self._splitter.push_accepts_more():
102 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
88 self.code = raw_input('.....:'+' '*self._splitter.indent_spaces)
103 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
89 self._splitter.push(' '*self._splitter.indent_spaces+self.code)
104 self._execute(self._splitter.source,False)
90 self._execute(self._splitter.source,False)
105 self._splitter.reset()
91 self._splitter.reset()
106 except KeyboardInterrupt:
92 except KeyboardInterrupt:
107 print('\nKeyboardInterrupt\n')
93 print('\nKeyboardInterrupt\n')
108 pass
94 pass
109
95
110
96
111 def start(self):
97 def start(self):
112 """Start the interaction loop, calling the .interact() method for each
98 """Start the interaction loop, calling the .interact() method for each
113 input cell.
99 input cell.
114 """
100 """
115 while True:
101 while True:
116 try:
102 try:
117 self.interact()
103 self.interact()
118 except KeyboardInterrupt:
104 except KeyboardInterrupt:
119 print('\nKeyboardInterrupt\n')
105 print('\nKeyboardInterrupt\n')
120 pass
106 pass
121 except EOFError:
107 except EOFError:
122 answer = ''
108 answer = ''
123 while True:
109 while True:
124 answer = raw_input('\nDo you really want to exit ([y]/n)?')
110 answer = raw_input('\nDo you really want to exit ([y]/n)?')
125 if answer == 'y' or answer == '' :
111 if answer == 'y' or answer == '' :
126 self.km.shutdown_kernel()
112 self.km.shutdown_kernel()
127 sys.exit()
113 sys.exit()
128 elif answer == 'n':
114 elif answer == 'n':
129 break
115 break
130
116
131 def _execute(self, source, hidden = True):
117 def _execute(self, source, hidden = True):
132 """ Execute 'source'. If 'hidden', do not show any output.
118 """ Execute 'source'. If 'hidden', do not show any output.
133
119
134 See parent class :meth:`execute` docstring for full details.
120 See parent class :meth:`execute` docstring for full details.
135 """
121 """
136 self.km.xreq_channel.execute(source, hidden)
122 self.km.xreq_channel.execute(source, hidden)
137 self.handle_xreq_channel()
123 while not self.km.xreq_channel.msg_ready():
138 self.handle_rep_channel()
124 try:
125 self.handle_rep_channel(timeout=0.1)
126 except Empty:
127 pass
128 self.handle_xreq_channel()
139
129
140 def handle_xreq_channel(self):
130 def handle_xreq_channel(self):
141 # Give the kernel up to 0.5s to respond
131 self.msg_xreq = self.km.xreq_channel.get_msg()
142 for i in range(5):
132 if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"]:
143 if self.km.xreq_channel.was_called():
133 if self.msg_xreq["content"]["status"] == 'ok' :
144 self.msg_xreq = self.km.xreq_channel.get_msg()
134 if self.msg_xreq["msg_type"] == "execute_reply" :
145 if self.msg_header["session"] == self.msg_xreq["parent_header"]["session"] :
135 self.handle_sub_channel()
146 if self.msg_xreq["content"]["status"] == 'ok' :
136 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
147 if self.msg_xreq["msg_type"] == "execute_reply" :
137
148 self.handle_sub_channel()
138 else:
149 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
139 etb = self.msg_xreq["content"]["traceback"]
150
140 print >> sys.stderr, etb[0]
151 else:
141 try: # These bits aren't there for a SyntaxError
152 etb = self.msg_xreq["content"]["traceback"]
142 print >> sys.stderr, etb[1]
153 print >> sys.stderr, etb[0]
143 print >> sys.stderr, etb[2]
154 print >> sys.stderr, etb[1]
144 except IndexError:
155 print >> sys.stderr, etb[2]
145 pass
156 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
146 self.prompt_count = self.msg_xreq["content"]["execution_count"]+1
157 break
158 time.sleep(0.1)
159
147
160
148
161 def handle_sub_channel(self):
149 def handle_sub_channel(self):
162 """ Method to procces subscribe channel's messages
150 """ Method to procces subscribe channel's messages
163
151
164 This method reads a message and processes the content in different
152 This method reads a message and processes the content in different
165 outputs like stdout, stderr, pyout and status
153 outputs like stdout, stderr, pyout and status
166
154
167 Arguments:
155 Arguments:
168 sub_msg: message receive from kernel in the sub socket channel
156 sub_msg: message receive from kernel in the sub socket channel
169 capture by kernel manager.
157 capture by kernel manager.
170 """
158 """
171 while self.km.sub_channel.was_called():
159 while self.km.sub_channel.msg_ready():
172 sub_msg = self.km.sub_channel.get_msg()
160 sub_msg = self.km.sub_channel.get_msg()
173 if self.msg_header["username"] == sub_msg['parent_header']['username'] and \
161 if self.msg_header["username"] == sub_msg['parent_header']['username'] and \
174 self.km.session.session == sub_msg['parent_header']['session']:
162 self.km.session.session == sub_msg['parent_header']['session']:
175 if sub_msg['msg_type'] == 'status' :
163 if sub_msg['msg_type'] == 'status' :
176 if sub_msg["content"]["execution_state"] == "busy" :
164 if sub_msg["content"]["execution_state"] == "busy" :
177 pass
165 pass
178
166
179 if sub_msg['msg_type'] == 'stream' :
167 if sub_msg['msg_type'] == 'stream' :
180 if sub_msg["content"]["name"] == "stdout":
168 if sub_msg["content"]["name"] == "stdout":
181 print >> sys.stdout,sub_msg["content"]["data"]
169 print >> sys.stdout,sub_msg["content"]["data"]
182 sys.stdout.flush()
170 sys.stdout.flush()
183 if sub_msg["content"]["name"] == "stderr" :
171 if sub_msg["content"]["name"] == "stderr" :
184 print >> sys.stderr,sub_msg["content"]["data"]
172 print >> sys.stderr,sub_msg["content"]["data"]
185 sys.stderr.flush()
173 sys.stderr.flush()
186
174
187 if sub_msg['msg_type'] == 'pyout' :
175 if sub_msg['msg_type'] == 'pyout' :
188 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
176 print >> sys.stdout,"Out[%i]:"%sub_msg["content"]["execution_count"], sub_msg["content"]["data"]["text/plain"]
189 sys.stdout.flush()
177 sys.stdout.flush()
190
178
191 def handle_rep_channel(self):
179 def handle_rep_channel(self, timeout=0.1):
192 """ Method to capture raw_input
180 """ Method to capture raw_input
193 """
181 """
194 if self.km.rep_channel.was_called() :
182 self.msg_rep = self.km.rep_channel.get_msg(timeout=timeout)
195 self.msg_rep = self.km.rep_channel.get_msg()
183 if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
196 if self.msg_header["session"] == self.msg_rep["parent_header"]["session"] :
184 raw_data = raw_input(self.msg_rep["content"]["prompt"])
197 raw_data = raw_input(self.msg_rep["content"]["prompt"])
185 self.km.rep_channel.input(raw_data)
198 self.km.rep_channel.input(raw_data)
199
186
200
187
201
188
202
189
203 def start_frontend():
190 def start_frontend():
204 """ Entry point for application.
191 """ Entry point for application.
205
192
206 """
193 """
207 # Parse command line arguments.
194 # Parse command line arguments.
208 parser = ArgumentParser()
195 parser = ArgumentParser()
209 kgroup = parser.add_argument_group('kernel options')
196 kgroup = parser.add_argument_group('kernel options')
210 kgroup.add_argument('-e', '--existing', action='store_true',
197 kgroup.add_argument('-e', '--existing', action='store_true',
211 help='connect to an existing kernel')
198 help='connect to an existing kernel')
212 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
199 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
213 help=\
200 help=\
214 "set the kernel\'s IP address [default localhost].\
201 "set the kernel\'s IP address [default localhost].\
215 If the IP address is something other than localhost, then \
202 If the IP address is something other than localhost, then \
216 Consoles on other machines will be able to connect\
203 Consoles on other machines will be able to connect\
217 to the Kernel, so be careful!")
204 to the Kernel, so be careful!")
218 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
205 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
219 help='set the XREQ channel port [default random]')
206 help='set the XREQ channel port [default random]')
220 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
207 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
221 help='set the SUB channel port [default random]')
208 help='set the SUB channel port [default random]')
222 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
209 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
223 help='set the REP channel port [default random]')
210 help='set the REP channel port [default random]')
224 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
211 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
225 help='set the heartbeat port [default random]')
212 help='set the heartbeat port [default random]')
226
213
227 egroup = kgroup.add_mutually_exclusive_group()
214 egroup = kgroup.add_mutually_exclusive_group()
228 egroup.add_argument('--pure', action='store_true', help = \
215 egroup.add_argument('--pure', action='store_true', help = \
229 'use a pure Python kernel instead of an IPython kernel')
216 'use a pure Python kernel instead of an IPython kernel')
230 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
217 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
231 const='auto', help = \
218 const='auto', help = \
232 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
219 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
233 given, the GUI backend is matplotlib's, otherwise use one of: \
220 given, the GUI backend is matplotlib's, otherwise use one of: \
234 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
221 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
235 egroup.add_argument('--colors', type=str,
222 egroup.add_argument('--colors', type=str,
236 help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
223 help="Set the color scheme (LightBG,Linux,NoColor). This is guessed\
237 based on the pygments style if not set.")
224 based on the pygments style if not set.")
238
225
239 args = parser.parse_args()
226 args = parser.parse_args()
240
227
241 # parse the colors arg down to current known labels
228 # parse the colors arg down to current known labels
242 if args.colors:
229 if args.colors:
243 colors=args.colors.lower()
230 colors=args.colors.lower()
244 if colors in ('lightbg', 'light'):
231 if colors in ('lightbg', 'light'):
245 colors='lightbg'
232 colors='lightbg'
246 elif colors in ('dark', 'linux'):
233 elif colors in ('dark', 'linux'):
247 colors='linux'
234 colors='linux'
248 else:
235 else:
249 colors='nocolor'
236 colors='nocolor'
250 else:
237 else:
251 colors=None
238 colors=None
252
239
253 # Create a KernelManager and start a kernel.
240 # Create a KernelManager and start a kernel.
254 kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
241 kernel_manager = KernelManager(xreq_address=(args.ip, args.xreq),
255 sub_address=(args.ip, args.sub),
242 sub_address=(args.ip, args.sub),
256 rep_address=(args.ip, args.rep),
243 rep_address=(args.ip, args.rep),
257 hb_address=(args.ip, args.hb))
244 hb_address=(args.ip, args.hb))
258 if not args.existing:
245 if not args.existing:
259 # if not args.ip in LOCAL_IPS+ALL_ALIAS:
246 # if not args.ip in LOCAL_IPS+ALL_ALIAS:
260 # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
247 # raise ValueError("Must bind a local ip, such as: %s"%LOCAL_IPS)
261
248
262 kwargs = dict(ip=args.ip)
249 kwargs = dict(ip=args.ip)
263 if args.pure:
250 if args.pure:
264 kwargs['ipython']=False
251 kwargs['ipython']=False
265 else:
252 else:
266 kwargs['colors']=colors
253 kwargs['colors']=colors
267 if args.pylab:
254 if args.pylab:
268 kwargs['pylab']=args.pylab
255 kwargs['pylab']=args.pylab
269 kernel_manager.start_kernel(**kwargs)
256 kernel_manager.start_kernel(**kwargs)
270
257
271
258
272 kernel_manager.start_channels()
259 kernel_manager.start_channels()
273 time.sleep(4)
274
260
275 frontend=Frontend(kernel_manager)
261 frontend=Frontend(kernel_manager)
276 return frontend
262 return frontend
277
263
278 if __name__ == "__main__" :
264 if __name__ == "__main__" :
279 frontend=start_frontend()
265 frontend=start_frontend()
280 frontend.start()
266 frontend.start()
@@ -1,129 +1,152 b''
1 """Implement a fully blocking kernel manager.
1 """Implement a fully blocking kernel manager.
2
2
3 Useful for test suites and blocking terminal interfaces.
3 Useful for test suites and blocking terminal interfaces.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2010-2011 The IPython Development Team
6 # Copyright (C) 2010-2011 The IPython Development Team
7 #
7 #
8 # Distributed under the terms of the BSD License. The full license is in
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING.txt, distributed as part of this software.
9 # the file COPYING.txt, distributed as part of this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from __future__ import print_function
15 from __future__ import print_function
16
16
17 # Stdlib
17 # Stdlib
18 from Queue import Queue, Empty
18 from Queue import Queue, Empty
19 from threading import Event
19
20
20 # Our own
21 # Our own
21 from IPython.utils import io
22 from IPython.utils import io
22 from IPython.utils.traitlets import Type
23 from IPython.utils.traitlets import Type
23
24
24 from .kernelmanager import (KernelManager, SubSocketChannel, HBSocketChannel,
25 from .kernelmanager import (KernelManager, SubSocketChannel, HBSocketChannel,
25 ShellSocketChannel, StdInSocketChannel)
26 ShellSocketChannel, StdInSocketChannel)
26
27
27 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
28 # Functions and classes
29 # Functions and classes
29 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
30
31
31 class BlockingSubSocketChannel(SubSocketChannel):
32 class BlockingSubSocketChannel(SubSocketChannel):
32
33
33 def __init__(self, context, session, address=None):
34 def __init__(self, context, session, address=None):
34 super(BlockingSubSocketChannel, self).__init__(context, session,
35 super(BlockingSubSocketChannel, self).__init__(context, session,
35 address)
36 address)
36 self._in_queue = Queue()
37 self._in_queue = Queue()
37
38
38 def call_handlers(self, msg):
39 def call_handlers(self, msg):
39 #io.rprint('[[Sub]]', msg) # dbg
40 #io.rprint('[[Sub]]', msg) # dbg
40 self._in_queue.put(msg)
41 self._in_queue.put(msg)
41
42
42 def msg_ready(self):
43 def msg_ready(self):
43 """Is there a message that has been received?"""
44 """Is there a message that has been received?"""
44 if self._in_queue.qsize() == 0:
45 if self._in_queue.qsize() == 0:
45 return False
46 return False
46 else:
47 else:
47 return True
48 return True
48
49
49 def get_msg(self, block=True, timeout=None):
50 def get_msg(self, block=True, timeout=None):
50 """Get a message if there is one that is ready."""
51 """Get a message if there is one that is ready."""
51 if block and timeout is None:
52 if block and timeout is None:
52 # never use timeout=None, because get
53 # never use timeout=None, because get
53 # becomes uninterruptible
54 # becomes uninterruptible
54 timeout = 1e6
55 timeout = 1e6
55 return self._in_queue.get(block, timeout)
56 return self._in_queue.get(block, timeout)
56
57
57 def get_msgs(self):
58 def get_msgs(self):
58 """Get all messages that are currently ready."""
59 """Get all messages that are currently ready."""
59 msgs = []
60 msgs = []
60 while True:
61 while True:
61 try:
62 try:
62 msgs.append(self.get_msg(block=False))
63 msgs.append(self.get_msg(block=False))
63 except Empty:
64 except Empty:
64 break
65 break
65 return msgs
66 return msgs
66
67
67
68
68 class BlockingShellSocketChannel(ShellSocketChannel):
69 class BlockingShellSocketChannel(ShellSocketChannel):
69
70
70 def __init__(self, context, session, address=None):
71 def __init__(self, context, session, address=None):
71 super(BlockingShellSocketChannel, self).__init__(context, session,
72 super(BlockingShellSocketChannel, self).__init__(context, session,
72 address)
73 address)
73 self._in_queue = Queue()
74 self._in_queue = Queue()
74
75
75 def call_handlers(self, msg):
76 def call_handlers(self, msg):
76 #io.rprint('[[Shell]]', msg) # dbg
77 #io.rprint('[[Shell]]', msg) # dbg
77 self._in_queue.put(msg)
78 self._in_queue.put(msg)
78
79
79 def msg_ready(self):
80 def msg_ready(self):
80 """Is there a message that has been received?"""
81 """Is there a message that has been received?"""
81 if self._in_queue.qsize() == 0:
82 if self._in_queue.qsize() == 0:
82 return False
83 return False
83 else:
84 else:
84 return True
85 return True
85
86
86 def get_msg(self, block=True, timeout=None):
87 def get_msg(self, block=True, timeout=None):
87 """Get a message if there is one that is ready."""
88 """Get a message if there is one that is ready."""
88 if block and timeout is None:
89 if block and timeout is None:
89 # never use timeout=None, because get
90 # never use timeout=None, because get
90 # becomes uninterruptible
91 # becomes uninterruptible
91 timeout = 1e6
92 timeout = 1e6
92 return self._in_queue.get(block, timeout)
93 return self._in_queue.get(block, timeout)
93
94
94 def get_msgs(self):
95 def get_msgs(self):
95 """Get all messages that are currently ready."""
96 """Get all messages that are currently ready."""
96 msgs = []
97 msgs = []
97 while True:
98 while True:
98 try:
99 try:
99 msgs.append(self.get_msg(block=False))
100 msgs.append(self.get_msg(block=False))
100 except Empty:
101 except Empty:
101 break
102 break
102 return msgs
103 return msgs
103
104
104
105
105 class BlockingStdInSocketChannel(StdInSocketChannel):
106 class BlockingStdInSocketChannel(StdInSocketChannel):
106
107
108 def __init__(self, context, session, address=None):
109 super(BlockingRepSocketChannel, self).__init__(context, session, address)
110 self._in_queue = Queue()
111
107 def call_handlers(self, msg):
112 def call_handlers(self, msg):
108 #io.rprint('[[Rep]]', msg) # dbg
113 #io.rprint('[[Rep]]', msg) # dbg
109 pass
114 self._in_queue.put(msg)
115
116 def get_msg(self, block=True, timeout=None):
117 "Gets a message if there is one that is ready."
118 return self._in_queue.get(block, timeout)
119
120 def get_msgs(self):
121 """Get all messages that are currently ready."""
122 msgs = []
123 while True:
124 try:
125 msgs.append(self.get_msg(block=False))
126 except Empty:
127 break
128 return msgs
129
130 def msg_ready(self):
131 "Is there a message that has been received?"
132 return not self._in_queue.empty()
110
133
111
134
112 class BlockingHBSocketChannel(HBSocketChannel):
135 class BlockingHBSocketChannel(HBSocketChannel):
113
136
114 # This kernel needs rapid monitoring capabilities
137 # This kernel needs rapid monitoring capabilities
115 time_to_dead = 0.2
138 time_to_dead = 0.2
116
139
117 def call_handlers(self, since_last_heartbeat):
140 def call_handlers(self, since_last_heartbeat):
118 #io.rprint('[[Heart]]', since_last_heartbeat) # dbg
141 #io.rprint('[[Heart]]', since_last_heartbeat) # dbg
119 pass
142 pass
120
143
121
144
122 class BlockingKernelManager(KernelManager):
145 class BlockingKernelManager(KernelManager):
123
146
124 # The classes to use for the various channels.
147 # The classes to use for the various channels.
125 shell_channel_class = Type(BlockingShellSocketChannel)
148 shell_channel_class = Type(BlockingShellSocketChannel)
126 sub_channel_class = Type(BlockingSubSocketChannel)
149 sub_channel_class = Type(BlockingSubSocketChannel)
127 stdin_channel_class = Type(BlockingStdInSocketChannel)
150 stdin_channel_class = Type(BlockingStdInSocketChannel)
128 hb_channel_class = Type(BlockingHBSocketChannel)
151 hb_channel_class = Type(BlockingHBSocketChannel)
129
152
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now