def METHOD_NAME(self, logname, data):
    # add data to the buffer for logname
    # keep appending to self._buffered until it gets longer than BUFFER_SIZE
    # which requires emptying the buffer by sending the message to the master
    is_log_message = logname in ("log", "stdout", "stderr", "header")
    if not is_log_message:
        len_data = 20
    else:
        if logname == "log":
            # different data format, when logname is 'log'
            # e.g. data = ('test_log', ('hello\n', [5], [0.0]))
            len_data = len(data[1][0]) + 8 * (len(data[1][1]) + len(data[1][2]))
        else:
            len_data = len(data[0]) + 8 * (len(data[1]) + len(data[2]))
    space_left = self._buffer_size - self._buflen
    if len_data <= space_left:
        # fills the buffer with short lines
        if not is_log_message:
            self._buffered.METHOD_NAME((logname, data))
        else:
            self.buffered_append_maybe_join_lines(logname, data)
        self._buflen += len_data
        self.setup_timeout()
        return
    self.send_message_from_buffer()
    if len_data <= self._buffer_size:
        self._buffered.METHOD_NAME((logname, data))
        self._buflen += len_data
        self.setup_timeout()
        return
    if not is_log_message:
        self.send_message([(logname, data)])
        return
    if logname == "log":
        log = data[0]
        data = data[1]
    pos_start = 0
    while pos_start < len(data[1]):
        # pos_end: which line is the last to be sent as a message (non-inclusive range)
        pos_end = pos_start + 1
        # Finds the range of lines to be sent:
        # pos_start - inclusive index of first line to be sent
        # pos_end - exclusive index of last line to be sent
        while pos_end <= len(data[1]):
            if pos_start == 0:
                string_part_size = data[1][pos_end - 1] + 1
            else:
                string_part_size = data[1][pos_end - 1] - (data[1][pos_start - 1])
            index_list_part_size = (pos_end - pos_start) * 8
            times_list_part_size = (pos_end - pos_start) * 8
            line_size = string_part_size + index_list_part_size + times_list_part_size
            if line_size <= self._buffer_size:
                pos_end += 1
            else:
                if pos_end > pos_start + 1:
                    pos_end -= 1
                break
        if pos_end > len(data[1]):
            # no more lines are left to grab
            pos_end -= 1
        pos_substring_end = data[1][pos_end - 1] + 1
        if pos_start != 0:
            pos_substring_start = data[1][pos_start - 1] + 1
            line_info = (data[0][pos_substring_start:pos_substring_end],
                         [index - pos_substring_start for index in data[1][pos_start:pos_end]],
                         data[2][pos_start: pos_end])
        else:
            line_info = (data[0][:pos_substring_end],
                         data[1][:pos_end],
                         data[2][:pos_end])
        if logname == "log":
            msg_data = (log, line_info)
        else:
            msg_data = line_info
        self.send_message([(logname, msg_data)])
        pos_start = pos_end