# Buggy code
def _enforce_limits(self, **kw):
    """
    Enforces any limits that may be imposed by the configuration.
    """

    # if kernels-per-user is configured, ensure that this next kernel is still within the limit
    max_kernels_per_user = self.kernel_manager.parent.parent.max_kernels_per_user
    if max_kernels_per_user >= 0:
        env_dict = kw.get("env")
        username = env_dict["KERNEL_USERNAME"]
        current_kernel_count = (
            self.kernel_manager.parent.parent.kernel_session_manager.active_sessions(
                username
            )
        )
        if current_kernel_count >= max_kernels_per_user:
            error_message = (
                "A max kernels per user limit has been set to {} and user '{}' currently has {} "
                "active {}.".format(
                    max_kernels_per_user,
                    username,
                    current_kernel_count,
                    "kernel" if max_kernels_per_user == 1 else "kernels",
                )
            )
            self.log_and_raise(http_status_code=403, reason=error_message)


# Traceback (HTTPError)
[I 2018-05-08 15:50:53.686 EnterpriseGatewayApp] KernelRestarter: restarting kernel (1/5), keep random ports
[W 180508 15:50:53 handlers:465] kernel 2a96df20-5527-42f0-ae4f-884c99f624ae restarted
[D 2018-05-08 15:50:53.688 EnterpriseGatewayApp] RemoteKernelManager.signal_kernel(9)
[D 2018-05-08 15:50:53.688 EnterpriseGatewayApp] YarnClusterProcessProxy.send_signal 9
[D 2018-05-08 15:50:53.739 EnterpriseGatewayApp] YarnClusterProcessProxy.kill: kill_app_by_id(application_1525280245118_0073) response: {u'state': u'FAILED'}, confirming app state is not RUNNING
[D 2018-05-08 15:50:59.113 EnterpriseGatewayApp] Sending signal: 15 to target: 17033 on host: 172.16.163.194
[D 2018-05-08 15:50:59.493 EnterpriseGatewayApp] SIGTERM signal sent to pid: 17033
[D 2018-05-08 15:50:59.518 EnterpriseGatewayApp] YarnClusterProcessProxy.kill, application ID: application_1525280245118_0073, kernel ID: 2a96df20-5527-42f0-ae4f-884c99f624ae, state: FAILED
[D 2018-05-08 15:50:59.551 EnterpriseGatewayApp] cleanup: terminating CONTROL tunnel process.
[D 2018-05-08 15:50:59.652 EnterpriseGatewayApp] cleanup: terminating SHELL tunnel process.
[D 2018-05-08 15:50:59.753 EnterpriseGatewayApp] cleanup: terminating STDIN tunnel process.
[D 2018-05-08 15:50:59.854 EnterpriseGatewayApp] cleanup: terminating IOPUB tunnel process.
[D 2018-05-08 15:50:59.955 EnterpriseGatewayApp] cleanup: terminating HB tunnel process.
[D 2018-05-08 15:51:00.058 EnterpriseGatewayApp] cleanup: terminating EG_COMM tunnel process.
[D 2018-05-08 15:51:00.762 EnterpriseGatewayApp] Instantiating kernel 'Spark - R (YARN Cluster Mode)' with process proxy: enterprise_gateway.services.processproxies.yarn.YarnClusterProcessProxy
[D 2018-05-08 15:51:00.764 EnterpriseGatewayApp] Response socket launched on 172.16.159.125, port: 56438 using 5.0s timeout
[D 2018-05-08 15:51:00.765 EnterpriseGatewayApp] Starting kernel: [u'/usr/local/share/jupyter/kernels/spark_R_yarn_cluster/bin/run.sh', u'/home/elyra/.local/share/jupyter/runtime/kernel-2a96df20-5527-42f0-ae4f-884c99f624ae.json', u'--RemoteProcessProxy.response-address', u'172.16.159.125:56438', u'--RemoteProcessProxy.port-range', u'0..0', u'--RemoteProcessProxy.spark-context-initialization-mode', u'lazy']
[D 2018-05-08 15:51:00.765 EnterpriseGatewayApp] Launching kernel: Spark - R (YARN Cluster Mode) with command: [u'/usr/local/share/jupyter/kernels/spark_R_yarn_cluster/bin/run.sh', u'/home/elyra/.local/share/jupyter/runtime/kernel-2a96df20-5527-42f0-ae4f-884c99f624ae.json', u'--RemoteProcessProxy.response-address', u'172.16.159.125:56438', u'--RemoteProcessProxy.port-range', u'0..0', u'--RemoteProcessProxy.spark-context-initialization-mode', u'lazy']
[E 2018-05-08 15:51:00.765 EnterpriseGatewayApp] A max kernels per user limit has been set to 2 and user 'jovyan' currently has 2 active kernels.
[E 180508 15:51:00 ioloop:792] Exception in callback <bound method IOLoopKernelRestarter.poll of <jupyter_client.ioloop.restarter.IOLoopKernelRestarter object at 0x7fa4360f5c10>>
Traceback (most recent call last):
File "/opt/anaconda2/lib/python2.7/site-packages/tornado/ioloop.py", line 1208, in _run
return self.callback()
File "/opt/anaconda2/lib/python2.7/site-packages/jupyter_client/restarter.py", line 113, in poll
self.kernel_manager.restart_kernel(now=True, newports=newports)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/kernels/remotemanager.py", line 156, in restart_kernel
super(RemoteKernelManager, self).restart_kernel(now, **kw)
File "/opt/anaconda2/lib/python2.7/site-packages/jupyter_client/manager.py", line 368, in restart_kernel
self.start_kernel(**self._launch_args)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/kernels/remotemanager.py", line 102, in start_kernel
return super(RemoteKernelManager, self).start_kernel(**kw)
File "/opt/anaconda2/lib/python2.7/site-packages/jupyter_client/manager.py", line 259, in start_kernel
**kw)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/kernels/remotemanager.py", line 131, in _launch_kernel
return self.process_proxy.launch_process(kernel_cmd, **kw)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/processproxies/yarn.py", line 46, in launch_process
super(YarnClusterProcessProxy, self).launch_process(kernel_cmd, **kw)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/processproxies/processproxy.py", line 538, in launch_process
super(RemoteProcessProxy, self).launch_process(kernel_cmd, **kw)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/processproxies/processproxy.py", line 152, in launch_process
self._enforce_limits(**kw)
File "/opt/anaconda2/lib/python2.7/site-packages/enterprise_gateway/services/processproxies/processproxy.py", line 397, in _enforce_limits
raise tornado.web.HTTPError(403, reason=error_message)
HTTPError: HTTP 403: A max kernels per user limit has been set to 2 and user 'jovyan' currently has 2 active kernels.

# Fixed code
def _enforce_limits(self, **kw):
    """
    Enforces any limits that may be imposed by the configuration.
    """

    # if kernels-per-user is configured, ensure that this next kernel is still within the limit.  If this
    # is due to a restart, skip enforcement since we're re-using that id.
    max_kernels_per_user = self.kernel_manager.parent.parent.max_kernels_per_user
    if max_kernels_per_user >= 0 and not self.kernel_manager.restarting:
        env_dict = kw.get("env")
        username = env_dict["KERNEL_USERNAME"]
        current_kernel_count = (
            self.kernel_manager.parent.parent.kernel_session_manager.active_sessions(
                username
            )
        )
        if current_kernel_count >= max_kernels_per_user:
            error_message = (
                "A max kernels per user limit has been set to {} and user '{}' currently has {} "
                "active {}.".format(
                    max_kernels_per_user,
                    username,
                    current_kernel_count,
                    "kernel" if max_kernels_per_user == 1 else "kernels",
                )
            )
            self.log_and_raise(http_status_code=403, reason=error_message)