Use twisted application framework
This commit is contained in:
parent
21e7a794bd
commit
28d5eebe7e
|
@ -9,3 +9,5 @@ build/*
|
||||||
_trial_temp/
|
_trial_temp/
|
||||||
subunit-output.txt
|
subunit-output.txt
|
||||||
test-report.xml
|
test-report.xml
|
||||||
|
twisted/plugins/dropin.cache
|
||||||
|
twistd.log
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -26,5 +26,5 @@ clean:
|
||||||
find . -name '.coverage' -delete
|
find . -name '.coverage' -delete
|
||||||
find . -name '_trial_coverage' -print0 | xargs --null rm -rf
|
find . -name '_trial_coverage' -print0 | xargs --null rm -rf
|
||||||
find . -name '_trial_temp' -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 time
|
||||||
import simplejson as json
|
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.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 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
|
from teeth_agent.logging import get_logger
|
||||||
log = get_logger()
|
log = get_logger()
|
||||||
|
|
||||||
|
@ -59,7 +63,7 @@ class TeethClientFactory(ReconnectingClientFactory, object):
|
||||||
super(TeethClientFactory, self).clientConnectionLost(connector, reason)
|
super(TeethClientFactory, self).clientConnectionLost(connector, reason)
|
||||||
|
|
||||||
|
|
||||||
class TeethClient(object):
|
class TeethClient(MultiService, object):
|
||||||
"""
|
"""
|
||||||
High level Teeth Client.
|
High level Teeth Client.
|
||||||
"""
|
"""
|
||||||
|
@ -68,18 +72,35 @@ class TeethClient(object):
|
||||||
|
|
||||||
def __init__(self, addrs):
|
def __init__(self, addrs):
|
||||||
super(TeethClient, self).__init__()
|
super(TeethClient, self).__init__()
|
||||||
|
self.setName('teeth-agent')
|
||||||
self._client_encoder = self.client_encoder_cls()
|
self._client_encoder = self.client_encoder_cls()
|
||||||
self._client_factory = self.client_factory_cls(self._client_encoder, self)
|
self._client_factory = self.client_factory_cls(self._client_encoder, self)
|
||||||
self._start_time = time.time()
|
self._start_time = time.time()
|
||||||
self._clients = []
|
self._clients = []
|
||||||
self._outmsg = []
|
self._outmsg = []
|
||||||
self._connectaddrs = addrs
|
self._connectaddrs = addrs
|
||||||
|
self._running = False
|
||||||
self._handlers = {
|
self._handlers = {
|
||||||
'v1': {
|
'v1': {
|
||||||
'status': self._handle_status,
|
'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):
|
def remove_endpoint(self, host, port):
|
||||||
"""Remove an Agent Endpoint from the active list."""
|
"""Remove an Agent Endpoint from the active list."""
|
||||||
|
|
||||||
|
@ -101,9 +122,15 @@ class TeethClient(object):
|
||||||
self._clients.append(client)
|
self._clients.append(client)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Start the agent."""
|
"""Start the agent, if running."""
|
||||||
|
|
||||||
|
if not self._running:
|
||||||
|
return
|
||||||
|
|
||||||
for host, port in self._connectaddrs:
|
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 = []
|
self._connectaddrs = []
|
||||||
|
|
||||||
def _on_command(self, topic, message):
|
def _on_command(self, topic, message):
|
||||||
|
|
|
@ -14,9 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
|
||||||
import structlog
|
import structlog
|
||||||
import twisted
|
|
||||||
|
|
||||||
CONFIGURED_LOGGING = False
|
CONFIGURED_LOGGING = False
|
||||||
|
|
||||||
|
@ -32,7 +30,6 @@ def configure():
|
||||||
|
|
||||||
CONFIGURED_LOGGING = True
|
CONFIGURED_LOGGING = True
|
||||||
|
|
||||||
twisted.python.log.startLogging(sys.stderr)
|
|
||||||
structlog.configure(
|
structlog.configure(
|
||||||
context_class=dict,
|
context_class=dict,
|
||||||
cache_logger_on_first_use=True)
|
cache_logger_on_first_use=True)
|
||||||
|
|
|
@ -18,6 +18,7 @@ import simplejson as json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
from twisted.internet import task
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.protocols.basic import LineReceiver
|
from twisted.protocols.basic import LineReceiver
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
|
@ -100,7 +101,7 @@ class RPCProtocol(LineReceiver, EventEmitter):
|
||||||
"""Attempt to disconnect from the transport as 'nicely' as possible. """
|
"""Attempt to disconnect from the transport as 'nicely' as possible. """
|
||||||
self._log.info('Trying to disconnect.')
|
self._log.info('Trying to disconnect.')
|
||||||
self.transport.loseConnection()
|
self.transport.loseConnection()
|
||||||
reactor.callLater(timeout, self.transport.abortConnection)
|
return task.deferLater(reactor, timeout, self.transport.abortConnection)
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
"""TCP hard. We made it. Maybe."""
|
"""TCP hard. We made it. Maybe."""
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
"""
|
"""
|
||||||
Copyright 2013 Rackspace, Inc.
|
Copyright 2013 Rackspace, Inc.
|
||||||
|
|
||||||
|
@ -17,17 +16,15 @@ limitations under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from os.path import dirname
|
|
||||||
|
|
||||||
sys.path.append(dirname(dirname(dirname(os.path.realpath(__file__)))))
|
|
||||||
|
|
||||||
from twisted.python import usage
|
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.logging import configure as configureLogging
|
||||||
from teeth_agent.agent import StandbyAgent
|
from teeth_agent.agent import StandbyAgent
|
||||||
|
|
||||||
|
|
||||||
class Options(usage.Options):
|
class Options(usage.Options):
|
||||||
|
"""Additional options for the Teeth Agent"""
|
||||||
synopsis = """%s [options]
|
synopsis = """%s [options]
|
||||||
""" % (
|
""" % (
|
||||||
os.path.basename(sys.argv[0]),)
|
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."]]
|
optParameters = [["mode", "m", "standbye", "Mode to run Agent in, standbye or decom."]]
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def makeService(config):
|
||||||
if len(sys.argv) == 1:
|
"""Create an instance of the Teeth-Agent service."""
|
||||||
sys.argv.append("--help")
|
|
||||||
|
|
||||||
config = Options()
|
|
||||||
try:
|
|
||||||
config.parseOptions()
|
|
||||||
except usage.error, ue:
|
|
||||||
raise SystemExit("%s: %s" % (sys.argv[0], ue))
|
|
||||||
|
|
||||||
configureLogging()
|
configureLogging()
|
||||||
|
|
||||||
|
s = MultiService()
|
||||||
|
|
||||||
if config['mode'] == "standbye":
|
if config['mode'] == "standbye":
|
||||||
agent = StandbyAgent([['localhost', 8081]])
|
agent = StandbyAgent([['localhost', 8081]])
|
||||||
agent.start()
|
agent.setServiceParent(s)
|
||||||
else:
|
else:
|
||||||
raise SystemExit("Invalid mode")
|
raise SystemExit("Invalid mode")
|
||||||
reactor.run()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
return s
|
||||||
run()
|
|
|
@ -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…
Reference in New Issue