<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self, once=False, force_once=False):
 """ Main loop of the worker. Use once=True to execute any queued tasks and then exit. Use force_once=True with once=True to always exit after one processing loop even if tasks remain queued. """


        self.log.info('ready', id=self.id,
                               queues=sorted(self.only_queues),
                               exclude_queues=sorted(self.exclude_queues),
                               single_worker_queues=sorted(self.single_worker_queues),
                               max_workers=self.max_workers_per_queue)

        if not self.scripts.can_replicate_commands:
            # Older Redis versions may create additional overhead when
            # executing pipelines.
            self.log.warn('using old Redis version')

        if self.config['STATS_INTERVAL']:
            self.stats_thread = StatsThread(self)
            self.stats_thread.start()

        # Queue any periodic tasks that are not queued yet.
        self._queue_periodic_tasks()

        # First scan all the available queues for new items until they're empty.
        # Then, listen to the activity channel.
        # XXX: This can get inefficient when having lots of queues.

        self._pubsub = self.connection.pubsub()
        self._pubsub.subscribe(self._key('activity'))

        self._queue_set = set(self._filter_queues(
                self.connection.smembers(self._key(QUEUED))))

        try:
            while True:
                # Update the queue set on every iteration so we don't get stuck
                # on processing a specific queue.
                self._wait_for_new_tasks(timeout=self.config['SELECT_TIMEOUT'],
                            batch_timeout=self.config['SELECT_BATCH_TIMEOUT'])

                self._install_signal_handlers()
                self._did_work = False
                self._worker_run()
                self._uninstall_signal_handlers()
                if once and (not self._queue_set or force_once):
                    break
                if self._stop_requested:
                    raise KeyboardInterrupt()
        except KeyboardInterrupt:
            pass

        except Exception as e:
            self.log.exception(event='exception')
            raise

        finally:
            if self.stats_thread:
                self.stats_thread.stop()
                self.stats_thread = None

            # Free up Redis connection
            self._pubsub.reset()
            self.log.info('done')