A basic support to run services in the background

This commit is contained in:
Christian Berendt 2015-02-15 19:02:47 +01:00
parent 8eb0347f80
commit eb5f34f7ca
6 changed files with 97 additions and 59 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@
.eggs
.*.swp
build
*.log

View File

@ -10,6 +10,7 @@
- ibmysqlclient-dev
- mysql-client
- mysql-server
- python-daemon
- python-dev
- python-kombu
- python-mysqldb

View File

@ -19,6 +19,7 @@ import sys
import time
import uuid
import daemon
import kombu
from kombu.pools import producers
from sqlalchemy import create_engine
@ -28,8 +29,9 @@ from openstack_application_tutorial import models
from openstack_application_tutorial import queues
def initialize_logging():
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
def initialize_logging(filename):
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO,
filename=filename)
def parse_command_line_arguments():
@ -41,6 +43,12 @@ def parse_command_line_arguments():
parser.add_argument(
"--database-url", type=str, help="database connection URL",
default="mysql://tutorial:secretsecret@localhost:3306/tutorial")
parser.add_argument(
"--log-file", type=str, help="write logs to this file", default=None)
parser.add_argument(
"--daemonize", action="store_true", help="run in background")
parser.add_argument("--one-shot", action='store_true',
help="Generate one set of tasks and exit.")
parser.add_argument("--max-height", type=int, default=1024,
help="The maximum height of the generate image.")
parser.add_argument("--max-width", type=int, default=1024,
@ -77,8 +85,6 @@ def parse_command_line_arguments():
help="The minimum number of generated tasks.")
parser.add_argument("--max-tasks", type=int, default=10,
help="The maximum number of generated tasks.")
parser.add_argument("--one-shot", action='store_true',
help="Generate one set of tasks and exit.")
return parser.parse_args()
@ -105,9 +111,44 @@ def generate_task(args):
}
def run(args, connection, session):
while True:
random.seed()
number = random.randint(args.min_tasks, args.max_tasks)
logging.info("generating %d task(s)" % number)
for i in xrange(0, number):
task = generate_task(args)
fractal = models.Fractal(
uuid=task['uuid'],
width=task['width'],
height=task['height'],
xa=task['xa'],
xb=task['xb'],
ya=task['ya'],
yb=task['yb'],
iterations=task['iterations'])
session.add(fractal)
session.commit()
logging.info("generated task: %s" % task)
with producers[connection].acquire(block=True) as producer:
producer.publish(
task,
serializer='pickle',
exchange=queues.task_exchange,
declare=[queues.task_exchange],
routing_key='tasks')
if args.one_shot:
break
pause = random.uniform(args.min_pause, args.max_pause)
logging.info("sleeping for %f seconds" % pause)
time.sleep(pause)
def main():
initialize_logging()
args = parse_command_line_arguments()
initialize_logging(args.log_file)
connection = kombu.Connection(args.amqp_url)
engine = create_engine(args.database_url)
@ -118,42 +159,14 @@ def main():
maker = sessionmaker(bind=engine)
session = maker()
try:
while True:
random.seed()
number = random.randint(args.min_tasks, args.max_tasks)
logging.info("generating %d task(s)" % number)
for i in xrange(0, number):
task = generate_task(args)
fractal = models.Fractal(
uuid=task['uuid'],
width=task['width'],
height=task['height'],
xa=task['xa'],
xb=task['xb'],
ya=task['ya'],
yb=task['yb'],
iterations=task['iterations'])
session.add(fractal)
session.commit()
logging.info("generated task: %s" % task)
with producers[connection].acquire(block=True) as producer:
producer.publish(
task,
serializer='pickle',
exchange=queues.task_exchange,
declare=[queues.task_exchange],
routing_key='tasks')
if args.one_shot:
break
pause = random.uniform(args.min_pause, args.max_pause)
logging.info("sleeping for %f seconds" % pause)
time.sleep(pause)
except KeyboardInterrupt:
pass
if args.daemonize:
with daemon.DaemonContext():
run(args, connection, session)
else:
try:
run(args, connection, session)
except KeyboardInterrupt:
return 0
return 0

View File

@ -18,6 +18,7 @@ import argparse
import logging
import sys
import daemon
import kombu
from kombu.mixins import ConsumerMixin
from sqlalchemy import create_engine
@ -57,8 +58,9 @@ class Tracker(ConsumerMixin):
message.ack()
def initialize_logging():
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
def initialize_logging(filename):
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO,
filename=filename)
def parse_command_line_arguments():
@ -70,19 +72,28 @@ def parse_command_line_arguments():
parser.add_argument(
"--database-url", type=str, help="database connection URL",
default="mysql://tutorial:secretsecret@localhost:3306/tutorial")
parser.add_argument(
"--log-file", type=str, help="write logs to this file", default=None)
parser.add_argument(
"--daemonize", action="store_true", help="run in background")
return parser.parse_args()
def main():
initialize_logging()
args = parse_command_line_arguments()
try:
tracker = Tracker(args.amqp_url, args.database_url)
tracker.run()
except KeyboardInterrupt:
return 0
initialize_logging(args.log_file)
tracker = Tracker(args.amqp_url, args.database_url)
return 1
if args.daemonize:
with daemon.DaemonContext():
tracker.run()
else:
try:
tracker.run()
except KeyboardInterrupt:
return 0
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -23,6 +23,7 @@ import random
import sys
import time
import daemon
import kombu
from kombu.mixins import ConsumerMixin
from kombu.pools import producers
@ -118,8 +119,9 @@ class Worker(ConsumerMixin):
message.ack()
def initialize_logging():
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
def initialize_logging(filename):
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO,
filename=filename)
def parse_command_line_arguments():
@ -131,19 +133,28 @@ def parse_command_line_arguments():
parser.add_argument(
"--amqp-url", type=str, help="AMQP connection URL",
default="amqp://tutorial:secretsecret@localhost:5672//")
parser.add_argument(
"--log-file", type=str, help="write logs to this file", default=None)
parser.add_argument(
"--daemonize", action="store_true", help="run in background")
return parser.parse_args()
def main():
initialize_logging()
args = parse_command_line_arguments()
try:
worker = Worker(args.amqp_url, args.target)
worker.run()
except KeyboardInterrupt:
return 0
initialize_logging(args.log_file)
worker = Worker(args.amqp_url, args.target)
return 1
if args.daemonize:
with daemon.DaemonContext():
worker.run()
else:
try:
worker.run()
except KeyboardInterrupt:
return 0
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -5,4 +5,5 @@ argparse
kombu
mysql
pillow
python-daemon
sqlalchemy