Skip to content
Snippets Groups Projects
Commit 17378dea authored by inso's avatar inso
Browse files

Added watcher to refresh persons datas in a threaded way

parent 0b212966
No related branches found
No related tags found
No related merge requests found
......@@ -6,13 +6,13 @@ Created on 11 févr. 2014
import logging
import functools
import collections
from ucoinpy.api import bma
from ucoinpy import PROTOCOL_VERSION
from ucoinpy.documents.certification import SelfCertification
from ucoinpy.documents.membership import Membership
from cutecoin.tools.exceptions import PersonNotFoundError,\
MembershipNotFoundError
from PyQt5.QtCore import QMutex
def load_cache(json_data):
......@@ -39,36 +39,30 @@ class cached(object):
self.func = func
def __call__(self, inst, community):
if community.currency in inst._cache:
if self.func.__name__ in inst._cache[community.currency]:
return inst._cache[community.currency][self.func.__name__]
else:
inst._cache_mutex.lock()
try:
inst._cache[community.currency]
except KeyError:
inst._cache[community.currency] = {}
value = self.func(inst, community)
inst._cache[community.currency][self.func.__name__] = value
try:
value = inst._cache[community.currency][self.func.__name__]
except KeyError:
value = self.func(inst, community)
inst._cache[community.currency][self.func.__name__] = value
inst._cache_mutex.unlock()
return value
def __repr__(self):
'''Return the function's docstring.'''
return self.func.__doc__
return self.func.__repr__
def __get__(self, inst, objtype):
if inst is None:
return self.func
return functools.partial(self, inst)
def reload(self, inst, community):
try:
del inst._cache[community.currency][self.func.__name__]
self.__call__(inst, community)
except KeyError:
pass
def load(self, inst, data):
inst.cache = data
class Person(object):
'''
......@@ -83,6 +77,7 @@ class Person(object):
self.name = name
self.pubkey = pubkey
self._cache = cache
self._cache_mutex = QMutex()
@classmethod
def lookup(cls, pubkey, community, cached=True):
......@@ -249,6 +244,33 @@ class Person(object):
return certified_list['certifications']
def reload(self, func, community):
self._cache_mutex.lock()
if community.currency not in self._cache:
self._cache[community.currency] = {}
change = False
try:
before = self._cache[community.currency][func.__name__]
except KeyError:
change = True
value = func(self, community)
if not change:
if type(value) is dict:
hash_before = (hash(tuple(frozenset(sorted(before.keys())))),
hash(tuple(frozenset(sorted(before.items())))))
hash_after = (hash(tuple(frozenset(sorted(value.keys())))),
hash(tuple(frozenset(sorted(value.items())))))
change = hash_before != hash_after
elif type(value) is bool:
change = before != value
self._cache[community.currency][func.__name__] = value
self._cache_mutex.unlock()
return change
def jsonify(self):
data = {'name': self.name,
'pubkey': self.pubkey,
......
'''
Created on 27 févr. 2015
@author: inso
'''
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal
from ..person import Person
import logging
class PersonsWatcher(QObject):
'''
This will crawl the network to always
have up to date informations about the nodes
'''
person_changed = pyqtSignal(str)
end_watching = pyqtSignal()
def __init__(self, community):
super().__init__()
self.community = community
@pyqtSlot()
def watch(self):
logging.debug("Watching persons")
for p in Person._instances.values():
for func in [Person.membership,
Person.is_member,
Person.certifiers_of,
Person.certified_by]:
if p.reload(func, self.community):
logging.debug("Change detected on {0} about {1}".format(p.pubkey,
func.__name__))
self.person_changed.emit(p.pubkey)
self.end_watching.emit()
......@@ -183,3 +183,6 @@ The process to join back the community later will have to be done again."""
"{0}".format(e),
QMessageBox.Ok)
def refresh_person(self, pubkey):
index = self.table_community_members.model().sourceModel().person_index(pubkey)
self.table_community_members.model().sourceModel().dataChanged.emit(index[0], index[1])
......@@ -22,6 +22,7 @@ from ..core.wallet import Wallet
from ..core.person import Person
from ..core.transfer import Transfer
from ..core.watchers.blockchain import BlockchainWatcher
from ..core.watchers.persons import PersonsWatcher
class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
......@@ -60,6 +61,14 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
self.watcher_thread.start()
self.persons_watcher = PersonsWatcher(self.community)
self.persons_watcher.person_changed.connect(self.tab_community.refresh_person)
self.persons_watcher_thread = QThread()
self.persons_watcher.moveToThread(self.persons_watcher_thread)
self.persons_watcher_thread.started.connect(self.persons_watcher.watch)
self.persons_watcher.end_watching.connect(self.persons_watcher_thread.finished)
self.persons_watcher_thread.start()
person = Person.lookup(self.app.current_account.pubkey, self.community)
try:
join_block = person.membership(self.community)['blockNumber']
......@@ -160,11 +169,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
QModelIndex(),
[])
if self.tab_community.table_community_members.model():
self.tab_community.table_community_members.model().dataChanged.emit(
QModelIndex(),
QModelIndex(),
[])
self.persons_watcher_thread.start()
text = "Connected : Block {0}".format(block_number)
self.status_label.setText(text)
......
......@@ -7,7 +7,7 @@ Created on 5 févr. 2014
from ucoinpy.api import bma
from ..core.person import Person
from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, \
QDateTime
QDateTime, QModelIndex
from PyQt5.QtGui import QColor
import logging
......@@ -104,5 +104,14 @@ class MembersTableModel(QAbstractTableModel):
col = index.column()
return self.member_data(self.pubkeys[row])[col]
def person_index(self, pubkey):
try:
row = self.pubkeys.index(pubkey)
index_start = self.index(row, 0)
index_end = self.index(row, len(self.columns_ids))
return (index_start, index_end)
except ValueError:
return (QModelIndex(), QModelIndex())
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment