<commit_before># Copyright (c) 2017, <NAME>
#
# All rights reserved.
#
# See the file "LICENCE" for information about the copyright
# and warranty status of this software.

import asyncio
import os
import re
import signal
import sys
import time
from functools import partial

from aiorpcx import TaskGroup

from electrumx.lib.util import class_logger


class ServerBase(object):
    '''Base class server implementation.

    Derived classes are expected to:

    - set PYTHON_MIN_VERSION and SUPPRESS_MESSAGES as appropriate
    - implement the serve() coroutine, called from the run() method.
      Upon return the event loop runs until the shutdown signal is received.
    '''

    SUPPRESS_MESSAGE_REGEX = re.compile('SSH handshake')
    PYTHON_MIN_VERSION = (3, 6)

    def __init__(self, env):
        '''Save the environment, perform basic sanity checks, and set the
        event loop policy.
        '''
        # First asyncio operation must be to set the event loop policy
        # as this replaces the event loop
        asyncio.set_event_loop_policy(env.loop_policy)

        self.logger = class_logger(__name__, self.__class__.__name__)
        self.logger.info(f'Python version: {sys.version}')
        self.env = env

        # Sanity checks
        if sys.version_info < self.PYTHON_MIN_VERSION:
            mvs = '.'.join(str(part) for part in self.PYTHON_MIN_VERSION)
            raise RuntimeError('Python version >= {} is required'.format(mvs))

        if os.geteuid() == 0 and not env.allow_root:
            raise RuntimeError('RUNNING AS ROOT IS STRONGLY DISCOURAGED!\n'
                               'You shoud create an unprivileged user account '
                               'and use that.\n'
                               'To continue as root anyway, restart with '
                               'environment variable ALLOW_ROOT non-empty')

    async def serve(self, shutdown_event):
        '''Override to provide the main server functionality.
        Run as a task that will be cancelled to request shutdown.

        Setting the event also shuts down the server.
        '''
        shutdown_event.set()

    def on_exception(self, loop, context):
        '''Suppress spurious messages it appears we cannot control.'''
        message = context.get('message')
        if message and self.SUPPRESS_MESSAGE_REGEX.match(message):
            return
        loop.default_exception_handler(context)

    async def _main(self, loop):
        '''Run the server application:

        - record start time
        - install SIGINT and SIGTERM handlers to trigger shutdown_event
        - set loop's exception handler to suppress unwanted messages
        - run the event loop until serve() completes
        '''
        def on_signal(signame):
            shutdown_event.set()
            self.logger.warning(f'received {signame} signal, '
                                f'initiating shutdown')

        self.start_time = time.time()
        for signame in ('SIGINT', 'SIGTERM'):<commit_msg>Suppress accept_connection2 asyncio log spew<commit_after># Copyright (c) 2017, <NAME>
#
# All rights reserved.
#
# See the file "LICENCE" for information about the copyright
# and warranty status of this software.

import asyncio
import os
import re
import signal
import sys
import time
from functools import partial

from aiorpcx import TaskGroup

from electrumx.lib.util import class_logger


class ServerBase(object):
    '''Base class server implementation.

    Derived classes are expected to:

    - set PYTHON_MIN_VERSION and SUPPRESS_MESSAGES as appropriate
    - implement the serve() coroutine, called from the run() method.
      Upon return the event loop runs until the shutdown signal is received.
    '''

    SUPPRESS_MESSAGE_REGEX = re.compile('SSH handshake')
    SUPPRESS_TASK_REGEX = re.compile('accept_connection2')
    PYTHON_MIN_VERSION = (3, 6)

    def __init__(self, env):
        '''Save the environment, perform basic sanity checks, and set the
        event loop policy.
        '''
        # First asyncio operation must be to set the event loop policy
        # as this replaces the event loop
        asyncio.set_event_loop_policy(env.loop_policy)

        self.logger = class_logger(__name__, self.__class__.__name__)
        self.logger.info(f'Python version: {sys.version}')
        self.env = env

        # Sanity checks
        if sys.version_info < self.PYTHON_MIN_VERSION:
            mvs = '.'.join(str(part) for part in self.PYTHON_MIN_VERSION)
            raise RuntimeError('Python version >= {} is required'.format(mvs))

        if os.geteuid() == 0 and not env.allow_root:
            raise RuntimeError('RUNNING AS ROOT IS STRONGLY DISCOURAGED!\n'
                               'You shoud create an unprivileged user account '
                               'and use that.\n'
                               'To continue as root anyway, restart with '
                               'environment variable ALLOW_ROOT non-empty')

    async def serve(self, shutdown_event):
        '''Override to provide the main server functionality.
        Run as a task that will be cancelled to request shutdown.

        Setting the event also shuts down the server.
        '''
        shutdown_event.set()

    def on_exception(self, loop, context):
        '''Suppress spurious messages it appears we cannot control.'''
        message = context.get('message')
        if message and self.SUPPRESS_MESSAGE_REGEX.match(message):
            return
        if self.SUPPRESS_TASK_REGEX.match(repr(context.get('task'))):
            return
        loop.default_exception_handler(context)

    async def _main(self, loop):
        '''Run the server application:

        - record start time
        - install SIGINT and SIGTERM handlers to trigger shutdown_event
        - set loop's exception handler to suppress unwanted messages
        - run the event loop until serve() completes
        '''
        def on_signal(signame):
            shutdown_event.set()
            self.logger.warning(f'received {signame} signal, '
                                f'initiating shutdown')

        self.start_time = time.time()
        for signame in ('SIGINT', 'SIGTERM'):
{'fraction_non_alphanumeric': 0.0764904386951631, 'fraction_numerical': 0.0025711071830306926, 'mean_word_length': 2.384448069603045, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1180441', 'n_tokens_mistral': 1692, 'n_tokens_neox': 1623, 'n_words': 576}