EntropyOrg / p5-Devel-IPerl

:microscope::books: Perl5 language kernel for Jupyter <http://jupyter.org/>
http://p3rl.org/Devel::IPerl
93 stars 15 forks source link

Running notebook cells in rapid succession makes kernel unresponsive #93

Closed dlukes closed 3 years ago

dlukes commented 6 years ago

Say you have a notebook which contains several cells with a fairly slow computation, e.g.:

# In [1]:
sub factorial {
    my $num = shift;
    if ($num == 2) {
        return 2;
    } else {
        return $num * &factorial($num - 1);
    }
}

# adjust the factorial arguments if too slow on your machine,
# or not slow enough to trigger the issue

# In [2]:
factorial 1000000

# In [3]:
factorial 1000000

# In [4]:
factorial 1000000

Now try to run them all in quick succession, either by repeatedly pressing Shift+Enter without waiting for the previous cell to complete, or by selecting CellRun All from the menu. The kernel becomes unresponsive and has to be restarted.

tofjw commented 5 years ago

I suspect new coming message (or its event) is lost while cell is being executed. Following patch is working good on my environment.

diff -ur p5-Devel-IPerl/lib/Devel/IPerl/Kernel.pm p5-Devel-IPerl-mine/lib/Devel/IPerl/Kernel.pm
--- p5-Devel-IPerl/lib/Devel/IPerl/Kernel.pm    2019-07-04 18:06:18.000000000 +0900
+++ archive/p5-Devel-IPerl/lib/Devel/IPerl/Kernel.pm    2019-07-04 18:22:07.000000000 +0900
@@ -197,15 +197,16 @@
                my $async_socket =  Net::Async::ZMQ::Socket->new(
                        socket => $socket,
                        on_read_ready => sub {
+                         while (1) {
                                my @blobs;
                                while ( my $recvmsg = zmq_recvmsg( $socket, ZMQ_RCVMORE ) ) {
                                        my $msg = zmq_msg_data($recvmsg);
                                        push @blobs, $msg;
                                        #print "|$msg|", "\n"; #DEBUG
                                }
-                               if( @blobs ) {
-                                       $self->route_message(\@blobs, $socket);
-                               }
+                               last unless (@blobs);
+                               $self->route_message(\@blobs, $socket);
+                         }
                        },
                );
zmughal commented 3 years ago

@tofjw, I believe that is right, because the method that I'm using to connect ZMQ socket events to the event loop is the filehandle and for ZMQ, the filehandle is edge-triggered (https://funcptr.net/2012/09/10/zeromq---edge-triggered-notification/).

I'll give this a test.