Ejemplo n.º 1
0
    def fork_kernel(self, config, pipe, resource_limits):
        """ A function to be set as the target for the new kernel processes forked in ForkingKernelManager.start_kernel. This method forks and initializes a new kernel, uses the update_function to update the kernel's namespace, sets resource limits for the kernel, and sends kernel connection information through the Pipe object.

        :arg traitlets.config.loader config: kernel configuration
        :arg multiprocessing.Pipe pipe: a multiprocessing connection object which will send kernel ip, session, and port information to the other side
        :arg dict resource_limits: a dict with keys resource.RLIMIT_* (see config_default documentation for explanation of valid options) and values of the limit for the given resource to be set in the kernel process
        """
        os.setpgrp()
        logger = kernel_logger.getChild(str(uuid.uuid4())[:4])
        logger.debug("kernel forked; now starting and configuring")
        try:
            ka = IPKernelApp.instance(config=config, ip=config["ip"])
            ka.log.propagate = True
            ka.log_level = logger.level
            from namespace import InstrumentedNamespace
            ka.user_ns = InstrumentedNamespace()
            ka.initialize([])
        except:
            logger.exception("Error initializing IPython kernel")
            # FIXME: What's the point in proceeding after?!
        try:
            if self.update_function is not None:
                self.update_function(ka)
        except:
            logger.exception("Error configuring up kernel")
        logger.debug("finished updating")
        for r, limit in resource_limits.iteritems():
            resource.setrlimit(getattr(resource, r), (limit, limit))
        pipe.send({"ip": ka.ip, "key": ka.session.key, "shell_port": ka.shell_port,
                "stdin_port": ka.stdin_port, "hb_port": ka.hb_port, "iopub_port": ka.iopub_port})
        pipe.close()
        # The following line will erase JSON connection file with ports and
        # other numbers. Since we do not reuse the kernels, we don't really need
        # these files. And new kernels set atexit hook to delete the file, but
        # it does not get called, perhaps because kernels are stopped by system
        # signals. The result is accumulation of files leading to disk quota
        # issues AND attempts to use stale files to connect to non-existing
        # kernels that eventually crash the server. TODO: figure out a better
        # fix, perhaps kernels have to be stopped in a more gentle fashion?
        ka.cleanup_connection_file()
        # In order to show the correct code line when a (deprecation) warning
        # is triggered, we change the main module name and save user code to
        # a file with the same name.
        import sys
        sys.argv = ['sagemathcell.py']
        old_execute = ka.kernel.do_execute
        import codecs
        
        def new_execute(code, *args, **kwds):
            with codecs.open('sagemathcell.py', 'w', encoding='utf-8') as f:
                f.write(code)
            return old_execute(code, *args, **kwds)
            
        ka.kernel.do_execute = new_execute
        ka.start()
Ejemplo n.º 2
0
    def fork_kernel(self, config, pipe, resource_limits):
        """ A function to be set as the target for the new kernel processes forked in ForkingKernelManager.start_kernel. This method forks and initializes a new kernel, uses the update_function to update the kernel's namespace, sets resource limits for the kernel, and sends kernel connection information through the Pipe object.

        :arg IPython.config.loader config: kernel configuration
        :arg multiprocessing.Pipe pipe: a multiprocessing connection object which will send kernel ip, session, and port information to the other side
        :arg dict resource_limits: a dict with keys resource.RLIMIT_* (see config_default documentation for explanation of valid options) and values of the limit for the given resource to be set in the kernel process
        """
        os.setpgrp()
        logger = kernel_logger.getChild(str(uuid.uuid4())[:4])
        logger.debug("kernel forked; now starting and configuring")
        try:
            ka = IPKernelApp.instance(config=config, ip=config["ip"])
            from namespace import InstrumentedNamespace
            ka.user_ns = InstrumentedNamespace()
            # The following line on UNIX systems (and we are unlikely to run on
            # Windows) will lead to creation of a 1-second poller that will kill
            # this process as soon as its parent dies. More importanly, it will
            # prevent from execution the following if block:
            # https://github.com/ipython/ipython/blob/rel-2.1.0/IPython/kernel/zmq/kernelapp.py#L348
            # which probably was filling some output buffer and used to severely
            # limit the number of computations possible without restarting the
            # server. TODO: figure out a better fix or confirm this is the one!
            ka.parent_handle = True
            ka.initialize([])
        except:
            logger.exception("Error initializing IPython kernel")
            # FIXME: What's the point in proceeding after?!
        try:
            if self.update_function is not None:
                self.update_function(ka)
        except:
            logger.exception("Error configuring up kernel")
        logger.debug("finished updating")
        for r, limit in resource_limits.iteritems():
            resource.setrlimit(getattr(resource, r), (limit, limit))
        pipe.send({
            "ip": ka.ip,
            "key": ka.session.key,
            "shell_port": ka.shell_port,
            "stdin_port": ka.stdin_port,
            "hb_port": ka.hb_port,
            "iopub_port": ka.iopub_port
        })
        pipe.close()
        # The following line will erase JSON connection file with ports and
        # other numbers. Since we do not reuse the kernels, we don't really need
        # these files. And new kernels set atexit hook to delete the file, but
        # it does not get called, perhaps because kernels are stopped by system
        # signals. The result is accumulation of files leading to disk quota
        # issues AND attempts to use stale files to connect to non-existing
        # kernels that eventually crash the server. TODO: figure out a better
        # fix, perhaps kernels have to be stopped in a more gentle fashion?
        ka.cleanup_connection_file()
        ka.start()
