def send_request(self, worker_class_or_function, args, on_receive=None):
        """
        Requests some work to be done by the backend. You can get notified of
        the work results by passing a callback (on_receive).

        :param worker_class_or_function: Worker class or function
        :param args: worker args, any Json serializable objects
        :param on_receive: an optional callback executed when we receive the
            worker's results. The callback will be called with one arguments:
            the results of the worker (object)

        :raise: backend.NotRunning if the backend process is not running.
        """
        if not self.running:
            try:
                # try to restart the backend if it crashed.
                self.start(self.server_script, interpreter=self.interpreter,
                           args=self.args)
            except AttributeError:
                pass  # not started yet
            finally:
                # caller should try again, later
                raise NotRunning()
        else:
            comm('sending request, worker=%r' % worker_class_or_function)
            # create a socket, the request will be send as soon as the socket
            # has connected
            socket = JsonTcpClient(
                self.editor, self._port, worker_class_or_function, args,
                on_receive=on_receive)
            socket.finished.connect(self._rm_socket)
            self._sockets.append(socket)
            # restart heartbeat timer
            self._heartbeat_timer.start()