Use twisted application framework
This commit is contained in:
parent
21e7a794bd
commit
28d5eebe7e
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,3 +9,5 @@ build/*
|
||||
_trial_temp/
|
||||
subunit-output.txt
|
||||
test-report.xml
|
||||
twisted/plugins/dropin.cache
|
||||
twistd.log
|
||||
|
2
Makefile
2
Makefile
@ -26,5 +26,5 @@ clean:
|
||||
find . -name '.coverage' -delete
|
||||
find . -name '_trial_coverage' -print0 | xargs --null rm -rf
|
||||
find . -name '_trial_temp' -print0 | xargs --null rm -rf
|
||||
rm -rf dist build *.egg-info
|
||||
rm -rf dist build *.egg-info twisted/plugins/dropin.cache
|
||||
|
||||
|
@ -16,11 +16,15 @@ limitations under the License.
|
||||
|
||||
import time
|
||||
import simplejson as json
|
||||
from teeth_agent.protocol import TeethAgentProtocol
|
||||
|
||||
from twisted.application.service import MultiService
|
||||
from twisted.application.internet import TCPClient
|
||||
from twisted.internet.protocol import ReconnectingClientFactory
|
||||
from twisted.python.failure import Failure
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet.defer import maybeDeferred
|
||||
from twisted.internet.defer import DeferredList
|
||||
from twisted.python.failure import Failure
|
||||
|
||||
from teeth_agent.protocol import TeethAgentProtocol
|
||||
from teeth_agent.logging import get_logger
|
||||
log = get_logger()
|
||||
|
||||
@ -59,7 +63,7 @@ class TeethClientFactory(ReconnectingClientFactory, object):
|
||||
super(TeethClientFactory, self).clientConnectionLost(connector, reason)
|
||||
|
||||
|
||||
class TeethClient(object):
|
||||
class TeethClient(MultiService, object):
|
||||
"""
|
||||
High level Teeth Client.
|
||||
"""
|
||||
@ -68,18 +72,35 @@ class TeethClient(object):
|
||||
|
||||
def __init__(self, addrs):
|
||||
super(TeethClient, self).__init__()
|
||||
self.setName('teeth-agent')
|
||||
self._client_encoder = self.client_encoder_cls()
|
||||
self._client_factory = self.client_factory_cls(self._client_encoder, self)
|
||||
self._start_time = time.time()
|
||||
self._clients = []
|
||||
self._outmsg = []
|
||||
self._connectaddrs = addrs
|
||||
self._running = False
|
||||
self._handlers = {
|
||||
'v1': {
|
||||
'status': self._handle_status,
|
||||
}
|
||||
}
|
||||
|
||||
def startService(self):
|
||||
"""Start the Service."""
|
||||
super(TeethClient, self).startService()
|
||||
self._running = True
|
||||
self.start()
|
||||
|
||||
def stopService(self):
|
||||
"""Stop the Service."""
|
||||
super(TeethClient, self).stopService()
|
||||
self._running = False
|
||||
dl = []
|
||||
for client in self._clients:
|
||||
dl.append(client.loseConnectionSoon(timeout=0.05))
|
||||
return DeferredList(dl)
|
||||
|
||||
def remove_endpoint(self, host, port):
|
||||
"""Remove an Agent Endpoint from the active list."""
|
||||
|
||||
@ -101,9 +122,15 @@ class TeethClient(object):
|
||||
self._clients.append(client)
|
||||
|
||||
def start(self):
|
||||
"""Start the agent."""
|
||||
"""Start the agent, if running."""
|
||||
|
||||
if not self._running:
|
||||
return
|
||||
|
||||
for host, port in self._connectaddrs:
|
||||
reactor.connectTCP(host, port, self._client_factory)
|
||||
service = TCPClient(host, port, self._client_factory)
|
||||
service.setName("teeth-agent[%s:%d]".format(host, port))
|
||||
self.addService(service)
|
||||
self._connectaddrs = []
|
||||
|
||||
def _on_command(self, topic, message):
|
||||
|
@ -14,9 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import structlog
|
||||
import twisted
|
||||
|
||||
CONFIGURED_LOGGING = False
|
||||
|
||||
@ -32,7 +30,6 @@ def configure():
|
||||
|
||||
CONFIGURED_LOGGING = True
|
||||
|
||||
twisted.python.log.startLogging(sys.stderr)
|
||||
structlog.configure(
|
||||
context_class=dict,
|
||||
cache_logger_on_first_use=True)
|
||||
|
@ -18,6 +18,7 @@ import simplejson as json
|
||||
import uuid
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.internet import task
|
||||
from twisted.internet import reactor
|
||||
from twisted.protocols.basic import LineReceiver
|
||||
from twisted.python.failure import Failure
|
||||
@ -100,7 +101,7 @@ class RPCProtocol(LineReceiver, EventEmitter):
|
||||
"""Attempt to disconnect from the transport as 'nicely' as possible. """
|
||||
self._log.info('Trying to disconnect.')
|
||||
self.transport.loseConnection()
|
||||
reactor.callLater(timeout, self.transport.abortConnection)
|
||||
return task.deferLater(reactor, timeout, self.transport.abortConnection)
|
||||
|
||||
def connectionMade(self):
|
||||
"""TCP hard. We made it. Maybe."""
|
||||
|
29
teeth_agent/scripts/teeth-agent.py → teeth_agent/service.py
Executable file → Normal file
29
teeth_agent/scripts/teeth-agent.py → teeth_agent/service.py
Executable file → Normal file
@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Copyright 2013 Rackspace, Inc.
|
||||
|
||||
@ -17,17 +16,15 @@ limitations under the License.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from os.path import dirname
|
||||
|
||||
sys.path.append(dirname(dirname(dirname(os.path.realpath(__file__)))))
|
||||
|
||||
from twisted.python import usage
|
||||
from twisted.internet import reactor
|
||||
from twisted.application.service import MultiService
|
||||
|
||||
from teeth_agent.logging import configure as configureLogging
|
||||
from teeth_agent.agent import StandbyAgent
|
||||
|
||||
|
||||
class Options(usage.Options):
|
||||
"""Additional options for the Teeth Agent"""
|
||||
synopsis = """%s [options]
|
||||
""" % (
|
||||
os.path.basename(sys.argv[0]),)
|
||||
@ -35,24 +32,16 @@ class Options(usage.Options):
|
||||
optParameters = [["mode", "m", "standbye", "Mode to run Agent in, standbye or decom."]]
|
||||
|
||||
|
||||
def run():
|
||||
if len(sys.argv) == 1:
|
||||
sys.argv.append("--help")
|
||||
|
||||
config = Options()
|
||||
try:
|
||||
config.parseOptions()
|
||||
except usage.error, ue:
|
||||
raise SystemExit("%s: %s" % (sys.argv[0], ue))
|
||||
|
||||
def makeService(config):
|
||||
"""Create an instance of the Teeth-Agent service."""
|
||||
configureLogging()
|
||||
|
||||
s = MultiService()
|
||||
|
||||
if config['mode'] == "standbye":
|
||||
agent = StandbyAgent([['localhost', 8081]])
|
||||
agent.start()
|
||||
agent.setServiceParent(s)
|
||||
else:
|
||||
raise SystemExit("Invalid mode")
|
||||
reactor.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
return s
|
29
twisted/plugins/teeth_agent.py
Normal file
29
twisted/plugins/teeth_agent.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
|
||||
"""
|
||||
Teeth Agent Twisted Application Plugin.
|
||||
"""
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TeethAgent = ServiceMaker(
|
||||
"Teeth Agent Client Application",
|
||||
"teeth_agent.service",
|
||||
"Teeth Agent for decomissioning and standbye",
|
||||
"teeth-agent"
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user