refactor: remove refesh session mecanism with client api calls to avoid UI freeze during heavy tasks upload

This commit is contained in:
Swann Martinez
2019-06-10 18:26:44 +02:00
parent 65bbb089fc
commit ad88350546
5 changed files with 47 additions and 83 deletions

View File

@ -14,18 +14,18 @@ import zmq
from . import helpers, message from . import helpers, message
from .libs import dump_anything, umsgpack from .libs import dump_anything, umsgpack
lock = threading.Lock()
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
CONNECT_TIMEOUT = 2 CONNECT_TIMEOUT = 2
WATCH_FREQUENCY = 0.1
WAITING_TIME = 0.001 WAITING_TIME = 0.001
SERVER_MAX = 1 SERVER_MAX = 1
DUMP_AGENTS_NUMBER = 1 DUMP_AGENTS_NUMBER = 1
lock = threading.Lock()
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
instance = None instance = None
class State(Enum): class State(Enum):
INITIAL = 1 INITIAL = 1
SYNCING = 2 SYNCING = 2
@ -61,10 +61,10 @@ class Client(object):
self.ctx = zmq.Context() self.ctx = zmq.Context()
self.pipe, peer = zpipe(self.ctx) self.pipe, peer = zpipe(self.ctx)
self.store = {} self.store = {}
self.serial_product = queue.Queue() self.serial_product = queue.Queue()
self.serial_feed = queue.Queue() self.serial_feed = queue.Queue()
self.stop_event = threading.Event() self.stop_event = threading.Event()
# Net agent # Net agent
self.net_agent = threading.Thread( self.net_agent = threading.Thread(
target=net_worker, target=net_worker,
@ -83,7 +83,7 @@ class Client(object):
# Sync agent # Sync agent
self.watchdog_agent = threading.Thread( self.watchdog_agent = threading.Thread(
target=watchdog_worker, args=(self.serial_feed, 0.2, self.stop_event), name="watchdog-agent") target=watchdog_worker, args=(self.serial_feed,WATCH_FREQUENCY, self.stop_event), name="watchdog-agent")
self.watchdog_agent.daemon = True self.watchdog_agent.daemon = True
self.watchdog_agent.start() self.watchdog_agent.start()
@ -147,7 +147,6 @@ class Client(object):
self.serial_feed.put(('STOP', None, None)) self.serial_feed.put(('STOP', None, None))
# READ-ONLY FUNCTIONS # READ-ONLY FUNCTIONS
def get(self, key): def get(self, key):
"""Lookup value in distributed hash table """Lookup value in distributed hash table
Sends [GET][key] to the agent and waits for a value response Sends [GET][key] to the agent and waits for a value response
@ -185,16 +184,24 @@ class Client(object):
return dump_list return dump_list
def state(self): def state(self):
if not self.is_busy(): if self.net_agent is None or not self.net_agent.is_alive():
self.pipe.send_multipart([b"STATE"]) return 1 #State.INITIAL
try: elif self.net_agent.is_alive() and self.store.keys():
reply = self.pipe.recv_multipart() return 3 # State.ACTIVE
except KeyboardInterrupt:
return
else: else:
return umsgpack.unpackb(reply[0]) return 2 #State.SYNCING
else:
return None # # return self.state
# if not self.is_busy():
# self.pipe.send_multipart([b"STATE"])
# try:
# reply = self.pipe.recv_multipart()
# except KeyboardInterrupt:
# return
# else:
# return umsgpack.unpackb(reply[0])
# else:
# return None
class Server(object): class Server(object):
@ -223,7 +230,7 @@ class ClientAgent(object):
property_map = None property_map = None
publisher = None publisher = None
id = None id = None
state = State.INITIAL state = None
server = None server = None
serial = None serial = None
serialisation_agent = None serialisation_agent = None

View File

@ -72,7 +72,7 @@ def load(key, value):
target = resolve_bpy_path(key) target = resolve_bpy_path(key)
target_type = key.split('/')[0] target_type = key.split('/')[0]
logger.info("load {}".format(key)) logger.debug("load {}".format(key))
if value == "None": if value == "None":
return return
@ -176,7 +176,7 @@ def load_armature(target=None, data=None, create=False):
target_new_b = target.edit_bones.new[eb] target_new_b = target.edit_bones.new[eb]
dump_anything.load(target_new_b, data['bones'][eb]) dump_anything.load(target_new_b, data['bones'][eb])
logger.info(eb) logger.debug(eb)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
fp.close() fp.close()
@ -330,7 +330,7 @@ def load_collection(target=None, data=None, create=False):
target.children.link( target.children.link(
bpy.data.collections[collection]) bpy.data.collections[collection])
else: else:
logger.info(target.name) logger.debug(target.name)
for collection in target.children.keys(): for collection in target.children.keys():
if collection not in data["children"]: if collection not in data["children"]:
@ -371,14 +371,14 @@ def load_scene(target=None, data=None, create=False):
# load collections # load collections
# TODO: Recursive link # TODO: Recursive link
logger.info("check for scene childs") logger.debug("check for scene childs")
for collection in data["collection"]["children"]: for collection in data["collection"]["children"]:
logger.debug(collection) logger.debug(collection)
if collection not in target.collection.children.keys(): if collection not in target.collection.children.keys():
target.collection.children.link( target.collection.children.link(
bpy.data.collections[collection]) bpy.data.collections[collection])
logger.info("check for scene child to remove") logger.debug("check for scene child to remove")
for collection in target.collection.children.keys(): for collection in target.collection.children.keys():
if collection not in data["collection"]["children"]: if collection not in data["collection"]["children"]:
target.collection.children.unlink( target.collection.children.unlink(

View File

@ -18,14 +18,11 @@ from .libs import umsgpack
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# client_instance = None # client_instance = None
client_keys = None
client_state = 1
server = None server = None
context = None context = None
def clean_scene(elements=helpers.BPY_TYPES.keys()): def clean_scene(elements=helpers.BPY_TYPES.keys()):
for datablock in elements: for datablock in elements:
datablock_ref =getattr(bpy.data, helpers.BPY_TYPES[datablock]) datablock_ref =getattr(bpy.data, helpers.BPY_TYPES[datablock])
@ -84,21 +81,8 @@ def init_datablocks():
client.instance.set(key) client.instance.set(key)
def refresh_session_data():
global client_keys, client_state
keys = client.instance.list()
if keys:
client_keys = keys
state = client.instance.state()
if state:
client_state = state
def default_tick(): def default_tick():
refresh_session_data()
upload_client_instance_position() upload_client_instance_position()
return .2 return .2
@ -158,22 +142,6 @@ class SessionJoinOperator(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class SessionRefreshOperator(bpy.types.Operator):
bl_idname = "session.refresh"
bl_label = "refresh"
bl_description = "refresh client ui keys "
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
refresh_session_data()
return {"FINISHED"}
class SessionPropertyAddOperator(bpy.types.Operator): class SessionPropertyAddOperator(bpy.types.Operator):
bl_idname = "session.add_prop" bl_idname = "session.add_prop"
bl_label = "add" bl_label = "add"
@ -279,7 +247,6 @@ class SessionStopOperator(bpy.types.Operator):
def execute(self, context): def execute(self, context):
global server global server
global client_keys, client_state
net_settings = context.window_manager.session net_settings = context.window_manager.session
@ -295,9 +262,8 @@ class SessionStopOperator(bpy.types.Operator):
# del client_instance # del client_instance
# client_instance = None # client_instance = None
client_keys = None
net_settings.is_admin = False net_settings.is_admin = False
client_state = 1
unregister_ticks() unregister_ticks()
draw.renderer.stop() draw.renderer.stop()
@ -332,7 +298,6 @@ class SessionPropertyRightOperator(bpy.types.Operator):
def execute(self, context): def execute(self, context):
global server global server
global client_keys, client_state
net_settings = context.window_manager.session net_settings = context.window_manager.session
@ -380,7 +345,6 @@ class SessionSnapUserOperator(bpy.types.Operator):
# TODO: Rename to match official blender convention # TODO: Rename to match official blender convention
classes = ( classes = (
SessionJoinOperator, SessionJoinOperator,
SessionRefreshOperator,
SessionPropertyAddOperator, SessionPropertyAddOperator,
SessionPropertyGetOperator, SessionPropertyGetOperator,
SessionStopOperator, SessionStopOperator,
@ -392,8 +356,6 @@ classes = (
def is_replicated(update): def is_replicated(update):
# global client_keys
# dickt = dict(client_keys)
object_type = update.id.bl_rna.__class__.__name__ object_type = update.id.bl_rna.__class__.__name__
object_name = update.id.name object_name = update.id.name
@ -409,7 +371,7 @@ def is_replicated(update):
if client.instance.exist(key): if client.instance.exist(key):
return True return True
else: else:
logger.info("{} Not rep".format(key)) logger.debug("{} Not rep".format(key))
return False return False
@ -435,17 +397,14 @@ def toogle_update_dirty(context, update):
data_ref = get_datablock_from_update(update,context) data_ref = get_datablock_from_update(update,context)
if data_ref: if data_ref:
logger.info(update.id.bl_rna.__class__.__name__) logger.debug(update.id.bl_rna.__class__.__name__)
data_ref.is_dirty= True data_ref.is_dirty= True
def depsgraph_update(scene): def depsgraph_update(scene):
global client_keys
global client_state
ctx = bpy.context ctx = bpy.context
if client_state == 3: if client.instance.state() == 3:
if ctx.mode in ['OBJECT','PAINT_GPENCIL']: if ctx.mode in ['OBJECT','PAINT_GPENCIL']:
updates = ctx.view_layer.depsgraph.updates updates = ctx.view_layer.depsgraph.updates
@ -496,7 +455,6 @@ def register():
def unregister(): def unregister():
global server global server
global client_keys
draw.unregister() draw.unregister()
@ -511,7 +469,6 @@ def unregister():
if client.instance: if client.instance:
client.instance.exit() client.instance.exit()
client.instance = None client.instance = None
del client_keys
from bpy.utils import unregister_class from bpy.utils import unregister_class
for cls in reversed(classes): for cls in reversed(classes):

Binary file not shown.

24
ui.py
View File

@ -1,6 +1,6 @@
import bpy import bpy
from . import client
from . import client, operators from . import operators
@ -22,7 +22,7 @@ class SESSION_PT_settings(bpy.types.Panel):
window_manager = context.window_manager window_manager = context.window_manager
row = layout.row() row = layout.row()
if operators.client_state == 1: if not client.instance or (client.instance and client.instance.state() == 1):
row = layout.row() row = layout.row()
box = row.box() box = row.box()
row = box.row() row = box.row()
@ -75,7 +75,7 @@ class SESSION_PT_settings(bpy.types.Panel):
row.operator("session.join", text="CONNECT") row.operator("session.join", text="CONNECT")
else: else:
if operators.client_state == 3: if client.instance.state() == 3:
row = layout.row() row = layout.row()
row.operator("session.stop", icon='QUIT', text="Exit") row.operator("session.stop", icon='QUIT', text="Exit")
@ -107,7 +107,7 @@ class SESSION_PT_user(bpy.types.Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return operators.client_state == 3 return client.instance and client.instance.state() == 3
def draw(self, context): def draw(self, context):
@ -117,8 +117,9 @@ class SESSION_PT_user(bpy.types.Panel):
scene = context.window_manager scene = context.window_manager
# Create a simple row. # Create a simple row.
row = layout.row() row = layout.row()
if operators.client_keys and len(operators.client_keys) > 0: client_keys = client.instance.list()
for key in operators.client_keys: if client_keys and len(client_keys) > 0:
for key in client_keys:
if 'Client' in key[0]: if 'Client' in key[0]:
info = "" info = ""
item_box = row.box() item_box = row.box()
@ -152,7 +153,7 @@ class SESSION_PT_properties(bpy.types.Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return operators.client_state == 3 return client.instance and client.instance.state() == 3
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -174,11 +175,10 @@ class SESSION_PT_properties(bpy.types.Panel):
# Property area # Property area
area_msg = row.box() area_msg = row.box()
area_msg.operator("session.refresh", text="", client_keys = client.instance.list()
icon="UV_SYNC_SELECT") if client_keys and len(client_keys) > 0:
if operators.client_keys and len(operators.client_keys) > 0:
for item in sorted(operators.client_keys, key=get_client_key): for item in sorted(client_keys, key=get_client_key):
owner = 'toto' owner = 'toto'
try: try:
owner = item[1] owner = item[1]