def logic(self):
        try:
            # Ждем коннекта
            connection, client_address = self.socket.accept()
        except socket.timeout:
            return

        # Получаем запрос
        key = connection.recv(128)
        log.debug('Coordinator receives: %s' % key)

        # Получаем значение подстановки из своего словаря
        try:
            reply = self.substitution[key]
        # Или генерируем случайное, если его нет
        except KeyError:
            reply = str(random.randint(1, 1024))
            self.substitution[key] = reply
            log.debug('New substitution created: %s -> %s' % (key, reply))

        # Засылаем ответ
        try:
            # Вот вам и разница между питонами!
            # Сработает в python2:
            connection.send(reply)
        except TypeError:
            # сработает в python3:
            connection.send(bytes(reply, 'utf-8'))

        # Закрываем соединение
        connection.close()
 def run(self):
     log.debug('%s: starting...' % self.name)
     while not self.stopped:
         self.logic()
     else:
         self.shut_down()
     log.debug('%s: stopping...' % self.name)
    def run(self):
        log.debug('Manager started.')
        # получаем асинхронный итератор по результатам
        results = self.pool.imap_unordered(self.worker,
                                           self.input)
        # и возвращаем их
        for item in results:
            self.output.put(item)

        log.debug('Manager finished.')
 def __next__(self):
     while not self.stopped:
         try:
             next_item = self.queue.get(True, 1)
         except Empty:
             pass
         else:
             log.debug('Next item in queue: %s ' % str(next_item))
             return next_item
     else:
         log.debug('Queue iteration stopped by external command')
         raise StopIteration
    def __init__(self, source_filename, target_queue):
        """
        :param source_filename: имя файла, который будет считан
        :type source_filename: str
        :param target_queue: очередь, в которую будут помещены задания
        :type target_queue: Queue.Queue
        """
        threading.Thread.__init__(self)
        self.filename = source_filename
        self.queue = target_queue

        log.debug('Reader parameters: filename = %s; queue = %s' % (self.filename,
                                                                    self.queue))
 def __init__(self, source, target, sock_address):
     """
     :param source: Iterable по входным параметрам
     :param target: очередь, в которую будут размещаться результаты
     :type target: Queue.Queue
     :param sock_address: адрес сокета, на котором расположен координатор
     :type sock_address: str
     """
     threading.Thread.__init__(self)
     self.input = source
     self.output = target
     self.worker = Worker(sock_address)
     self.pool = mp.Pool(get_core_num())
     log.debug('Manager initialized.')
    def logic(self):
        try:
            # запрос get() выполняется с параметрами blocking=True и timeout=1
            # это значит, что если очередь пуста, выполнение будет приостановлено
            # на время до 1 секунды, если за это время не появятся элементы в
            # очереди, будет сгенерировано исключение Empty()
            seq, line = self.queue.get(True, 1)
        except Empty:
            # Мы не собираемся ничего особого предпринимать, если очередь долго
            # пуста. Нам лишь нужно переодически выходить из ожидания, чтобы не
            # пропустить момент завершения программы
            pass
        else:
            log.debug('Position: %s Line: %s' % (seq, line))
            self.buffer.append((seq, line))

        if len(self.buffer) == self.dump_threshold:
            self.dump_to_disk()
    def run(self):
        log.debug('Reader started.')

        with open(self.filename, 'r') as f:

            # index - это номер строки (начиная с 1)
            for index, line in enumerate(f):
                log.debug('Reading line %s: %s' % (index, line.rstrip()))

                # Параметры block=True и timeout=None нужны для обработки ситуации,
                # когда очередь достигла максимального размера.
                # В такое комбинации эта thread будет приостановлена до тех пор,
                # пока в очереди не появится место.
                self.queue.put((index, line), block=True, timeout=None)

        log.debug('Reader finished.')
    def start(self):
        # запускаем их все и надеемся, что взлетим...
        for component_instance in self.components.values():
            component_instance.start()
        log.info('Components started.')

        # ждем пока дочитается файл
        self.components['reader'].join()
        log.info('Reached end of input file.')
        log.debug('Reader alive: %s' % self.components['reader'].is_alive())

        # ждем пока рабочие разберут все задачи из очереди
        while not self.jobs_queue.empty():
            time.sleep(1)
        log.debug('Jobs queue is empty.')

        # тормозим итератор задач
        self.jobs_iter.stop()
        log.debug('Stopping jobs iterator.')

        # ждем пока остановится менеджер
        self.components['manager'].join()
        log.info('Manager finished.')
        log.debug('Manager alive: %s' % self.components['manager'].is_alive())

        # останавливаем остальные компоненты
        log.debug('Trying to stop writer.')
        self.components['writer'].stop()
        log.debug('Trying to stop coordinator.')
        self.components['coordinator'].stop()
        time.sleep(2)
        log.debug('Writer alive: %s' % self.components['writer'].is_alive())
        log.debug('Coordinator alive: %s' % self.components['coordinator'].is_alive())

        log.info('All components stopped.')

        # если сюда добрались - значит все ОК и код возврата = 0
        return 0
    from Queue import Empty
except ImportError:
    # python 3
    from queue import Empty

from obfuscation.log import log
from obfuscation.thread_reader import Reader
from obfuscation.thread_writer import Writer
from obfuscation.thread_coordinator import Coordinator
from obfuscation.thread_manager import Manager

######################### Проверка окружения ###################################
# Данная версия скрипта взлетит только в Linux-системах.
# Потому что для кросплатформенности нужно кучу всего предусматривать, ну ее
# нафиг пока что.
log.debug('Platform: %s' % sys.platform)
if not sys.platform.startswith('linux'):
    raise RuntimeError('Sorry. This script works only on Linux.')

# Конфликты между вторым и третьим питоном тоже могут быть, нам следует быть
# более конкретными в нашем коде
log.debug('Python version: %s' % sys.version)
is_py3 = sys.version_info.major == 3
log.debug('Python 3 interpreter detected: %s' % is_py3)

################################ Константы #####################################
INPUT_FILE = 'dutylog'
OUTPUT_FILE = 'cleanlog'

# Для того, чтобы все дети делали замены согласованно, управление этим
# процессом должно быть централизовано в одном месте.
 def stop(self):
     log.debug('%s: got stop request.' % self.name)
     self.stopped = True
 def __init__(self):
     threading.Thread.__init__(self)
     log.debug('%s: initialisation...' % self.name)
     self.stopped = False