~didrocks/ubuntuone-client/dont-suffer-zg-crash

« back to all changes in this revision

Viewing changes to ubuntuone/syncdaemon/states.py

  • Committer: Bazaar Package Importer
  • Author(s): Rodney Dawes
  • Date: 2011-01-25 16:42:52 UTC
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: james.westby@ubuntu.com-20110125164252-rl1pybasx1nsqgoy
Tags: upstream-1.5.3
ImportĀ upstreamĀ versionĀ 1.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
226
226
    """A smaller finite state machine to handle queues."""
227
227
 
228
228
    IDLE = Node('IDLE', "nothing in the queues")
229
 
    WORKING_ON_METADATA = Node('WORKING_ON_METADATA', "working on metadata")
230
 
    WORKING_ON_CONTENT = Node('WORKING_ON_CONTENT', "working con content")
231
 
    WORKING_ON_BOTH = Node('WORKING_ON_BOTH', "working on both")
 
229
    WORKING = Node('WORKING', "working on the commands queue")
232
230
 
233
231
    def __init__(self, state_manager):
234
232
        self.sm = state_manager
235
 
        self.cq = state_manager.aq.content_queue
236
 
        self.mq = state_manager.aq.meta_queue
 
233
        self.queue = state_manager.aq.queue
237
234
        self.state = self.IDLE
238
235
        self.log = logging.getLogger("ubuntuone.SyncDaemon.QueueManager")
239
236
        self.log.debug("start")
244
241
        self.state = new_state
245
242
 
246
243
    def on_event(self, event):
247
 
        """Handle transitions between working queues."""
 
244
        """Handle transitions."""
248
245
        prv_state = self.state
249
246
        if self.state == self.IDLE:
250
 
            if event == 'SYS_META_QUEUE_WAITING':
251
 
                self._set_state(self.WORKING_ON_METADATA)
252
 
                self._run(self.mq)
253
 
            elif event == 'SYS_CONTENT_QUEUE_WAITING':
254
 
                self._set_state(self.WORKING_ON_CONTENT)
255
 
                self._run(self.cq)
256
 
            else:
257
 
                self._bad_event(event)
258
 
 
259
 
        elif self.state == self.WORKING_ON_METADATA:
260
 
            if event == 'SYS_META_QUEUE_WAITING':
261
 
                self._run(self.mq)
262
 
            elif event == 'SYS_META_QUEUE_DONE':
263
 
                self._set_state(self.IDLE)
264
 
            elif event == 'SYS_CONTENT_QUEUE_WAITING':
265
 
                self._set_state(self.WORKING_ON_BOTH)
266
 
            else:
267
 
                self._bad_event(event)
268
 
 
269
 
        elif self.state == self.WORKING_ON_CONTENT:
270
 
            if event == 'SYS_META_QUEUE_WAITING':
271
 
                self._set_state(self.WORKING_ON_BOTH)
272
 
                self._run(self.mq)
273
 
            elif event == 'SYS_CONTENT_QUEUE_WAITING':
274
 
                self._run(self.cq)
275
 
            elif event == 'SYS_CONTENT_QUEUE_DONE':
276
 
                self._set_state(self.IDLE)
277
 
            else:
278
 
                self._bad_event(event)
279
 
 
280
 
        elif self.state == self.WORKING_ON_BOTH:
281
 
            if event == 'SYS_META_QUEUE_WAITING':
282
 
                self._run(self.mq)
283
 
            elif event == 'SYS_META_QUEUE_DONE':
284
 
                self._set_state(self.WORKING_ON_CONTENT)
285
 
                self._run(self.cq)
286
 
            elif event == 'SYS_CONTENT_QUEUE_WAITING':
287
 
                pass # same node, no run()
288
 
            elif event == 'SYS_CONTENT_QUEUE_DONE':
289
 
                self._set_state(self.WORKING_ON_METADATA)
 
247
            if event == 'SYS_QUEUE_WAITING':
 
248
                self._set_state(self.WORKING)
 
249
            else:
 
250
                self._bad_event(event)
 
251
 
 
252
        elif self.state == self.WORKING:
 
253
            if event == 'SYS_QUEUE_DONE':
 
254
                self._set_state(self.IDLE)
290
255
            else:
291
256
                self._bad_event(event)
292
257
 
299
264
    def on_enter(self, new_node):
300
265
        """Called when SM gets into a new node."""
301
266
        if new_node == StateManager.QUEUE_MANAGER:
302
 
            if self.state == self.WORKING_ON_CONTENT:
303
 
                self._run(self.cq)
304
 
            elif self.state in (self.WORKING_ON_METADATA, self.WORKING_ON_BOTH):
305
 
                self._run(self.mq)
 
267
            self.queue.run()
306
268
 
307
269
    def _bad_event(self, event):
308
270
        """Log the bad event."""
309
271
        m = "Bad Event received: Got %r while in %s"
310
272
        self.log.warning(m, event, self.state)
311
273
 
312
 
    def _run(self, queue):
313
 
        """Execute queue.run() if conditions are ok.
314
 
 
315
 
        Conditions:
316
 
 
317
 
        - the queue needs to have something to run
318
 
 
319
 
        - the global state should be this QueueManager
320
 
        """
321
 
        if len(queue) and self.sm.state == StateManager.QUEUE_MANAGER:
322
 
            self.log.debug("In %s: running %s", self.state.name, queue.name)
323
 
            queue.run()
324
 
 
325
274
 
326
275
ACCEPTED_EVENTS = [
327
276
    'SYS_AUTH_ERROR',
330
279
    'SYS_CONNECTION_LOST',
331
280
    'SYS_CONNECTION_MADE',
332
281
    'SYS_CONNECTION_RETRY',
333
 
    'SYS_CONTENT_QUEUE_DONE',
334
 
    'SYS_CONTENT_QUEUE_WAITING',
 
282
    'SYS_QUEUE_DONE',
 
283
    'SYS_QUEUE_WAITING',
335
284
    'SYS_HANDSHAKE_TIMEOUT',
336
285
    'SYS_INIT_DONE',
337
286
    'SYS_LOCAL_RESCAN_DONE',
338
 
    'SYS_META_QUEUE_DONE',
339
 
    'SYS_META_QUEUE_WAITING',
340
287
    'SYS_NET_CONNECTED',
341
288
    'SYS_NET_DISCONNECTED',
342
289
    'SYS_PROTOCOL_VERSION_ERROR',
343
290
    'SYS_PROTOCOL_VERSION_OK',
 
291
    'SYS_QUIT',
344
292
    'SYS_ROOT_MISMATCH',
345
293
    'SYS_SERVER_RESCAN_DONE',
346
294
    'SYS_SERVER_ERROR',
373
321
 
374
322
    SERVER_RESCAN = Node('SERVER_RESCAN', "doing server rescan", conn=True)
375
323
 
376
 
    QUEUE_MANAGER = Node('QUEUE_MANAGER', "processing queues",
 
324
    QUEUE_MANAGER = Node('QUEUE_MANAGER', "processing the commands pool",
377
325
                         conn=True, online=True)
378
326
 
379
327
    STANDOFF = Node('STANDOFF', "waiting for connection to end", conn=True)
382
330
                         "different", error=True)
383
331
    UNKNOWN_ERROR = Node('UNKNOWN_ERROR', "something went wrong", error=True)
384
332
 
 
333
    SHUTDOWN = Node('SHUTDOWN', "shutting down the service")
 
334
 
385
335
    def __init__(self, main, handshake_timeout=None):
386
336
        self.main = main
387
337
        self.aq = main.action_q
434
384
            return
435
385
        self.log.debug("received event %r", event)
436
386
 
 
387
        # quit
 
388
        if event == 'SYS_QUIT':
 
389
            self._transition(event, StateManager.SHUTDOWN)
 
390
            return
 
391
 
437
392
        # error management
438
393
        if event == 'SYS_UNKNOWN_ERROR':
439
394
            self._transition(event, StateManager.UNKNOWN_ERROR)
445
400
            return
446
401
 
447
402
        # queue events
448
 
        if event in ('SYS_META_QUEUE_WAITING', 'SYS_META_QUEUE_DONE',
449
 
                     'SYS_CONTENT_QUEUE_WAITING', 'SYS_CONTENT_QUEUE_DONE'):
 
403
        if event in ('SYS_QUEUE_WAITING', 'SYS_QUEUE_DONE'):
450
404
            self.log.debug("sending event to QueueManager")
451
405
            changed = self.queues.on_event(event)
452
406
            if changed:
502
456
 
503
457
        # on exit actions
504
458
        if self.state == self.QUEUE_MANAGER:
505
 
            self.aq.cleanup()
 
459
            self.aq.queue.stop()
506
460
 
507
461
        # make the transition
508
462
        self.state = new_node