-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmessageboard.py
More file actions
80 lines (68 loc) · 3.17 KB
/
messageboard.py
File metadata and controls
80 lines (68 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
'''
Copyright © 2016 Daniel Müllner <http://danifold.net>
All changes from 2017-12-27 on: Copyright © Google Inc. <http://google.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
from collections import OrderedDict
import weakref
from rwlock import RWLock, RWLockReaderPriority
class MessageBoard:
def __init__(self):
self.messages = {}
self.messageLock = RWLock()
self.subscriptions = {}
self.subscriptionLock = RWLockReaderPriority()
def post(self, heading, message):
with self.messageLock.write_access:
self.messages[heading] = message
with self.subscriptionLock.read_access:
if heading in self.subscriptions:
for wr, callback in self.subscriptions[heading].iteritems():
instance = wr()
if instance is not None:
callback(instance, message)
def query(self, heading):
with self.messageLock.read_access:
if heading in self.messages:
return self.messages[heading]
def subscribe(self, heading, instance, callback):
with self.subscriptionLock.write_access:
if not heading in self.subscriptions:
self.subscriptions[heading] = OrderedDict()
wr = weakref.ref(instance)
assert wr not in self.subscriptions[heading]
self.subscriptions[heading][wr] = callback
def unsubscribe(self, heading, instance):
with self.subscriptionLock.write_access:
wr = weakref.ref(instance)
if heading in self.subscriptions and wr in self.subscriptions[heading]:
del self.subscriptions[heading][wr]
if not self.subscriptions[heading]:
del self.subscriptions[heading]
def unsubscribeAll(self, instance):
with self.subscriptionLock.write_access:
wr = weakref.ref(instance)
for heading in list(self.subscriptions):
if wr in self.subscriptions[heading]:
del self.subscriptions[heading][wr]
if not self.subscriptions[heading]:
del self.subscriptions[heading]
def ask(self, heading, message):
with self.subscriptionLock.read_access:
if heading in self.subscriptions:
for wr, callback in self.subscriptions[heading].iteritems():
instance = wr()
if instance is not None:
return callback(instance, message)
messageboard = MessageBoard()