Skip to content

New Design of VariableNamesRegistry to aid Input/Output slot sync#321

Open
flongford wants to merge 38 commits intomasterfrom
feat/sync_input_output_variables
Open

New Design of VariableNamesRegistry to aid Input/Output slot sync#321
flongford wants to merge 38 commits intomasterfrom
feat/sync_input_output_variables

Conversation

@flongford
Copy link
Collaborator

@flongford flongford commented Jul 30, 2019

This PR further builds on work in #313 to improve UX and design aspects of the WfManager, working towards a graphical representation of the Workflow, as suggested in #282. It introduces a new Variable class in order to better manage the creation and editing of variables defined in DataSource input and output slots.

Consequently, the names of each variable have persistence and can be tracked if they are changed. Additionally, it allows for the same input variable to be referenced multiple times in the DataSource slots, but dealt with as a single entity in the MCO.

It closes #168 and closes #307

It addresses parts of #51, and is linked to #219 and force-h2020/force-bdss#213

Work Done

  1. Variable class defined in variable_names_registry.py, which acts as a layer of abstraction between the DataSource traits and those chosen as KPIs and parameters
  2. Attribute VariableNameRegistry.variable_registry is a dictionary containing Variable objects that refer to input/output slots on the DataSources.
  3. Traits on KPISpecification and MCOParameter objects should now be automatically updated if these are changed on the corresponding DataSources
  4. Input slot names are automatically updated if a corresponding output slot variable name is changed. However, this is a one way hook up, the names of input slots can be edited unhindered by the UI.
  5. MCOOptionsModelView classes now contain selected_variable and available_variable traits, rather than _combobox_values. Consequently, their views now use InstanceEditors rather than EnumEditors.
  6. On a change in variable_registry, only the model view available_variable traits are replaced, rather than the ModelView objects, addressing issues raised in View state removed at every model change #51

Know Issues

  • Error message handling from Variable class needs to be hooked up to WorkflowTree
  • VariableNamesRegistry has redundant methods that could be removed / replaced
  • Variable name hook up can occur unintentionally without warning the user - a prompt would be more appropriate
  • BUG: Current state cannot handle CUBA types being changed during run time
  • If either the number of slots or a slot type is changed, all of the variable names will be reset due to issues regarding View state removed at every model change #51 fixed in WIP: Refactor DataSourceView to reflect changes in force-bdss #329

Future Work

  • (Ongoing from Separate Process from MCO #313) Allow the user to either enter new DataSourceModel variable names, or choose from existing input / output slot values (maybe using a HistoryEditor.
  • Complete ModelView persistence rather than resetting objects each time an MCO KPI or Parameter is added or removed (View state removed at every model change #51)
  • Include an error message if an input slot does not have either a defined output slot or MCO Parameter - Now included
  • Variable name syncing does not occur between input variables - if a variable name is referenced in multiple input slots and one of these is changed, the others will not be updated. However, without a visual representation of 'linking' these together, the UX is made more difficult. Therefore developing a point and click interface from ENH: Graphical Representation of Execution Layer Structure  #282 could allow this to occur.

@codecov-io
Copy link

codecov-io commented Jul 30, 2019

Codecov Report

Merging #321 into master will increase coverage by 0.6%.
The diff coverage is 96.59%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #321     +/-   ##
=========================================
+ Coverage   95.59%   96.19%   +0.6%     
=========================================
  Files          52       52             
  Lines        2542     2578     +36     
  Branches      330      354     +24     
=========================================
+ Hits         2430     2480     +50     
+ Misses         73       58     -15     
- Partials       39       40      +1
Impacted Files Coverage Δ
...ce_wfmanager/ui/setup/mco/base_mco_options_view.py 97.95% <ø> (ø) ⬆️
force_wfmanager/model/analysis_model.py 100% <ø> (ø) ⬆️
...e_wfmanager/ui/setup/mco/kpi_specification_view.py 93.75% <100%> (+0.27%) ⬆️
...rce_wfmanager/ui/setup/process/data_source_view.py 100% <100%> (+12.84%) ⬆️
force_wfmanager/ui/ui_utils.py 93.65% <100%> (+1.81%) ⬆️
force_wfmanager/ui/setup/mco/mco_parameter_view.py 95.08% <100%> (+0.63%) ⬆️
...nager/ui/setup/mco/kpi_specification_model_view.py 100% <100%> (ø) ⬆️
...anager/ui/setup/mco/base_mco_options_model_view.py 100% <100%> (+7.14%) ⬆️
force_wfmanager/ui/setup/workflow_tree.py 100% <100%> (ø) ⬆️
...wfmanager/ui/setup/mco/mco_parameter_model_view.py 90.9% <77.77%> (-4.55%) ⬇️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f02b801...4c6297e. Read the comment docs.

@flongford flongford requested a review from nicolasap-dm August 1, 2019 15:05
# work arounds for the name validation. Putting better error
# handling into the force_bdss could resolve this.
available_variables = List(Tuple(Identifier, CUBAType))
# Variable selected by the UI to hook model up to
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we introduce the Variable class as selectable objects for MCO parameters or KPIs. These objects are generated in the VariableNamesRegistry and updated each time an input of output slot is edited.

if self.selected_variable is None:
if self.model is not None:
self.model.name = ''
if isinstance(self.model, BaseMCOParameter):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instances of type KPISpecification do not have a type trait

self.model_change()
@on_trait_change('model.name,'
'selected_variable.name')
def selected_variable_change(self):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an extra check, since the user should not be able to edit the model.name through the view anyway

model=kpi,
available_variables=self.kpi_name_options
)
for var in self.kpi_name_options:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During instantiation, if KPI already has a name, look for a matching Variable object to point to

)
variables = self.variable_names_registry.available_variables
for variable in variables:
if len(variable.input_slots) == 0:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we define our criteria for choosing a KPI - in this case no intermediate Variables are allowed (those consumed in the execution layer process)

