docs: def process_request(self, num_pending, ports, request_blocking=False):
          '''port is the open port at the worker, num_pending is the num_pending of stack.
          A non-zero num_pending means that the worker is pending on something while
          looking for new job, so the worker should not be killed.
          '''
          if any(port in self._step_requests for port in ports):
              # if the port is available
              port = [x for x in ports if x in self._step_requests][0]
              self._worker_backend_socket.send_pyobj(
                  self._step_requests.pop(port))
              self._n_processed += 1
              self.report(f'Step {port} processed')
              # port should be in claimed ports
              self._claimed_ports.remove(port)
              if ports[0] in self._last_pending_time:
                  self._last_pending_time.pop(ports[0])
          elif any(port in self._claimed_ports for port in ports):
              # the port is claimed, but the real message is not yet available
              self._worker_backend_socket.send_pyobj({})
              self.report(f'pending with claimed {ports}')
          elif any(port in self._blocking_ports for port in ports):
              # in block list but appear to be idle, kill it
              self._max_workers -= 1
              env.logger.debug(
                  f'Reduce maximum number of workers to {self._max_workers} after completion of a blocking subworkflow.'
              )
              for port in ports:
                  if port in self._blocking_ports:
                      self._blocking_ports.remove(port)
                  if port in self._available_ports:
                      self._available_ports.remove(port)
              self._worker_backend_socket.send_pyobj(None)
              self._num_workers -= 1
              self.report(f'Blocking worker {ports} killed')
          elif self._substep_requests:
              # port is not claimed, free to use for substep worker
              msg = self._substep_requests.pop()
              self._worker_backend_socket.send_pyobj(msg)
              self._n_processed += 1
              self.report(f'Substep processed with {ports[0]}')
              # port can however be in available ports
              for port in ports:
                  if port in self._available_ports:
                      self._available_ports.remove(port)
                  if port in self._last_pending_time:
                      self._last_pending_time.pop(port)
          elif request_blocking:
              self._worker_backend_socket.send_pyobj({})
              return ports[0]
          elif num_pending == 0 and ports[
                  0] in self._last_pending_time and time.time(
                  ) - self._last_pending_time[ports[0]] > 5:
              # kill the worker
              for port in ports:
                  if port in self._available_ports:
                      self._available_ports.remove(port)
              self._worker_backend_socket.send_pyobj(None)
              self._num_workers -= 1
              self.report(f'Kill standing {ports}')
              self._last_pending_time.pop(ports[0])
          else:
              if num_pending == 0 and ports[0] not in self._last_pending_time:
                  self._last_pending_time[ports[0]] = time.time()
              self._available_ports.add(ports[0])
              self._worker_backend_socket.send_pyobj({})
              ports = tuple(ports)
              if (ports, num_pending) not in self._last_pending_msg or time.time(
              ) - self._last_pending_msg[(ports, num_pending)] > 1.0:
                  self.report(
                      f'pending with port {ports} at num_pending {num_pending}')
                  self._last_pending_msg[(ports, num_pending)] = time.time()