def run_generator_for_training(self, websocket):
        if not self.is_generator:
            raise RuntimeError(
                "Method run_generator_for_training should only be called "
                "when a generator is being used.")

        message_count = 0
        while True:

            # Generators should just always send next data messages
            to_server = self.get_next_data_message()
            yield from websocket.send(to_server.SerializeToString())

            # Get a message from the server
            from_server_bytes = yield from websocket.recv()
            from_server = ServerToSimulator()
            from_server.ParseFromString(from_server_bytes)

            # Handle FINISHED and SET_PROPERTIES messages, otherwise
            # ignore the message.
            if (from_server.message_type == ServerToSimulator.SET_PROPERTIES):
                if not from_server.HasField("set_properties_data"):
                    raise RuntimeError(
                        "Received a SET_PROPERTIES message that did "
                        "not contain set_properties_data.")
                self.handle_set_properties(from_server.set_properties_data)
            elif from_server.message_type == ServerToSimulator.FINISHED:
                log.info("Training is finished!")
                return

            message_count += 1
            if message_count % 250 == 0:
                log.info("Handled %i messages from the server so far",
                         message_count)
    def recv_acknowledge_register(self, websocket):
        from_server_bytes = yield from websocket.recv()
        from_server = ServerToSimulator()
        from_server.ParseFromString(from_server_bytes)

        if from_server.message_type != ServerToSimulator.ACKNOWLEDGE_REGISTER:
            raise RuntimeError(
                "Expected to receive an ACKNOWLEDGE_REGISTER message, but "
                "instead received message of type {}".format(
                    from_server.message_type))

        if not from_server.HasField("acknowledge_register_data"):
            raise RuntimeError(
                "Received an ACKNOWLEDGE_REGISTER message that did "
                "not contain acknowledge_register_data.")

        # Reconstitute the simulator schemas.
        self.properties_schema = MessageBuilder().reconstitute(
            from_server.acknowledge_register_data.properties_schema)
        self.output_schema = MessageBuilder().reconstitute(
            from_server.acknowledge_register_data.output_schema)
        self.prediction_schema = MessageBuilder().reconstitute(
            from_server.acknowledge_register_data.prediction_schema)