Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: infra/services/service_manager/config_watcher.py

Issue 1365583002: Have service_manager start a cloudtail attached to each service it starts. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Just use the default project ID Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import collections 5 import collections
6 import glob 6 import glob
7 import json 7 import json
8 import logging 8 import logging
9 import os.path 9 import os.path
10 import time 10 import time
(...skipping 15 matching lines...) Expand all
26 """Polls a directory for .json files describing services to be run. 26 """Polls a directory for .json files describing services to be run.
27 27
28 Tries to keep the running services in sync with the config files - services 28 Tries to keep the running services in sync with the config files - services
29 are started immediately when valid configs are added, restarted when their 29 are started immediately when valid configs are added, restarted when their
30 configs change (adding or removing args for example), and stopped when the 30 configs change (adding or removing args for example), and stopped when the
31 configs are deleted. 31 configs are deleted.
32 """ 32 """
33 33
34 def __init__(self, config_directory, config_poll_interval, 34 def __init__(self, config_directory, config_poll_interval,
35 service_poll_interval, state_directory, root_directory, 35 service_poll_interval, state_directory, root_directory,
36 cloudtail_path,
36 sleep_fn=time.sleep): 37 sleep_fn=time.sleep):
37 """ 38 """
38 Args: 39 Args:
39 config_directory: Directory containing .json config files to monitor. 40 config_directory: Directory containing .json config files to monitor.
40 config_poll_interval: How often (in seconds) to poll config_directory 41 config_poll_interval: How often (in seconds) to poll config_directory
41 for changes. 42 for changes.
42 service_poll_interval: How often (in seconds) to restart failed services. 43 service_poll_interval: How often (in seconds) to restart failed services.
43 state_directory: A file will be created in this directory (with the same 44 state_directory: A file will be created in this directory (with the same
44 name as the service) when it is running containing its PID and 45 name as the service) when it is running containing its PID and
45 starttime. 46 starttime.
47 cloudtail_path: Path to the cloudtail binary to use for logging, or None
48 if logging is disabled.
46 """ 49 """
47 50
48 self._config_glob = os.path.join(config_directory, '*.json') 51 self._config_glob = os.path.join(config_directory, '*.json')
49 self._config_poll_interval = config_poll_interval 52 self._config_poll_interval = config_poll_interval
50 self._service_poll_interval = service_poll_interval 53 self._service_poll_interval = service_poll_interval
51 self._state_directory = state_directory 54 self._state_directory = state_directory
55 self._cloudtail_path = cloudtail_path
52 56
53 self._metadata = {} # Filename -> _Metadata 57 self._metadata = {} # Filename -> _Metadata
54 self._services = {} # Service name -> Filename 58 self._services = {} # Service name -> Filename
55 self._stop = False 59 self._stop = False
56 60
57 self._sleep_fn = sleep_fn 61 self._sleep_fn = sleep_fn
58 62
59 self._own_service = service.OwnService(state_directory, root_directory) 63 self._own_service = service.OwnService(state_directory, root_directory)
60 64
61 def run(self): 65 def run(self):
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 if config['name'] in self._services: 130 if config['name'] in self._services:
127 LOGGER.error('Duplicate service name "%s" (defined in %s and %s)' % ( 131 LOGGER.error('Duplicate service name "%s" (defined in %s and %s)' % (
128 config['name'], self._services[config['name']], filename)) 132 config['name'], self._services[config['name']], filename))
129 return 133 return
130 134
131 LOGGER.info('Adding new service config for %s', config['name']) 135 LOGGER.info('Adding new service config for %s', config['name'])
132 136
133 thread = service_thread.ServiceThread( 137 thread = service_thread.ServiceThread(
134 self._service_poll_interval, 138 self._service_poll_interval,
135 self._state_directory, 139 self._state_directory,
136 config) 140 config,
141 self._cloudtail_path)
137 thread.start() 142 thread.start()
138 thread.start_service() 143 thread.start_service()
139 self._metadata[filename] = _Metadata(mtime, config, thread) 144 self._metadata[filename] = _Metadata(mtime, config, thread)
140 self._services[config['name']] = filename 145 self._services[config['name']] = filename
141 146
142 def _config_changed(self, filename, metadata, new_mtime): 147 def _config_changed(self, filename, metadata, new_mtime):
143 if metadata.config is not None: 148 if metadata.config is not None:
144 del self._services[metadata.config['name']] 149 del self._services[metadata.config['name']]
145 150
146 metadata.config = self._load_config(filename) 151 metadata.config = self._load_config(filename)
(...skipping 11 matching lines...) Expand all
158 if metadata.thread is not None: 163 if metadata.thread is not None:
159 metadata.thread.stop_service() 164 metadata.thread.stop_service()
160 return 165 return
161 166
162 LOGGER.info('Updating service config for %s', metadata.config['name']) 167 LOGGER.info('Updating service config for %s', metadata.config['name'])
163 168
164 if metadata.thread is None: 169 if metadata.thread is None:
165 metadata.thread = service_thread.ServiceThread( 170 metadata.thread = service_thread.ServiceThread(
166 self._service_poll_interval, 171 self._service_poll_interval,
167 self._state_directory, 172 self._state_directory,
168 metadata.config) 173 metadata.config,
174 self._cloudtail_path)
169 metadata.thread.start() 175 metadata.thread.start()
170 metadata.thread.start_service() 176 metadata.thread.start_service()
171 else: 177 else:
172 metadata.thread.restart_with_new_config(metadata.config) 178 metadata.thread.restart_with_new_config(metadata.config)
173 179
174 self._services[metadata.config['name']] = filename 180 self._services[metadata.config['name']] = filename
175 181
176 def _config_removed(self, metadata): 182 def _config_removed(self, metadata):
177 LOGGER.info('Removing service config for %s', metadata.config['name']) 183 LOGGER.info('Removing service config for %s', metadata.config['name'])
178 184
179 del self._services[metadata.config['name']] 185 del self._services[metadata.config['name']]
180 186
181 metadata.config = None 187 metadata.config = None
182 metadata.mtime = None 188 metadata.mtime = None
183 metadata.thread.stop_service() 189 metadata.thread.stop_service()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698