def make_read_and_store_stream_func(execution_db, action_db, store_data_func):
    """
    Factory function which returns a function for reading from a stream (stdout / stderr).

    This function writes read data into a buffer and stores it in a database.
    """
    # NOTE: This import has intentionally been moved here to avoid massive performance overhead
    # (1+ second) for other functions inside this module which don't need to use those imports.
    from st2common.util import concurrency

    greenlet_exit_exc_cls = concurrency.get_greenlet_exit_exception_class()

    def read_and_store_stream(stream, buff):
        try:
            while not stream.closed:
                line = stream.readline()
                if not line:
                    break

                if isinstance(line, six.binary_type):
                    line = line.decode("utf-8")

                buff.write(line)

                # Filter out result delimiter lines
                if ACTION_OUTPUT_RESULT_DELIMITER in line:
                    continue

                if cfg.CONF.actionrunner.stream_output:
                    store_data_func(
                        execution_db=execution_db, action_db=action_db, data=line
                    )
        except RuntimeError:
            # process was terminated abruptly
            pass
        except greenlet_exit_exc_cls:
            # Green thread exited / was killed
            pass

    return read_and_store_stream

    Factory function which returns a function for reading from a stream (stdout / stderr).

    This function writes read data into a buffer and stores it in a database.
    
st2common/st2common/runners/utils.py