Browse Source

Make exchange rate plugin a network thread job

This fixes a lot of thread error noise when closing down electrum.
master
Neil Booth 10 years ago
parent
commit
a5e0265010
  1. 5
      lib/network.py
  2. 52
      plugins/exchange_rate.py

5
lib/network.py

@ -17,6 +17,7 @@ from bitcoin import *
from interface import Connection, Interface from interface import Connection, Interface
from blockchain import Blockchain from blockchain import Blockchain
from version import ELECTRUM_VERSION, PROTOCOL_VERSION from version import ELECTRUM_VERSION, PROTOCOL_VERSION
from plugins import run_hook
DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'} DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'}
@ -132,7 +133,7 @@ class Network(util.DaemonThread):
- Member functions get_header(), get_interfaces(), get_local_height(), - Member functions get_header(), get_interfaces(), get_local_height(),
get_parameters(), get_server_height(), get_status_value(), get_parameters(), get_server_height(), get_status_value(),
is_connected(), new_blockchain_height(), set_parameters(), start(), is_connected(), new_blockchain_height(), set_parameters(),
stop() stop()
""" """
@ -750,6 +751,7 @@ class Network(util.DaemonThread):
self.process_responses(interface) self.process_responses(interface)
def run(self): def run(self):
run_hook('set_network', self)
self.blockchain.init() self.blockchain.init()
while self.is_running(): while self.is_running():
self.maintain_sockets() self.maintain_sockets()
@ -759,6 +761,7 @@ class Network(util.DaemonThread):
self.process_pending_sends() self.process_pending_sends()
self.stop_network() self.stop_network()
run_hook('set_network', None)
self.trigger_callback('stop') self.trigger_callback('stop')
self.print_error("stopped") self.print_error("stopped")

52
plugins/exchange_rate.py

