+ def caught_send(socket, message):
+ """Send message by socket, catch broken socket connection error."""
+ try:
+ plom_socket_io.send(socket, message)
+ except plom_socket_io.BrokenSocketConnection:
+ pass
+
+ def send_counter_loop(socket, counter, kill):
+ """Every 5 seconds, send state of counter[0] until kill[0] set."""
+ while not kill[0]:
+ caught_send(socket, 'COUNTER ' + str(counter[0]))
+ time.sleep(5)
+
+ def handle_message(message):
+ """Evaluate message for tasks to perform, yield result.
+
+ Accepts one command: FIB, followed by positive integers, all tokens
+ separated by whitespace. Will calculate and return for each such
+ integer n the n-th Fibonacci number. Uses multiprocessing to
+ perform multiple such calculations in parallel. Yields a
+ 'CALCULATING …' message before the calculation starts, and finally
+ yields a message containing the results. (The 'CALCULATING …'
+ message coming before the results message is currently the main
+ reason this works as a generator function using yield.)
+
+ When no command can be read into the message, just yields a 'NO
+ COMMAND UNDERSTOOD:', followed by the message.
+ """
+ from multiprocessing import Pool
+ tokens = message.split(' ')
+ if tokens[0] == 'FIB':
+ msg_fail_fib = 'MALFORMED FIB REQUEST'
+ if len(tokens) < 2:
+ yield msg_fail_fib
+ return
+ numbers = []
+ for token in tokens[1:]:
+ if token != '0' and token.isdigit():
+ numbers += [int(token)]
+ elif token == '':
+ continue
+ else:
+ yield msg_fail_fib
+ return
+ yield 'CALCULATING …'
+ reply = ''
+ with Pool(len(numbers)) as p:
+ results = p.map(fib, numbers)
+ reply = ' '.join([str(r) for r in results])
+ yield reply
+ return
+ yield 'NO COMMAND UNDERSTOOD: %s' % message