code: def spawn_reader_writer(get_data_fn, put_data_fn):
      
      def _reader_thread():
          while True:
              out = get_data_fn()
              put_data_fn(out)
              if not out:
                  # EOF.
                  # We've passed this on so things farther down the pipeline will
                  # know to shut down.
                  break
  
      t = threading.Thread(target=_reader_thread)
      t.daemon = True
      t.start()
      return t
docs: Spawn a thread that reads from a data source and writes to a sink.
  
      The thread will terminate if it receives a Falsey value from the source.
  
      Args:
          get_data_fn: Data-reading function. Called repeatedly until it returns
              False-y to indicate that the thread should terminate.
          put_data_fn: Data-writing function.
      Returns: threading.Thread