1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
"""Plumd main entry point.""" |
3
|
|
|
import sys |
4
|
|
|
import time |
5
|
|
|
import random |
6
|
|
|
|
7
|
|
|
import plumd |
8
|
|
|
from plumd.load import PluginRegistry |
9
|
|
|
import plumd.server |
10
|
|
|
|
11
|
|
|
PY3 = sys.version_info > (3,) |
12
|
|
|
|
13
|
|
|
__author__ = 'Kenny Freeman' |
14
|
|
|
__email__ = '[email protected]' |
15
|
|
|
__license__ = "ISCL" |
16
|
|
|
__docformat__ = 'reStructuredText' |
17
|
|
|
|
18
|
|
|
|
19
|
|
|
class NullServer(plumd.server.Server): |
20
|
|
|
"""A 'null' server that simply spawns Reader/Writer threads.""" |
21
|
|
|
|
22
|
|
|
defaults = { |
23
|
|
|
'thread.daemon': True, |
24
|
|
|
'shutdown.timeout': 5, |
25
|
|
|
'delay.startup': 5 |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
def __init__(self, log, config): |
29
|
|
|
"""Create and return a ready to use NullServer instance. |
30
|
|
|
|
31
|
|
|
:param log: A logger. |
32
|
|
|
:type log: logging.Logger |
33
|
|
|
:param config: A config object. |
34
|
|
|
:type config: plumd.config.Conf |
35
|
|
|
""" |
36
|
|
|
super(NullServer, self).__init__(log, config) |
37
|
|
|
self.config.defaults(NullServer.defaults) |
38
|
|
|
self.registry = PluginRegistry(log, config) |
39
|
|
|
# maintain a mapping of reader/writer threads => reader/writer plugins |
40
|
|
|
self.readers = dict() |
41
|
|
|
self.writers = dict() |
42
|
|
|
if self.registry.nplugins < 1: |
43
|
|
|
raise plumd.ConfigError("no plugins loaded") |
44
|
|
|
elif self.registry.nreaders < 1: |
45
|
|
|
raise plumd.ConfigError("no reader plugins loaded") |
46
|
|
|
elif self.registry.nrenders < 1: |
47
|
|
|
raise plumd.ConfigError("no render plugins loaded") |
48
|
|
|
elif self.registry.nwriters < 1: |
49
|
|
|
raise plumd.ConfigError("no writer plugins loaded") |
50
|
|
|
self.load() |
51
|
|
|
|
52
|
|
|
def load(self): |
53
|
|
|
"""Create and initialize the Reader/Writer plugin threads.""" |
54
|
|
|
# create writer threads, set their render source |
55
|
|
|
for pname, writer in self.registry.get_writers(): |
56
|
|
|
wthread = plumd.WriterThread(self.log, self.config, writer) |
57
|
|
|
rname = writer.config.get('render', exception=True) |
58
|
|
|
render = self.registry.get_render(rname) |
59
|
|
|
wthread.register(render) |
60
|
|
|
self.writers[pname] = wthread |
61
|
|
|
# create reader threads, set their render output(s) |
62
|
|
|
for pname, reader in self.registry.get_readers(): |
63
|
|
|
rthread = plumd.ReaderThread(self.log, self.config, reader) |
64
|
|
|
for rname in reader.config.get("render", exception=True): |
65
|
|
|
render = self.registry.get_render(rname) |
66
|
|
|
rthread.register(render) |
67
|
|
|
self.readers[pname] = rthread |
68
|
|
|
|
69
|
|
|
def start(self): |
70
|
|
|
"""Start the Reader/Writer plugin threads.""" |
71
|
|
|
# no stampeding herds on restart |
72
|
|
|
time.sleep(random.randrange(int(self.config.get('delay.startup')))) |
73
|
|
|
|
74
|
|
|
# start writer plugins first |
75
|
|
|
for writer in self.writers.values(): |
76
|
|
|
writer.start() |
77
|
|
|
# start reader plugins |
78
|
|
|
for reader in self.readers.values(): |
79
|
|
|
reader.start() |
80
|
|
|
|
81
|
|
|
def stop(self): |
82
|
|
|
"""Stop the Reader/Writer plugin threads.""" |
83
|
|
|
# first stop readers |
84
|
|
|
for reader in self.readers.values(): |
85
|
|
|
reader.stop() |
86
|
|
|
# ensure they've all stopped |
87
|
|
|
for reader in self.readers.values(): |
88
|
|
|
reader.join(timeout=self.config.get('shutdown.timeout')) |
89
|
|
|
|
90
|
|
|
# stop writers last |
91
|
|
|
for writer in self.writers.values(): |
92
|
|
|
writer.stop() |
93
|
|
|
# ensure they've all stopped |
94
|
|
|
for writer in self.writers.values(): |
95
|
|
|
writer.join(timeout=self.config.get('shutdown.timeout')) |