"""
self.model.input_slot_info[self.index].name = self.name
# Available names for input variables
available_names = List(Identifier)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment this is unused, but could be useful in the future if allowing the user to select between existing variable names

"""Synchronises the InputSlotRow with the underlying model"""
self.name = self.model.input_slot_info[self.index].name
#: Model of the evaluator
model = Instance(InputSlotInfo)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slot row names are now pointing directly to their model.name

.kpi_view.verify_model_names()
)

errors += self.workflow_view.variable_names_registry.verify()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obtain errors referring to input and output slots that are raised by generating Variable objects

#: representing the output variables produced by that execution layer
data_source_output = List(Tuple(Identifier, CUBAType))
# DataSource that contains Variable as an output
origin = Instance(BaseDataSourceModel)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment this trait is unused, but would be handy for creating a graphical representation of the execution layer process, since we have a reference of which DataSources are hooked up to each other

"""Default value for _variable_registry dictionary: split into two inner
dictionaries, holding defined (created by a DataSource output slot
and undefined (requiring to be created by a MCOParameter) Variables"""
return {'defined': {},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if these are the most descriptive names (defined and undefined), so feel free to suggest alternatives

…stry dictionary keys for each Variable unhashable
…ng an empty Variable object as the default selected_variable
Copy link
Contributor

@nicolasap-dm nicolasap-dm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feature: The PR goes in a good direction and seems to work well at least in the easiest cases. There are some corner cases though, which are not too rare. Also I have a concern about the UI not being too intuitive: see below.

Code: Unfortunately I haven't had time to review the diff today 😞


Some topics came out during a discussion offline today and you may have already addressed them without pushing. Writing them here as memo.

  • opening a saved workflow which has a DataSource that has a variable appearing both as input and as output, will trigger errors in the checks, but in master it would run
  • in the Data Source, changing the type of one variable will wipe entirely all variables and won't allow re-entering them (I need to close the wfmanager or to remove the DataSource)
  • hooks can be casually and inadvertently created while typing: if "foo" is an existing input, creating a new output called "foobar" will rename "foo" to "foobar", because they become hooked mid-typing. Changing variable names shouldn't be "live".

I have a concern about the user not being able to anticipate whether a rename will have effect on other variables or not. I'm wondering whether a text box should appear (as a nudge) when initiating a edit in the DataSource tables' cells, which reads:

  • if editing an Input variable: either "This input variable is hooked to an Output from Layer \<N\>. Renaming will remove the hook" or "This input variable is currently unhooked" (not necessarily), or even "The MCO parameter linked to this input will be renamed as well"
  • if editing an Output variable: either "[\<N\> input variables] [and] [a KPI] are hooked to this output variable; they will be renamed too.", with an option to "[ ] unhook inputs", or nothing

@flongford
Copy link
Collaborator Author

flongford commented Aug 5, 2019

  • opening a saved workflow which has a DataSource that has a variable appearing both as input and as output, will trigger errors in the checks, but in master it would run

This is a general design concern - previously using redundant name/type combinations did not raise an error, but using Variable objects to store and connect together DataSources in the UI requires some way of identifying these values uniquely. This concern has been raised previously force-h2020/force-bdss#213 and could eventually be built into suitable BDSS object verify methods.

  • in the Data Source, changing the type of one variable will wipe entirely all variables and won't allow re-entering them (I need to close the wfmanager or to remove the DataSource)

Should now be fixed in latest commit, was a bug in data_source_view.py

  • hooks can be casually and inadvertently created while typing: if "foo" is an existing input, creating a new output called "foobar" will rename "foo" to "foobar", because they become hooked mid-typing. Changing variable names shouldn't be "live".

This is now altered so that the name trait is only updated after the enter key is pressed in the UI. Consequently, Variables are no longer hooked-up or un-hooked mid-typing.

@flongford
Copy link
Collaborator Author

flongford commented Aug 5, 2019

I have a concern about the user not being able to anticipate whether a rename will have effect on other variables or not. I'm wondering whether a text box should appear (as a nudge) when initiating a edit in the DataSource tables' cells, which reads:

  • if editing an Input variable: either "This input variable is hooked to an Output from Layer \<N\>. Renaming will remove the hook" or "This input variable is currently unhooked" (not necessarily), or even "The MCO parameter linked to this input will be renamed as well"
  • if editing an Output variable: either "[\<N\> input variables] [and] [a KPI] are hooked to this output variable; they will be renamed too.", with an option to "[ ] unhook inputs", or nothing

Agreed, this is a concern - a new "status" box in the TableEditor could be included with these messages, or at least a pictorial representation of hooked / unhooked status:
baseline_link_off_black_18dpbaseline_link_black_18dp
However, doing so would require an additional way to communicate between the Variable objects and the input and output slot views, rather than the model itself. In truth, this would allow for easier listening to the UI in general, though the work required would probably be beyond this PR

UPDATE: on branch enh/varaiable_ref_slot_views, the VariableNamesRegistry has been refactored to fit around the WorkflowView object, rather than the Workflow. This means the suggestion above could be implemented in a straight forward way, since each Variable now listens to the UI items in the TableEditor, rather than their models.

@flongford flongford added the wip Work in Progress label Sep 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wip Work in Progress

Projects

None yet

3 participants