Ejemplo n.º 3
0
    def fork_kernel(self, config, pipe, resource_limits):
        """ A function to be set as the target for the new kernel processes forked in ForkingKernelManager.start_kernel. This method forks and initializes a new kernel, uses the update_function to update the kernel's namespace, sets resource limits for the kernel, and sends kernel connection information through the Pipe object.

        :arg IPython.config.loader config: kernel configuration
        :arg multiprocessing.Pipe pipe: a multiprocessing connection object which will send kernel ip, session, and port information to the other side
        :arg dict resource_limits: a dict with keys resource.RLIMIT_* (see config_default documentation for explanation of valid options) and values of the limit for the given resource to be set in the kernel process
        """
        os.setpgrp()
        logger = kernel_logger.getChild(str(uuid.uuid4())[:4])
        logger.debug("kernel forked; now starting and configuring")
        try:
            ka = IPKernelApp.instance(config=config, ip=config["ip"])
            from namespace import InstrumentedNamespace
            ka.user_ns = InstrumentedNamespace()
            # The following line on UNIX systems (and we are unlikely to run on
            # Windows) will lead to creation of a 1-second poller that will kill
            # this process as soon as its parent dies. More importanly, it will
            # prevent from execution the following if block:
            # https://github.com/ipython/ipython/blob/rel-2.1.0/IPython/kernel/zmq/kernelapp.py#L348
            # which probably was filling some output buffer and used to severely
            # limit the number of computations possible without restarting the
            # server. TODO: figure out a better fix or confirm this is the one!
            ka.parent_handle = True
            ka.initialize([])
        except:
            logger.exception("Error initializing IPython kernel")
            # FIXME: What's the point in proceeding after?!
        try:
            if self.update_function is not None:
                self.update_function(ka)
        except:
            logger.exception("Error configuring up kernel")
        logger.debug("finished updating")
        for r, limit in resource_limits.iteritems():
            resource.setrlimit(getattr(resource, r), (limit, limit))
        pipe.send({"ip": ka.ip, "key": ka.session.key, "shell_port": ka.shell_port,
                "stdin_port": ka.stdin_port, "hb_port": ka.hb_port, "iopub_port": ka.iopub_port})
        pipe.close()
        # The following line will erase JSON connection file with ports and
        # other numbers. Since we do not reuse the kernels, we don't really need
        # these files. And new kernels set atexit hook to delete the file, but
        # it does not get called, perhaps because kernels are stopped by system
        # signals. The result is accumulation of files leading to disk quota
        # issues AND attempts to use stale files to connect to non-existing
        # kernels that eventually crash the server. TODO: figure out a better
        # fix, perhaps kernels have to be stopped in a more gentle fashion?
        ka.cleanup_connection_file()
        ka.start()
Ejemplo n.º 4
0
    def fork_kernel(self, config, pipe, resource_limits):
        """The target for new processes in ForkingKernelManager.start_kernel.
       
        This method forks and initializes a new kernel, uses the update_function
        to update the kernel's namespace, sets resource limits for the kernel,
        and sends kernel connection information through the Pipe object.

        :arg traitlets.config.loader config: kernel configuration
        :arg multiprocessing.Pipe pipe: a pipe for sending kernel ip, session,
            and port information to the other side
        :arg dict resource_limits: a dictionary with keys resource.RLIMIT_*
            (see config_default documentation for explanation of valid options)
        """
        os.setpgrp()
        logger = kernel_logger.getChild(str(uuid.uuid4())[:4])
        logger.debug("kernel forked; now starting and configuring")
        try:
            ka = IPKernelApp.instance(config=config, ip=config["ip"])
            ka.log.propagate = True
            ka.log_level = logger.level
            from namespace import InstrumentedNamespace
            ka.user_ns = InstrumentedNamespace()
            ka.initialize([])
        except:
            logger.exception("error initializing IPython kernel")
            raise KernelError("error initializing IPython kernel")
        try:
            if self.update_function is not None:
                self.update_function(ka)
        except:
            logger.exception("error configuring up kernel")
            raise KernelError("error configuring up kernel")
        logger.debug("finished updating")
        for r, limit in resource_limits.iteritems():
            resource.setrlimit(getattr(resource, r), (limit, limit))
        pipe.send({
            "ip": ka.ip,
            "key": ka.session.key,
            "shell_port": ka.shell_port,
            "stdin_port": ka.stdin_port,
            "hb_port": ka.hb_port,
            "iopub_port": ka.iopub_port
        })
        pipe.close()
        # The following line will erase JSON connection file with ports and
        # other numbers. Since we do not reuse the kernels, we don't really need
        # these files. And new kernels set atexit hook to delete the file, but
        # it does not get called, perhaps because kernels are stopped by system
        # signals. The result is accumulation of files leading to disk quota
        # issues AND attempts to use stale files to connect to non-existing
        # kernels that eventually crash the server. TODO: figure out a better
        # fix, perhaps kernels have to be stopped in a more gentle fashion?
        ka.cleanup_connection_file()
        # In order to show the correct code line when a (deprecation) warning
        # is triggered, we change the main module name and save user code to
        # a file with the same name.
        import sys
        sys.argv = ['sagemathcell.py']
        old_execute = ka.kernel.do_execute
        import codecs

        def new_execute(code, *args, **kwds):
            with codecs.open('sagemathcell.py', 'w', encoding='utf-8') as f:
                f.write(code)
            return old_execute(code, *args, **kwds)

        ka.kernel.do_execute = new_execute
        ka.start()