This file is indexed.

/usr/lib/python2.7/dist-packages/maasserver/eventloop.py is in python-django-maas 1.5.4+bzr2294-0ubuntu1.2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# Copyright 2014 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Event-loop support for the MAAS Region Controller.

This helps start up a background event loop (using Twisted, via crochet)
to handle communications with Cluster Controllers, and any other tasks
that are not tied to an HTTP reqoest.

.. py:data:: loop

   The single instance of :py:class:`RegionEventLoop` that's all a
   process needs.

.. py:data:: services

   The :py:class:`~twisted.application.service.MultiService` which forms
   the root of this process's service tree.

   This is a convenient reference to :py:attr:`.loop.services`.

.. py:data:: start

   Start all the services in :py:data:`services`.

   This is a convenient reference to :py:attr:`.loop.start`.

.. py:data:: stop

   Stop all the services in :py:data:`services`.

   This is a convenient reference to :py:attr:`.loop.stop`.

"""

from __future__ import (
    absolute_import,
    print_function,
    unicode_literals,
    )

str = None

__metaclass__ = type
__all__ = [
    "loop",
    "services",
    "start",
    "stop",
]

from functools import wraps
from logging import getLogger
from os import getpid
from socket import gethostname

import crochet
from django.utils import autoreload
from twisted.application.service import MultiService
from twisted.internet.error import ReactorNotRunning


logger = getLogger(__name__)


def stop_event_loop_when_reloader_is_invoked():
    """Stop the event loop if Django starts reloading itself.

    This typically only happens when using Django's development server.
    """
    # The original restart_with_reloader.
    restart_with_reloader = autoreload.restart_with_reloader

    @wraps(restart_with_reloader)
    def stop_event_loop_then_restart_with_reloader():
        logger.info("Stopping event loop in process %d", getpid())
        try:
            crochet.reactor.stop()
        except ReactorNotRunning:
            pass
        return restart_with_reloader()

    autoreload.restart_with_reloader = (
        stop_event_loop_then_restart_with_reloader)

stop_event_loop_when_reloader_is_invoked()


def make_RegionService():
    # Import here to avoid a circular import.
    from maasserver.rpc import regionservice
    return regionservice.RegionService()


def make_RegionAdvertisingService():
    # Import here to avoid a circular import.
    from maasserver.rpc import regionservice
    return regionservice.RegionAdvertisingService()


class RegionEventLoop:
    """An event loop running in a region controller process.

    Typically several processes will be running the web application --
    chiefly Django -- across several machines, with multiple threads of
    execution in each process.

    This class represents a single event loop for each *process*,
    allowing convenient control of the event loop -- a Twisted reactor
    running in a thread -- and to which to attach and query services.

    :cvar factories: A sequence of ``(name, factory)`` tuples. Used to
        populate :py:attr:`.services` at start time.

    :ivar services:
        A :py:class:`~twisted.application.service.MultiService` which
        forms the root of the service tree.

    """

    factories = (
        ("rpc", make_RegionService),
        ("rpc-advertise", make_RegionAdvertisingService),
    )

    def __init__(self):
        super(RegionEventLoop, self).__init__()
        self.services = MultiService()
        self.handle = None

    def init(self):
        """Spin up a Twisted event loop in this process."""
        if not crochet.reactor.running:
            logger.info("Starting event loop in process %d", getpid())
            crochet.setup()

    @crochet.run_in_reactor
    def start(self):
        """start()

        Start all services in the region's event-loop.
        """
        for name, factory in self.factories:
            try:
                self.services.getServiceNamed(name)
            except KeyError:
                service = factory()
                service.setName(name)
                service.setServiceParent(self.services)
        self.handle = crochet.reactor.addSystemEventTrigger(
            'before', 'shutdown', self.services.stopService)
        return self.services.startService()

    @crochet.run_in_reactor
    def stop(self):
        """stop()

        Stop all services in the region's event-loop.
        """
        if self.handle is not None:
            handle, self.handle = self.handle, None
            crochet.reactor.removeSystemEventTrigger(handle)
        return self.services.stopService()

    @property
    def name(self):
        """A name for identifying this service in a distributed system."""
        return "%s:pid=%d" % (gethostname(), getpid())


loop = RegionEventLoop()
services = loop.services
start = loop.start
stop = loop.stop

loop.init()