Changeset c9c68cb4856333078390a4fedecaed57636682bc
- Timestamp:
- 05/28/2011 02:56:31 PM (2 years ago)
- Author:
- Loic Dachary <loic@…>
- Children:
- cbaf5abc0bd22defc08e9cee4c5e9ba77daf7791
- Parents:
- aff7187e7c0c6e5a15b2ac000e44a46a8f578b10
- git-committer:
- Loic Dachary <loic@…> (05/28/2011 02:56:31 PM)
- Message:
-
Add the listen and notify functions to CardstoriesServices?. listen() returns a deferred that will be called when a) the service is started (type start), b) the service is stopped (type stop), c) a game is deleted (type delete), d) a game has changed (type change). The result argument of the callback is a map with a "type" member set as explained above. When the type is either "delete" or "change", it the "game" member is the CardstoriesGame? object to which the even relates. The "detail" member further describes the event when the "type" is "change" or it is set to None when the "type" is "delete". refs#62
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r2c789e9
|
rc9c68cb
|
|
| 55 | 55 | self.games = {} |
| 56 | 56 | self.players = {} |
| | 57 | self.listeners = [] |
| | 58 | |
| | 59 | def listen(self): |
| | 60 | d = defer.Deferred() |
| | 61 | self.listeners.append(d) |
| | 62 | return d |
| | 63 | |
| | 64 | def notify(self, result): |
| | 65 | if hasattr(self, 'notify_running'): |
| | 66 | raise UserWarning, 'recursive call to notify' |
| | 67 | self.notify_running = True |
| | 68 | listeners = self.listeners |
| | 69 | self.listeners = [] |
| | 70 | def error(reason): |
| | 71 | reason.printDetailedTraceback() |
| | 72 | return True |
| | 73 | for listener in listeners: |
| | 74 | listener.addErrback(error) |
| | 75 | listener.callback(result) |
| | 76 | del self.notify_running |
| 57 | 77 | |
| 58 | 78 | def startService(self): |
| … |
… |
|
| 69 | 89 | db.close() |
| 70 | 90 | self.db = adbapi.ConnectionPool("sqlite3", database=database, cp_noisy=True) |
| | 91 | self.notify({'type': 'start'}) |
| 71 | 92 | |
| 72 | 93 | def stopService(self): |
| | 94 | self.notify({'type': 'stop'}) |
| 73 | 95 | for game in self.games.values(): |
| 74 | 96 | game.destroy() |
| … |
… |
|
| 171 | 193 | def game_notify(self, args, game_id): |
| 172 | 194 | if args == None: |
| | 195 | self.notify({'type': 'delete', 'game': self.games[game_id], 'details': args}) |
| 173 | 196 | del self.games[game_id] |
| 174 | 197 | return False |
| … |
… |
|
| 176 | 199 | return False |
| 177 | 200 | game = self.games[game_id] |
| | 201 | self.notify({'type': 'change', 'game': game, 'details': args}) |
| 178 | 202 | for player_id in game.get_players(): |
| 179 | 203 | if self.players.has_key(player_id): |
-
|
r2c789e9
|
rc9c68cb
|
|
| 32 | 32 | base.DelayedCall.debug = True |
| 33 | 33 | |
| | 34 | class CardstoriesServiceTestNotify(unittest.TestCase): |
| | 35 | |
| | 36 | def test00_notify(self): |
| | 37 | service = CardstoriesService({}) |
| | 38 | d = service.listen() |
| | 39 | def check(result): |
| | 40 | self.assertTrue(result) |
| | 41 | service.checked = True |
| | 42 | return result |
| | 43 | d.addCallback(check) |
| | 44 | service.notify(True) |
| | 45 | self.assertTrue(service.checked) |
| | 46 | |
| | 47 | def test01_notify_recursive(self): |
| | 48 | service = CardstoriesService({}) |
| | 49 | d = service.listen() |
| | 50 | def recurse(result): |
| | 51 | try: |
| | 52 | service.notify(False) |
| | 53 | except UserWarning, e: |
| | 54 | self.failUnlessSubstring('recurs', e.args[0]) |
| | 55 | service.recursed = True |
| | 56 | return result |
| | 57 | d.addCallback(recurse) |
| | 58 | service.notify(True) |
| | 59 | self.assertTrue(service.recursed) |
| | 60 | |
| | 61 | def test02_notify_ignore_exception(self): |
| | 62 | service = CardstoriesService({}) |
| | 63 | d = service.listen() |
| | 64 | def fail(result): |
| | 65 | service.raised = True |
| | 66 | raise UserWarning, 'raise exception' |
| | 67 | d.addCallback(fail) |
| | 68 | service.notify(True) |
| | 69 | self.assertTrue(service.raised) |
| | 70 | |
| 34 | 71 | class CardstoriesServiceTestInit(unittest.TestCase): |
| 35 | 72 | |
| … |
… |
|
| 38 | 75 | service = CardstoriesService({'db': database}) |
| 39 | 76 | self.assertFalse(os.path.exists(database)) |
| | 77 | def start(event): |
| | 78 | self.assertEqual(event['type'], 'start') |
| | 79 | service.notified_start = True |
| | 80 | return event |
| | 81 | service.listen().addCallback(start) |
| 40 | 82 | service.startService() |
| | 83 | self.assertTrue(service.notified_start) |
| 41 | 84 | self.assertTrue(os.path.exists(database)) |
| 42 | | return service.stopService() |
| | 85 | def stop(event): |
| | 86 | self.assertEqual(event['type'], 'stop') |
| | 87 | service.notified_stop = True |
| | 88 | return event |
| | 89 | service.listen().addCallback(stop) |
| | 90 | d = service.stopService() |
| | 91 | self.assertTrue(service.notified_stop) |
| | 92 | return d |
| 43 | 93 | |
| 44 | 94 | @defer.inlineCallbacks |
| … |
… |
|
| 395 | 445 | self.assertEquals(result['player_id'], [owner_id]) |
| 396 | 446 | self.assertEquals(result['game_id'], [game.id]) |
| | 447 | game.checked = True |
| 397 | 448 | return result |
| 398 | 449 | d.addCallback(check) |
| | 450 | def change(event): |
| | 451 | self.assertTrue(event['type'], 'change') |
| | 452 | self.assertTrue(event['game'].get_id(), game.get_id()) |
| | 453 | game.changed = True |
| | 454 | self.service.listen().addCallback(change) |
| 399 | 455 | game.touch() # calls game_notify indirectly |
| | 456 | self.assertTrue(game.checked) |
| | 457 | self.assertTrue(game.changed) |
| | 458 | # |
| | 459 | # Event notification when a game is destroyed |
| | 460 | # |
| | 461 | def destroy(event): |
| | 462 | self.assertTrue(event['type'], 'delete') |
| | 463 | self.assertTrue(event['game'].get_id(), game.get_id()) |
| | 464 | game.destroyed = True |
| | 465 | self.service.listen().addCallback(destroy) |
| | 466 | game.destroy() |
| | 467 | self.assertTrue(game.destroyed) |
| 400 | 468 | # |
| 401 | 469 | # calling game_notify on a non existent game is a noop |
| … |
… |
|
| 564 | 632 | # loader.methodPrefix = "test11_" |
| 565 | 633 | suite = loader.suiteFactory() |
| | 634 | suite.addTest(loader.loadClass(CardstoriesServiceTestNotify)) |
| 566 | 635 | suite.addTest(loader.loadClass(CardstoriesServiceTestInit)) |
| 567 | 636 | suite.addTest(loader.loadClass(CardstoriesServiceTest)) |