1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 Serializable objects from worker through manager to admin for
24 planet, flow, job and component.
25 """
26
27 from twisted.spread import pb
28 from twisted.internet import defer
29
30 from flumotion.twisted import flavors
31 from flumotion.twisted.compat import implements
32 from flumotion.common import enum, log
33
35 """
36 I represent the state of a planet in the manager.
37
38 I have the following keys:
39
40 - name
41 - manager
42 - atmosphere: L{ManagerAtmosphereState}
43 - flows (list): list of L{ManagerFlowState}
44 """
45
57
59 """
60 Return a list of all component states in this planet
61 (from atmosphere and all flows).
62
63 @rtype: list of L{ManagerComponentState}
64 """
65 list = []
66
67 a = self.get('atmosphere')
68 if a:
69 list.extend(a.get('components'))
70
71 flows = self.get('flows')
72 if flows:
73 for flow in flows:
74 list.extend(flow.get('components'))
75
76 return list
77
78
80 """
81 I represent the state of a planet in an admin client.
82 See L{ManagerPlanetState}.
83 """
91
92 pb.setUnjellyableForClass(ManagerPlanetState, AdminPlanetState)
93
95 """
96 I represent the state of an atmosphere in the manager.
97 The atmosphere contains components that do not participate in a flow,
98 but provide services to flow components.
99
100 I have the following keys:
101
102 - name: string, "atmosphere"
103 - parent: L{ManagerPlanetState}
104 - components (list): list of L{ManagerComponentState}
105 """
106
113
115 """
116 Clear out all component entries.
117
118 @returns: a DeferredList that will fire when all notifications are done.
119 """
120 list = [self.remove('components', c) for c in self.get('components')]
121 return defer.DeferredList(list)
122
124 """
125 I represent the state of an atmosphere in an admin client.
126 See L{ManagerAtmosphereState}.
127 """
133
134 pb.setUnjellyableForClass(ManagerAtmosphereState, AdminAtmosphereState)
135
137 """
138 I represent the state of a flow in the manager.
139
140 I have the following keys:
141
142 - name: string, name of the flow
143 - parent: L{ManagerPlanetState}
144 - components (list): list of L{ManagerComponentState}
145 """
147 """
148 ManagerFlowState constructor. Any keyword arguments are
149 intepreted as initial key-value pairs to set on the new
150 ManagerFlowState.
151 """
152 flavors.StateCacheable.__init__(self)
153 self.addKey('name')
154 self.addKey('parent')
155 self.addListKey('components')
156 for k, v in kwargs.items():
157 self.set(k, v)
158
160 """
161 Clear out all component entries
162 """
163
164 components = self.get('components')[:]
165
166 list = [self.remove('components', c) for c in components]
167 return defer.DeferredList(list)
168
170 """
171 I represent the state of a flow in an admin client.
172 See L{ManagerFlowState}.
173 """
179
180 pb.setUnjellyableForClass(ManagerFlowState, AdminFlowState)
181
182
183
184 """
185 @cvar moods: an enum representing the mood a component can be in.
186 """
187 moods = enum.EnumClass(
188 'Moods',
189 ('happy', 'hungry', 'waking', 'sleeping', 'lost', 'sad')
190 )
191 moods.can_stop = staticmethod(lambda m: m != moods.sleeping and m != moods.lost)
192 moods.can_start = staticmethod(lambda m: m == moods.sleeping)
193
194 _jobStateKeys = ['mood', 'manager-ip', 'pid', 'workerName', 'cpu']
195 _jobStateListKeys = ['messages', ]
196
197
199 """
200 I represent the state of a component in the manager.
201 I have my own state, and also proxy state from the L{ManagerJobState}
202 when the component is actually created in a worker.
203
204 I have the following keys of my own:
205
206 - name: str, name of the component, unique in the parent
207 - parent: L{ManagerFlowState} or L{ManagerAtmosphereState}
208 - type: str, type of the component
209 - moodPending: int, the mood value the component is being set to
210 - workerRequested: str, name of the worker this component is
211 requested to be started on.
212 - config: dict, the configuration dict for this component
213
214 It also has a special key, 'mood'. This acts as a proxy for the mood
215 in the L{WorkerJobState}, when there is a job attached (the job's copy
216 is authoritative when it connects), and is controlled independently at
217 other times.
218
219 I proxy the following keys from the serialized L{WorkerJobState}:
220 - mood, manager-ip, pid, workerName, cpu
221 - messages (list)
222 """
223
240
242 return "<ManagerComponentState %s>" % self._dict['name']
243
273 return event
274
275 jobState.addListener(self, proxy('set'), proxy('append'),
276 proxy('remove'))
277
279 log.debug('componentstate', 'told to change mood from %s to %d',
280 self.get('mood'), moodValue)
281 if self._jobState and moodValue != moods.sad.value:
282 log.warning('componentstate', 'cannot set component mood to '
283 'something other than sad when we have a '
284 'jobState -- fix your code!')
285 else:
286 self.set('mood', moodValue)
287
289 """
290 Remove the job state.
291 """
292 self._jobState.removeListener(self)
293 self._jobState = None
294
296 """
297 I represent the state of a component in the admin client.
298 See L{ManagerComponentState}.
299 """
301 return "<AdminComponentState %s>" % self._dict['name']
302
303 pb.setUnjellyableForClass(ManagerComponentState, AdminComponentState)
304
305
306
308 """
309 I represent the state of a job in the worker, running a component.
310
311 I have the following keys:
312
313 - mood: int, value of the mood this component is in
314 - ip: string, IP address of the worker
315 - pid: int, PID of the job process
316 - workerName: string, name of the worker I'm running on
317 - cpu: float, CPU usage
318 - messages: list of L{flumotion.common.messages.Message}
319
320 In addition, if I am the state of a FeedComponent, then I also
321 have the following keys:
322
323 - eaterNames: list of feedId being eaten by the eaters
324 - feederNames: list of feedId being fed by the feeders
325
326 @todo: change eaterNames and feederNames to eaterFeedIds and ...
327 """
334
336 """
337 I represent the state of a job in the manager.
338 See L{WorkerJobState}.
339 """
340 pass
341
342 pb.setUnjellyableForClass(WorkerJobState, ManagerJobState)
343