1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Copyright (c) 2010 Google Inc. All rights reserved.
2cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#
3cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# Redistribution and use in source and binary forms, with or without
4cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# modification, are permitted provided that the following conditions are
5cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# met:
6cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#
7cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#     * Redistributions of source code must retain the above copyright
8cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# notice, this list of conditions and the following disclaimer.
9cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#     * Redistributions in binary form must reproduce the above
10cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# copyright notice, this list of conditions and the following disclaimer
11cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# in the documentation and/or other materials provided with the
12cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# distribution.
13cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#     * Neither the name of Google Inc. nor the names of its
14cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# contributors may be used to endorse or promote products derived from
15cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# this software without specific prior written permission.
16cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#
17cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
29cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass MessagePumpDelegate(object):
31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def schedule(self, interval, callback):
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
33cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def message_available(self, message):
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
36cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def final_message_delivered(self):
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        raise NotImplementedError, "subclasses must implement"
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass MessagePump(object):
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    interval = 10 # seconds
43cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def __init__(self, delegate, message_queue):
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._delegate = delegate
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._message_queue = message_queue
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._schedule()
48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def _schedule(self):
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._delegate.schedule(self.interval, self._callback)
51cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def _callback(self):
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        (messages, is_running) = self._message_queue.take_all()
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for message in messages:
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            self._delegate.message_available(message)
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if not is_running:
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            self._delegate.final_message_delivered()
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        self._schedule()
60