commit 042f8ef832ff969532b0915cb5b77cc58fcea60e
parent 43df795b1ffc2e99b45ff406670da1e44cb60b0d
Author: ThomasV <thomasv@electrum.org>
Date: Thu, 26 Nov 2015 11:26:01 +0100
network: cache subscription responses
Diffstat:
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/lib/network.py b/lib/network.py
@@ -168,6 +168,7 @@ class Network(util.DaemonThread):
self.utxo_roots = {}
# callbacks passed with subscriptions
self.subscriptions = defaultdict(list)
+ self.sub_cache = {}
# callbacks set by the GUI
self.callbacks = defaultdict(list)
@@ -275,6 +276,7 @@ class Network(util.DaemonThread):
def send_subscriptions(self):
self.print_error('sending subscriptions to', self.interface.server, len(self.unanswered_requests), len(self.subscribed_addresses))
+ self.sub_cache.clear()
# Resend unanswered requests
requests = self.unanswered_requests.values()
self.unanswered_requests = {}
@@ -462,6 +464,7 @@ class Network(util.DaemonThread):
error = response.get('error')
result = response.get('result')
method = response.get('method')
+ params = response.get('params')
# We handle some responses; return the rest to the client.
if method == 'server.version':
@@ -486,9 +489,11 @@ class Network(util.DaemonThread):
self.on_get_chunk(interface, response)
elif method == 'blockchain.block.get_header':
self.on_get_header(interface, response)
- else:
- params = response['params']
- callbacks = self.subscriptions.get(repr((method, params)), [])
+
+ elif method.endswith('.subscribe'):
+ k = repr((method, params))
+ self.sub_cache[k] = response
+ callbacks = self.subscriptions.get(k, [])
for callback in callbacks:
callback(response)
@@ -496,7 +501,6 @@ class Network(util.DaemonThread):
responses = interface.get_responses()
for request, response in responses:
- callback = None
if request:
method, params, message_id = request
# client requests go through self.send() with a
@@ -505,7 +509,6 @@ class Network(util.DaemonThread):
client_req = self.unanswered_requests.pop(message_id, None)
if client_req:
assert interface == self.interface
-
# Copy the request method and params to the response
response['method'] = method
response['params'] = params
@@ -534,14 +537,23 @@ class Network(util.DaemonThread):
'''Messages is a list of (method, params) tuples'''
with self.lock:
subs = filter(lambda (m,v): m.endswith('.subscribe'), messages)
- for method, params in subs:
- k = repr((method, params))
- l = self.subscriptions.get(k, [])
- if callback not in l:
- l.append(callback)
- self.subscriptions[k] = l
-
- self.pending_sends += messages
+ for message in messages:
+ method, params = message
+ if method.endswith('.subscribe'):
+ k = repr((method, params))
+ l = self.subscriptions.get(k, [])
+ if callback not in l:
+ l.append(callback)
+ self.subscriptions[k] = l
+ # check cached response
+ r = self.sub_cache.get(k)
+ if r is not None:
+ util.print_error("cache hit", k)
+ callback(r)
+ else:
+ self.pending_sends.append(message)
+ else:
+ self.pending_sends.append(message)
def process_pending_sends(self):