|
7 | 7 | print_function, unicode_literals)
|
8 | 8 |
|
9 | 9 | import argparse
|
10 |
| -from enum import Enum |
11 | 10 | from ..settings import get_config
|
| 11 | +from tasq.remote.supervisor import supervisor_factory |
| 12 | +from tasq.logger import logger |
12 | 13 |
|
13 | 14 |
|
14 |
| -class WorkerType(Enum): |
15 |
| - ActorWorker = 'actor' |
16 |
| - ProcessWorker = 'process' |
| 15 | +class UnknownSupervisorException(Exception): |
| 16 | + pass |
17 | 17 |
|
18 | 18 |
|
19 |
| -def get_parser(): |
20 |
| - parser = argparse.ArgumentParser(description='Tasq CLI commands') |
21 |
| - parser.add_argument('subcommand') |
22 |
| - parser.add_argument('-f', action='store') |
23 |
| - parser.add_argument('--secure', '-s', action='store_true') |
24 |
| - parser.add_argument('--unix', '-u', action='store_true') |
25 |
| - parser.add_argument('--workers', nargs='*') |
26 |
| - parser.add_argument('--worker-type', action='store') |
27 |
| - parser.add_argument('--num-workers', action='store') |
28 |
| - parser.add_argument('--random', action='store') |
29 |
| - parser.add_argument('--verbose', '-v', action='store_true') |
30 |
| - parser.add_argument('--addr', '-a', action='store') |
31 |
| - parser.add_argument('--port', '-p', action='store') |
32 |
| - parser.add_argument('--db', action='store') |
33 |
| - parser.add_argument('--name', action='store') |
34 |
| - return parser |
35 |
| - |
36 |
| - |
37 |
| -def start_worker(host, port, sign_data, unix_socket, worker_type): |
38 |
| - from tasq.remote.supervisor import ZMQActorSupervisor, ZMQQueueSupervisor |
39 |
| - if worker_type == WorkerType.ActorWorker: |
40 |
| - supervisor = ZMQActorSupervisor(host, port, port + 1, |
41 |
| - sign_data=sign_data, unix_socket=unix_socket) |
42 |
| - else: |
43 |
| - supervisor = ZMQQueueSupervisor(host, port, port + 1, |
44 |
| - sign_data=sign_data, unix_socket=unix_socket) |
45 |
| - supervisor.serve_forever() |
| 19 | +supervisors = { |
| 20 | + 'actor': { |
| 21 | + 'zmq': 'ZMQ_ACTOR_SUPERVISOR', |
| 22 | + 'redis': 'REDIS_ACTOR_SUPERVISOR', |
| 23 | + 'rabbitmq': 'AMQP_ACTOR_SUPERVISOR' |
| 24 | + }, |
| 25 | + 'process': { |
| 26 | + 'zmq': 'ZMQ_QUEUE_SUPERVISOR', |
| 27 | + 'redis': 'REDIS_QUEUE_SUPERVISOR', |
| 28 | + 'rabbitmq': 'AMQP_QUEUE_SUPERVISOR' |
| 29 | + } |
| 30 | +} |
46 | 31 |
|
47 | 32 |
|
48 |
| -def start_redis_worker(host, port, db, name, sign_data, worker_type): |
49 |
| - from tasq.remote.supervisor import RedisActorSupervisor, RedisQueueSupervisor |
50 |
| - if worker_type == WorkerType.ActorWorker: |
51 |
| - supervisor = RedisActorSupervisor(host, port, db, |
52 |
| - name, sign_data=sign_data) |
53 |
| - else: |
54 |
| - supervisor = RedisQueueSupervisor(host, port, db, name, |
55 |
| - sign_data=sign_data) |
56 |
| - supervisor.serve_forever() |
| 33 | +def parse_arguments(): |
| 34 | + parser = argparse.ArgumentParser(description='Tasq CLI') |
| 35 | + parser.add_argument('subcommand') |
| 36 | + parser.add_argument('--conf', '-c', |
| 37 | + help='The filepath to the configuration file, in json', |
| 38 | + nargs='?') |
| 39 | + parser.add_argument( |
| 40 | + '--address', '-a', |
| 41 | + help='The ZMQ host address to connect to, default to localhost', |
| 42 | + nargs='?' |
| 43 | + ) |
| 44 | + parser.add_argument('--port', '-p', |
| 45 | + help='The ZMQ port to connect to, default to 9000 for ' |
| 46 | + 'ZMQ/TCP/UNIX connections, to 6379 while using a ' |
| 47 | + 'redis broker or 5672 in case of RabbitMQ as backend.', |
| 48 | + nargs='?', |
| 49 | + type=int) |
| 50 | + parser.add_argument('--plport', |
| 51 | + help='The ZMQ port to connect to, default to 9001 for ' |
| 52 | + 'ZMQ/TCP/UNIX connections', |
| 53 | + nargs='?', |
| 54 | + type=int) |
| 55 | + parser.add_argument('--worker-type', |
| 56 | + help='The type of worker to deploy for a supervisor', |
| 57 | + nargs='?') |
| 58 | + parser.add_argument('--db', |
| 59 | + help='The database to use with redis as backend', |
| 60 | + nargs='?', |
| 61 | + type=int) |
| 62 | + parser.add_argument( |
| 63 | + '--name', |
| 64 | + help='The name of the queue, only for redis or rabbitmq backends', |
| 65 | + nargs='?' |
| 66 | + ) |
| 67 | + parser.add_argument( |
| 68 | + '--shared-key', '-sk', |
| 69 | + help='The shared key to use to sign byte streams between clients and ' |
| 70 | + 'supervisors', |
| 71 | + nargs='?' |
| 72 | + ) |
| 73 | + parser.add_argument('--unix', '-u', |
| 74 | + help='Unix socket flag, in case supervisors and ' |
| 75 | + 'clients reside on the same node', |
| 76 | + action='store_true') |
| 77 | + parser.add_argument('--num-workers', |
| 78 | + help='Number of workers to instantiate on the node', |
| 79 | + nargs='?', |
| 80 | + type=int) |
| 81 | + parser.add_argument('--log-level', |
| 82 | + help='Set logging level', |
| 83 | + nargs='?') |
| 84 | + args = parser.parse_args() |
| 85 | + return args |
57 | 86 |
|
58 | 87 |
|
59 |
| -def start_rabbitmq_worker(host, port, name, sign_data, worker_type): |
60 |
| - from tasq.remote.supervisor import RabbitMQActorSupervisor, RabbitMQQueueSupervisor |
61 |
| - if worker_type == WorkerType.ActorWorker: |
62 |
| - supervisor = RabbitMQActorSupervisor(host, port, |
63 |
| - name, sign_data=sign_data) |
| 88 | +def start_worker(supervisor_type, worker_type, host, **kwargs): |
| 89 | + try: |
| 90 | + s_type = supervisors[worker_type][supervisor_type] |
| 91 | + except KeyError: |
| 92 | + raise UnknownSupervisorException() |
64 | 93 | else:
|
65 |
| - supervisor = RabbitMQQueueSupervisor(host, port, name, |
66 |
| - sign_data=sign_data) |
67 |
| - supervisor.serve_forever() |
68 |
| - |
69 |
| - |
70 |
| -def start_workers(workers, sign_data, unix_socket): |
71 |
| - from tasq.remote.supervisor import Supervisors |
72 |
| - supervisors = Supervisors(workers, sign_data=sign_data, unix_socket=unix_socket) |
73 |
| - supervisors.start_procs() |
74 |
| - |
75 |
| - |
76 |
| -def start_random_workers(host, num_workers, sign_data, unix_socket): |
77 |
| - import random |
78 |
| - from tasq.remote.supervisor import Supervisors |
79 |
| - workers_set = set() |
80 |
| - init_port = 9000 |
81 |
| - while True: |
82 |
| - port = random.randint(init_port, 65000) |
83 |
| - if (host, port, port + 1) in workers_set: |
84 |
| - continue |
85 |
| - workers_set.add((host, port, port + 1)) |
86 |
| - if len(workers_set) == num_workers: |
87 |
| - break |
88 |
| - init_port = port + 2 |
89 |
| - supervisors = Supervisors(list(workers_set), sign_data=sign_data, unix_socket=unix_socket) |
90 |
| - supervisors.start_procs() |
91 |
| - |
92 |
| - |
93 |
| -def _translate_peers(workers): |
94 |
| - return [tuple(x.split(':')) for x in workers] |
| 94 | + supervisor = supervisor_factory.create(s_type, host=host, **kwargs) |
| 95 | + supervisor.serve_forever() |
95 | 96 |
|
96 | 97 |
|
97 | 98 | def main():
|
98 |
| - conf = get_config() |
99 |
| - parser = get_parser() |
100 |
| - args = parser.parse_args() |
101 |
| - if args.f: |
102 |
| - conf = get_config(path=args.f) |
103 |
| - host, port = conf['host'], conf['port'] |
104 |
| - verbose = conf['verbose'] |
| 99 | + args = parse_arguments() |
| 100 | + conf = get_config(args.conf) |
| 101 | + logger.loglevel = args.log_level or conf['log_level'] |
105 | 102 | sign_data = conf['sign_data']
|
106 | 103 | unix_socket = conf['unix_socket']
|
107 |
| - num_workers = 4 |
108 |
| - db = 0 |
109 |
| - worker_type = WorkerType.ActorWorker |
110 |
| - if args.verbose: |
111 |
| - verbose = True |
112 |
| - if args.secure: |
113 |
| - sign_data = True |
114 |
| - if args.unix: |
115 |
| - unix_socket = True |
116 |
| - if args.num_workers: |
117 |
| - num_workers = args.num_workers |
118 |
| - if args.worker_type: |
119 |
| - try: |
120 |
| - worker_type = WorkerType(args.worker_type) |
121 |
| - except ValueError: |
122 |
| - print(f"{args.worker_type} is not a valid type: use either process " |
123 |
| - "or actor. Fallbacking to actor") |
124 |
| - if args.workers: |
125 |
| - try: |
126 |
| - pairs = conf['workers'] |
127 |
| - except KeyError: |
128 |
| - pairs = args.workers |
129 |
| - if not pairs: |
130 |
| - print("No [host:port] list specified") |
131 |
| - else: |
132 |
| - workers = _translate_peers(pairs) |
133 |
| - else: |
134 |
| - workers = _translate_peers(args.workers or conf['workers']) |
135 |
| - start_workers(workers, sign_data, unix_socket) |
| 104 | + num_workers = args.num_workers or conf['num_workers'] |
| 105 | + worker_type = args.worker_type or 'actor' |
| 106 | + addr = args.address or conf['addr'] |
136 | 107 | if args.subcommand == 'worker':
|
137 |
| - if args.addr: |
138 |
| - host = args.addr |
139 |
| - if args.port: |
140 |
| - port = int(args.port) |
141 |
| - start_worker(host, port, sign_data, unix_socket, worker_type) |
142 |
| - elif args.subcommand == 'redis': |
143 |
| - if args.addr: |
144 |
| - host = args.addr |
145 |
| - port = 6379 |
146 |
| - if args.port: |
147 |
| - port = int(args.port) |
148 |
| - if args.db: |
149 |
| - db = int(args.db) |
150 |
| - name = args.name or 'redis-queue' |
151 |
| - start_redis_worker(host, port, db, name, sign_data, worker_type) |
152 |
| - elif args.subcommand == 'rabbitmq': |
153 |
| - if args.addr: |
154 |
| - host = args.addr |
155 |
| - port = 5672 |
156 |
| - if args.port: |
157 |
| - port = int(args.port) |
158 |
| - name = args.name or 'rabbitmq-queue' |
159 |
| - start_rabbitmq_worker(host, port, name, sign_data, worker_type) |
160 |
| - elif args.random: |
161 |
| - start_random_workers(host, int(args.random), sign_data, unix_socket) |
| 108 | + push_port = args.plport or conf['zmq']['push_port'] |
| 109 | + pull_port = args.port or conf['zmq']['pull_port'] |
| 110 | + start_worker('zmq', worker_type, addr, push_port=push_port, |
| 111 | + pull_port=pull_port, sign_data=sign_data, |
| 112 | + unix_socket=unix_socket) |
| 113 | + elif args.subcommand == 'redis-worker': |
| 114 | + port = args.port or conf['redis']['port'] |
| 115 | + db = args.db or conf['redis']['db'] |
| 116 | + name = args.name or conf['redis']['name'] |
| 117 | + start_worker('redis', worker_type, addr, port, |
| 118 | + db=db, name=name, sign_data=sign_data) |
| 119 | + elif args.subcommand == 'rabbitmq-worker': |
| 120 | + port = args.port or conf['rabbitmq']['port'] |
| 121 | + name = args.name or conf['rabbitmq']['name'] |
| 122 | + start_worker('rabbitmq', worker_type, addr, |
| 123 | + port, name=name, sign_data=sign_data) |
0 commit comments