code: def read_message(self):
          
          msg = ""
          num_blank_lines = 0
          while True:
              # readline will return trailing \n so that output is unambigious, we
              # should only have line == '' if we're at EOF
              with self._reader_lock:
                  line = self.input_stream.readline()
              if line == "end\n":
                  break
              elif line == "":
                  raise StormWentAwayError()
              elif line == "\n":
                  num_blank_lines += 1
                  if num_blank_lines % 1000 == 0:
                      log.warn(
                          "While trying to read a command or pending task "
                          "ID, Storm has instead sent %s '\\n' messages.",
                          num_blank_lines,
                      )
                  continue
  
              msg = "{}{}\n".format(msg, line[0:-1])
  
          try:
              return json.loads(msg)
          except Exception:
              log.error("JSON decode error for message: %r", msg, exc_info=True)
              raise
docs: The Storm multilang protocol consists of JSON messages followed by
          a newline and "end\n".
  
          All of Storm's messages (for either bolts or spouts) should be of the
          form::
  
              '<command or task_id form prior emit>\\nend\\n'
  
          Command example, an incoming Tuple to a bolt::
  
              '{ "id": "-6955786537413359385",  "comp": "1", "stream": "1", "task": 9, "tuple": ["snow white and the seven dwarfs", "field2", 3]}\\nend\\n'
  
          Command example for a spout to emit its next Tuple::
  
              '{"command": "next"}\\nend\\n'
  
          Example, the task IDs a prior emit was sent to::
  
              '[12, 22, 24]\\nend\\n'
  
          The edge case of where we read ``''`` from ``input_stream`` indicating
          EOF, usually means that communication with the supervisor has been
          severed.