<commit_before>import argparse
from collections import Counter, defaultdict
import heapq
import numpy as np
import os
import ray
import wikipedia

parser = argparse.ArgumentParser()
parser.add_argument(
    "--num-mappers", help="number of mapper actors used", default=3, type=int)
parser.add_argument(
    "--num-reducers",
    help="number of reducer actors used",
    default=4,
    type=int)


@ray.remote
class Mapper(object):
    def __init__(self, title_stream):
        self.title_stream = title_stream
        self.num_articles_processed = 0
        self.articles = []
        self.word_counts = []

    def get_new_article(self):
        # Get the next wikipedia article.
        article = wikipedia.page(self.title_stream.next()).content
        # Count the words and store the result.
        self.word_counts.append(Counter(article.split(" ")))
        self.num_articles_processed += 1

    def get_range(self, article_index, keys):
        # Process more articles if this Mapper hasn't processed enough yet.
        while self.num_articles_processed < article_index + 1:
            self.get_new_article()
        # Return the word counts from within a given character range.
        return [(k, v) for k, v in self.word_counts[article_index].items()
                if len(k) >= 1 and k[0] >= keys[0] and k[0] <= keys[1]]


@ray.remote
class Reducer(object):
    def __init__(self, keys, *mappers):
        self.mappers = mappers
        self.keys = keys

    def next_reduce_result(self, article_index):
        word_count_sum = defaultdict(lambda: 0)
        # Get the word counts for this Reducer's keys from all of the Mappers
        # and aggregate the results.
        count_ids = [
            mapper.get_range.remote(article_index, self.keys)
            for mapper in self.mappers
        ]
        # TODO(rkn): We should process these out of order using ray.wait.
        for count_id in count_ids:
            for k, v in ray.get(count_id):
                word_count_sum[k] += v
        return word_count_sum


class Stream(object):
    def __init__(self, elements):
        self.elements = elements

    def next(self):
        i = np.random.randint(0, len(self.elements))
        return self.elements[i]


if __name__ == "__main__":
    args = parser.parse_args()

    ray.init()

    # Create one streaming source of articles per mapper.
    directory = os.path.dirname(os.path.realpath(__file__))
    streams = []<commit_msg>Update streaming example to use wait<commit_after>import argparse
from collections import Counter, defaultdict
import heapq
import numpy as np
import os
import ray
import wikipedia

parser = argparse.ArgumentParser()
parser.add_argument(
    "--num-mappers", help="number of mapper actors used", default=3, type=int)
parser.add_argument(
    "--num-reducers",
    help="number of reducer actors used",
    default=4,
    type=int)


@ray.remote
class Mapper(object):
    def __init__(self, title_stream):
        self.title_stream = title_stream
        self.num_articles_processed = 0
        self.articles = []
        self.word_counts = []

    def get_new_article(self):
        # Get the next wikipedia article.
        article = wikipedia.page(self.title_stream.next()).content
        # Count the words and store the result.
        self.word_counts.append(Counter(article.split(" ")))
        self.num_articles_processed += 1

    def get_range(self, article_index, keys):
        # Process more articles if this Mapper hasn't processed enough yet.
        while self.num_articles_processed < article_index + 1:
            self.get_new_article()
        # Return the word counts from within a given character range.
        return [(k, v) for k, v in self.word_counts[article_index].items()
                if len(k) >= 1 and k[0] >= keys[0] and k[0] <= keys[1]]


@ray.remote
class Reducer(object):
    def __init__(self, keys, *mappers):
        self.mappers = mappers
        self.keys = keys

    def next_reduce_result(self, article_index):
        word_count_sum = defaultdict(lambda: 0)
        # Get the word counts for this Reducer's keys from all of the Mappers
        # and aggregate the results.
        count_ids = [
            mapper.get_range.remote(article_index, self.keys)
            for mapper in self.mappers
        ]

        while len(count_ids) > 0:
            finished, unfinished = ray.wait(count_ids)
            for count_id in finished:
                for k, v in ray.get(count_id):
                    word_count_sum[k] += v
            count_ids = unfinished

        return word_count_sum


class Stream(object):
    def __init__(self, elements):
        self.elements = elements

    def next(self):
        i = np.random.randint(0, len(self.elements))
        return self.elements[i]


if __name__ == "__main__":
    args = parser.parse_args()

    ray.init()

    # Create one streaming source of articles per mapper.
    directory = os.path.dirname(os.path.realpath(__file__))
    streams = []
{'fraction_non_alphanumeric': 0.0964, 'fraction_numerical': 0.005, 'mean_word_length': 2.610830324909747, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 8, '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': '7570517', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1460, 'n_words': 425}