Talk with a container. Sends the initial input. Allows to start student containers

async def handle_running_container(self, job_id, container_id, inputdata, debug, ports, orig_env,
                                       orig_memory_limit, orig_time_limit, orig_hard_time_limit, sockets_path,
                                       student_path, systemfiles_path, course_common_student_path, future_results):
        """ Talk with a container. Sends the initial input. Allows to start student containers """
        sock = await self._docker.attach_to_container(container_id)
        try:
            read_stream, write_stream = await asyncio.open_connection(sock=sock.get_socket())
        except asyncio.CancelledError:
            raise
        except:
            self._logger.exception("Exception occurred while creating read/write stream to container")
            return None

        # Send hello msg
        await self._write_to_container_stdin(write_stream, {"type": "start", "input": inputdata, "debug": debug})
        result = None

        buffer = bytearray()
        try:
            while not read_stream.at_eof():
                msg_header = await read_stream.readexactly(8)
                outtype, length = struct.unpack_from('>BxxxL', msg_header)  # format imposed by docker in the attach endpoint
                if length != 0:
                    content = await read_stream.readexactly(length)
                    if outtype == 1:  # stdout
                        buffer += content

                    if outtype == 2:  # stderr
                        self._logger.debug("Received stderr from containers:\n%s", content)

                    # 4 first bytes are the lenght of the message. If we have a complete message...
                    while len(buffer) > 4 and len(buffer) >= 4+struct.unpack('I',buffer[0:4])[0]:
                        msg_encoded = buffer[4:4 + struct.unpack('I', buffer[0:4])[0]]  # ... get it
                        buffer = buffer[4 + struct.unpack('I', buffer[0:4])[0]:]  # ... withdraw it from the buffer
                        try:
                            msg = msgpack.unpackb(msg_encoded, encoding="utf8", use_list=False)
                            self._logger.debug("Received msg %s from container %s", msg["type"], container_id)
                            if msg["type"] == "run_student":
                                # start a new student container
                                environment = msg["environment"] or orig_env
                                memory_limit = min(msg["memory_limit"] or orig_memory_limit, orig_memory_limit)
                                time_limit = min(msg["time_limit"] or orig_time_limit, orig_time_limit)
                                hard_time_limit = min(msg["hard_time_limit"] or orig_hard_time_limit, orig_hard_time_limit)
                                share_network = msg["share_network"]
                                socket_id = msg["socket_id"]
                                assert "/" not in socket_id  # ensure task creator do not try to break the agent :-(
                                self._create_safe_task(self.create_student_container(job_id, container_id, sockets_path, student_path,
                                                                                     systemfiles_path, course_common_student_path,
                                                                                     socket_id,  environment, memory_limit, time_limit,
                                                                                     hard_time_limit, share_network, write_stream))
                            elif msg["type"] == "ssh_key":
                                # send the data to the backend (and client)
                                self._logger.info("%s %s", container_id, str(msg))
                                await self.send_ssh_job_info(job_id, self._address_host, ports[22], msg["ssh_key"])
                            elif msg["type"] == "result":
                                # last message containing the results of the container
                                result = msg["result"]
                        except:
                            self._logger.exception("Received incorrect message from container %s (job id %s)", container_id, job_id)
        except asyncio.IncompleteReadError:
            self._logger.debug("Container output ended with an IncompleteReadError; It was probably killed.")
        except asyncio.CancelledError:
            write_stream.close()
            sock.close_socket()
            future_results.set_result(result)
            raise
        except:
            self._logger.exception("Exception while reading container %s output", container_id)

        write_stream.close()
        sock.close_socket()
        future_results.set_result(result)

        if not result:
            self._logger.warning("Container %s has not given any result", container_id)