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

Side by Side Diff: third_party/twisted_8_1/twisted/application/service.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 #
5 """
6 Service architecture for Twisted
7
8 Services are arranged in a hierarchy. At the leafs of the hierarchy,
9 the services which actually interact with the outside world are started.
10 Services can be named or anonymous -- usually, they will be named if
11 there is need to access them through the hierarchy (from a parent or
12 a sibling).
13
14 Maintainer: U{Moshe Zadka<mailto:moshez@twistedmatrix.com>}
15 """
16
17 from zope.interface import implements, Interface, Attribute
18
19 from twisted.python.reflect import namedAny
20 from twisted.python import components
21 from twisted.internet import defer
22 from twisted.persisted import sob
23 from twisted.plugin import IPlugin
24
25 class IServiceMaker(Interface):
26 """
27 An object which can be used to construct services in a flexible
28 way.
29
30 This interface should most often be implemented along with
31 twisted.plugin.IPlugin, and will most often be used by the
32 'twistd' command.
33 """
34 tapname = Attribute(
35 "A short string naming this Twisted plugin, for example 'web' or "
36 "'pencil'. This name will be used as the subcommand of 'twistd'.")
37
38 description = Attribute(
39 "A brief summary of the features provided by this "
40 "Twisted application plugin.")
41
42 options = Attribute(
43 "A C{twisted.python.usage.Options} subclass defining the"
44 "configuration options for this application.")
45
46
47 def makeService(options):
48 """
49 Create and return an object providing
50 L{twisted.application.service.IService}.
51
52 @param options: A mapping (typically a C{dict} or
53 C{twisted.python.usage.Options} instance) of configuration
54 options to desired configuration values.
55 """
56
57
58
59 class ServiceMaker(object):
60 """
61 Utility class to simplify the definition of L{IServiceMaker} plugins.
62 """
63 implements(IPlugin, IServiceMaker)
64
65 def __init__(self, name, module, description, tapname):
66 self.name = name
67 self.module = module
68 self.description = description
69 self.tapname = tapname
70
71
72 def options():
73 def get(self):
74 return namedAny(self.module).Options
75 return get,
76 options = property(*options())
77
78
79 def makeService():
80 def get(self):
81 return namedAny(self.module).makeService
82 return get,
83 makeService = property(*makeService())
84
85
86
87 class IService(Interface):
88 """
89 A service.
90
91 Run start-up and shut-down code at the appropriate times.
92
93 @type name: C{string}
94 @ivar name: The name of the service (or None)
95 @type running: C{boolean}
96 @ivar running: Whether the service is running.
97 """
98
99 def setName(name):
100 """Set the name of the service.
101
102 @type name: C{str}
103 @raise RuntimeError: Raised if the service already has a parent.
104 """
105
106 def setServiceParent(parent):
107 """Set the parent of the service.
108
109 @type name: L{IServiceCollection}
110 @raise RuntimeError: Raised if the service already has a parent
111 or if the service has a name and the parent already has a child
112 by that name.
113 """
114
115 def disownServiceParent():
116 """Remove the parent of the service.
117
118 @rtype: L{Deferred}
119 @return: a deferred which is triggered when the service has
120 finished shutting down. If shutting down is immediate,
121 a value can be returned (usually, None).
122 """
123
124 def startService():
125 """Start the service."""
126
127 def stopService():
128 """Stop the service.
129
130 @rtype: L{Deferred}
131 @return: a deferred which is triggered when the service has
132 finished shutting down. If shutting down is immediate,
133 a value can be returned (usually, None).
134 """
135
136 def privilegedStartService():
137 """Do preparation work for starting the service.
138
139 Here things which should be done before changing directory,
140 root or shedding privileges are done."""
141
142
143 class Service:
144
145 """
146 Base class for services
147
148 Most services should inherit from this class. It handles the
149 book-keeping reponsibilities of starting and stopping, as well
150 as not serializing this book-keeping information.
151 """
152
153 implements(IService)
154
155 running = 0
156 name = None
157 parent = None
158
159 def __getstate__(self):
160 dict = self.__dict__.copy()
161 if dict.has_key("running"):
162 del dict['running']
163 return dict
164
165 def setName(self, name):
166 if self.parent is not None:
167 raise RuntimeError("cannot change name when parent exists")
168 self.name = name
169
170 def setServiceParent(self, parent):
171 if self.parent is not None:
172 self.disownServiceParent()
173 parent = IServiceCollection(parent, parent)
174 self.parent = parent
175 self.parent.addService(self)
176
177 def disownServiceParent(self):
178 d = self.parent.removeService(self)
179 self.parent = None
180 return d
181
182 def privilegedStartService(self):
183 pass
184
185 def startService(self):
186 self.running = 1
187
188 def stopService(self):
189 self.running = 0
190
191
192
193 class IServiceCollection(Interface):
194
195 """Collection of services.
196
197 Contain several services, and manage their start-up/shut-down.
198 Services can be accessed by name if they have a name, and it
199 is always possible to iterate over them.
200 """
201
202 def getServiceNamed(name):
203 """Get the child service with a given name.
204
205 @type name: C{str}
206 @rtype: L{IService}
207 @raise KeyError: Raised if the service has no child with the
208 given name.
209 """
210
211 def __iter__():
212 """Get an iterator over all child services"""
213
214 def addService(service):
215 """Add a child service.
216
217 @type service: L{IService}
218 @raise RuntimeError: Raised if the service has a child with
219 the given name.
220 """
221
222 def removeService(service):
223 """Remove a child service.
224
225 @type service: L{IService}
226 @raise ValueError: Raised if the given service is not a child.
227 @rtype: L{Deferred}
228 @return: a deferred which is triggered when the service has
229 finished shutting down. If shutting down is immediate,
230 a value can be returned (usually, None).
231 """
232
233
234
235 class MultiService(Service):
236
237 """Straightforward Service Container
238
239 Hold a collection of services, and manage them in a simplistic
240 way. No service will wait for another, but this object itself
241 will not finish shutting down until all of its child services
242 will finish.
243 """
244
245 implements(IServiceCollection)
246
247 def __init__(self):
248 self.services = []
249 self.namedServices = {}
250 self.parent = None
251
252 def privilegedStartService(self):
253 Service.privilegedStartService(self)
254 for service in self:
255 service.privilegedStartService()
256
257 def startService(self):
258 Service.startService(self)
259 for service in self:
260 service.startService()
261
262 def stopService(self):
263 Service.stopService(self)
264 l = []
265 services = list(self)
266 services.reverse()
267 for service in services:
268 l.append(defer.maybeDeferred(service.stopService))
269 return defer.DeferredList(l)
270
271 def getServiceNamed(self, name):
272 return self.namedServices[name]
273
274 def __iter__(self):
275 return iter(self.services)
276
277 def addService(self, service):
278 if service.name is not None:
279 if self.namedServices.has_key(service.name):
280 raise RuntimeError("cannot have two services with same name"
281 " '%s'" % service.name)
282 self.namedServices[service.name] = service
283 self.services.append(service)
284 if self.running:
285 # It may be too late for that, but we will do our best
286 service.privilegedStartService()
287 service.startService()
288
289 def removeService(self, service):
290 if service.name:
291 del self.namedServices[service.name]
292 self.services.remove(service)
293 if self.running:
294 # Returning this so as not to lose information from the
295 # MultiService.stopService deferred.
296 return service.stopService()
297 else:
298 return None
299
300
301
302 class IProcess(Interface):
303
304 """Process running parameters
305
306 Represents parameters for how processes should be run.
307
308 @ivar processName: the name the process should have in ps (or None)
309 @type processName: C{str}
310 @ivar uid: the user-id the process should run under.
311 @type uid: C{int}
312 @ivar gid: the group-id the process should run under.
313 @type gid: C{int}
314 """
315
316
317 class Process:
318 """Process running parameters
319
320 Sets up uid/gid in the constructor, and has a default
321 of C{None} as C{processName}.
322 """
323 implements(IProcess)
324 processName = None
325
326 def __init__(self, uid=None, gid=None):
327 """Set uid and gid.
328
329 @param uid: The user ID as whom to execute the process. If
330 this is None, no attempt will be made to change the UID.
331
332 @param gid: The group ID as whom to execute the process. If
333 this is None, no attempt will be made to change the GID.
334 """
335 self.uid = uid
336 self.gid = gid
337
338
339 def Application(name, uid=None, gid=None):
340 """Return a compound class.
341
342 Return an object supporting the L{IService}, L{IServiceCollection},
343 L{IProcess} and L{sob.IPersistable} interfaces, with the given
344 parameters. Always access the return value by explicit casting to
345 one of the interfaces.
346 """
347 ret = components.Componentized()
348 for comp in (MultiService(), sob.Persistent(ret, name), Process(uid, gid)):
349 ret.addComponent(comp, ignoreClass=1)
350 IService(ret).setName(name)
351 return ret
352
353
354
355 def loadApplication(filename, kind, passphrase=None):
356 """Load Application from a given file.
357
358 The serialization format it was saved in should be given as
359 C{kind}, and is one of 'pickle', 'source', 'xml' or 'python'. If
360 C{passphrase} is given, the application was encrypted with the
361 given passphrase.
362
363 @type filename: C{str}
364 @type kind: C{str}
365 @type passphrase: C{str}
366 """
367 if kind == 'python':
368 application = sob.loadValueFromFile(filename, 'application', passphrase)
369 else:
370 application = sob.load(filename, kind, passphrase)
371 return application
372
373
374 __all__ = ['IServiceMaker', 'IService', 'Service',
375 'IServiceCollection', 'MultiService',
376 'IProcess', 'Process', 'Application', 'loadApplication']
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/application/reactors.py ('k') | third_party/twisted_8_1/twisted/application/strports.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698