@ -2,18 +2,15 @@ from PyQt4.QtGui import *
from PyQt4.QtCore import * from PyQt4.QtCore import *
import datetime import datetime
import decimal
import requests import requests
import json
import threading import threading
import time import time
import re
from ssl import SSLError
from decimal import Decimal from decimal import Decimal
from electrum.bitcoin import COIN from electrum.bitcoin import COIN
from electrum.plugins import BasePlugin, hook from electrum.plugins import BasePlugin, hook
from electrum.i18n import _ from electrum.i18n import _
from electrum.util import ThreadJob
from electrum_gui.qt.util import * from electrum_gui.qt.util import *
from electrum_gui.qt.amountedit import AmountEdit from electrum_gui.qt.amountedit import AmountEdit
@ -38,37 +35,29 @@ EXCH_SUPPORT_HIST = [("CoinDesk", "USD"),
("BitcoinVenezuela", "ARS"), ("BitcoinVenezuela", "ARS"),
("BitcoinVenezuela", "VEF")] ("BitcoinVenezuela", "VEF")]
class Exchanger(threading.Thread): class Exchanger(ThreadJob):
def __init__(self, parent): def __init__(self, parent):
threading.Thread.__init__(self)
self.daemon = True
self.parent = parent self.parent = parent
self.quote_currencies = None self.quote_currencies = None
self.lock = threading.Lock() self.timeout = 0
self.query_rates = threading.Event()
self.use_exchange = self.parent.config.get('use_exchange', "Blockchain") self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
self.parent.exchanges = EXCHANGES self.parent.exchanges = EXCHANGES
#self.parent.win.emit(SIGNAL("refresh_exchanges_combo()")) #self.parent.win.emit(SIGNAL("refresh_exchanges_combo()"))
#self.parent.win.emit(SIGNAL("refresh_currencies_combo()")) #self.parent.win.emit(SIGNAL("refresh_currencies_combo()"))
self.is_running = False
def get_json(self, site, get_string): def get_json(self, site, get_string):
resp = requests.request('GET', 'https://' + site + get_string, headers={"User-Agent":"Electrum"}) resp = requests.request('GET', 'https://' + site + get_string, headers={"User-Agent":"Electrum"})
return resp.json() return resp.json()
def exchange(self, btc_amount, quote_currency): def exchange(self, btc_amount, quote_currency):
with self.lock: if self.quote_currencies is None:
if self.quote_currencies is None: return None
return None quote_currencies = self.quote_currencies.copy()
quote_currencies = self.quote_currencies.copy()
if quote_currency not in quote_currencies: if quote_currency not in quote_currencies:
return None return None
return btc_amount * Decimal(str(quote_currencies[quote_currency])) return btc_amount * Decimal(str(quote_currencies[quote_currency]))
def stop(self):
self.is_running = False
def update_rate(self): def update_rate(self):
self.use_exchange = self.parent.config.get('use_exchange', "Blockchain") self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
update_rates = { update_rates = {
@ -92,18 +81,14 @@ class Exchanger(threading.Thread):
except Exception as e: except Exception as e:
self.parent.print_error(e) self.parent.print_error(e)
rates = {} rates = {}
with self.lock: self.quote_currencies = rates
self.quote_currencies = rates self.parent.set_currencies(rates)
self.parent.set_currencies(rates)
self.parent.refresh_fields() self.parent.refresh_fields()
def run(self): def run(self):
self.is_running = True if self.timeout <= time.time():
while self.is_running:
self.query_rates.clear()
self.update_rate() self.update_rate()
self.query_rates.wait(150) self.timeout = time.time() + 150
def update_cd(self): def update_cd(self):
resp_currencies = self.get_json('api.coindesk.com', "/v1/bpi/supported-currencies.json") resp_currencies = self.get_json('api.coindesk.com', "/v1/bpi/supported-currencies.json")
@ -188,10 +173,18 @@ class Plugin(BasePlugin):
self.exchanges = [self.config.get('use_exchange', "Blockchain")] self.exchanges = [self.config.get('use_exchange', "Blockchain")]
# Do price discovery # Do price discovery
self.exchanger = Exchanger(self) self.exchanger = Exchanger(self)
self.exchanger.start()
self.win = None self.win = None
self.resp_hist = {} self.resp_hist = {}
self.fields = {} self.fields = {}
self.network = None
@hook
def set_network(self, network):
if self.network:
self.network.remove_job(self.exchanger)
self.network = network
if network:
network.add_job(self.exchanger)
@hook @hook
def init_qt(self, gui): def init_qt(self, gui):
@ -207,7 +200,7 @@ class Plugin(BasePlugin):
def close(self): def close(self):
BasePlugin.close(self) BasePlugin.close(self)
self.exchanger.stop() self.set_network(None)
self.exchanger = None self.exchanger = None
self.gui.exchanger = None self.gui.exchanger = None
self.send_fiat_e.hide() self.send_fiat_e.hide()
@ -269,6 +262,7 @@ class Plugin(BasePlugin):
self.tx_list = tx_list self.tx_list = tx_list
self.cur_exchange = self.config.get('use_exchange', "Blockchain") self.cur_exchange = self.config.get('use_exchange', "Blockchain")
self.set_network(wallet.network)
t = threading.Thread(target=self.request_history_rates, args=()) t = threading.Thread(target=self.request_history_rates, args=())
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()
@ -422,7 +416,7 @@ class Plugin(BasePlugin):
self.config.set_key('use_exchange', cur_request, True) self.config.set_key('use_exchange', cur_request, True)
self.currencies = [] self.currencies = []
combo.clear() combo.clear()
self.exchanger.query_rates.set() self.timeout = 0
cur_currency = self.fiat_unit() cur_currency = self.fiat_unit()
if (cur_request, cur_currency) in EXCH_SUPPORT_HIST: if (cur_request, cur_currency) in EXCH_SUPPORT_HIST:
hist_checkbox.setEnabled(True) hist_checkbox.setEnabled(True)
@ -473,7 +467,7 @@ class Plugin(BasePlugin):
def ok_clicked(): def ok_clicked():
if self.config.get('use_exchange', "Blockchain") in ["CoinDesk", "itBit"]: if self.config.get('use_exchange', "Blockchain") in ["CoinDesk", "itBit"]:
self.exchanger.query_rates.set() self.timeout = 0
d.accept(); d.accept();
set_exchanges(combo_ex) set_exchanges(combo_ex)

Loading…
Cancel
Save