<commit_before>"""
Utility functions for dhcp2nest
"""
from queue import Queue
from subprocess import Popen, PIPE
from threading import Thread


def follow_file(fn, max_lines=100):
    """
    Return a Queue that is fed lines (up to max_lines) from the given file (fn)
    continuously

    The implementation given here was inspired by
    http://stackoverflow.com/questions/12523044/how-can-i-tail-a-log-file-in-python
    """
    fq = Queue(maxsize=max_lines)

    def _follow_file_thread(fn, fq):
        """
        Queue lines from the given file (fn) continuously, even as the file
        grows or is replaced

        WARNING: This generator will block forever on the tail subprocess--no
        timeouts are enforced.
        """
        # Use system tail with name-based following and retry
        p = Popen(["tail", "-n0", "-F", fn], stdout=PIPE)

        # Loop forever on pulling data from tail
        line = True
        while line:
            line = p.stdout.readline().decode('utf-8')
            fq.put(line)

    # Spawn a thread to read data from tail
    Thread(target=_follow_file_thread, args=(fn, fq)).start()

    # Return the queue
    return fq
<commit_msg>Use daemon threads for follow_file()<commit_after>"""
Utility functions for dhcp2nest
"""
from queue import Queue
from subprocess import Popen, PIPE
from threading import Thread


def follow_file(fn, max_lines=100):
    """
    Return a Queue that is fed lines (up to max_lines) from the given file (fn)
    continuously

    The implementation given here was inspired by
    http://stackoverflow.com/questions/12523044/how-can-i-tail-a-log-file-in-python
    """
    fq = Queue(maxsize=max_lines)

    def _follow_file_thread(fn, fq):
        """
        Queue lines from the given file (fn) continuously, even as the file
        grows or is replaced

        WARNING: This generator will block forever on the tail subprocess--no
        timeouts are enforced.
        """
        # Use system tail with name-based following and retry
        p = Popen(["tail", "-n0", "-F", fn], stdout=PIPE)

        # Loop forever on pulling data from tail
        line = True
        while line:
            line = p.stdout.readline().decode('utf-8')
            fq.put(line)

    # Spawn a thread to read data from tail
    Thread(target=_follow_file_thread, args=(fn, fq), daemon=True).start()

    # Return the queue
    return fq

{'fraction_non_alphanumeric': 0.0937759336099585, 'fraction_numerical': 0.011618257261410789, 'mean_word_length': 2.62012012012012, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2048736', 'n_tokens_mistral': 738, 'n_tokens_neox': 705, 'n_words': 251}