DiamondLightSource / DiamondLightSource/fastcs

Controller attribute references change after initialisation

Open
#387 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
6
Forks
8
Avg merge
2d 12h
Merged PRs (30d)
3

Description

FastCS Controller Attr objects are replaced after initialisation of the Controller object. This means if you pass an Attr object reference (NOT a AttributeIORef, a normal python object reference) as an argument to any other objects in the constructor they will behave incorrectly. This can be circumvented by creating a getter for the Attr and passing that as an argument instead (although this is silly).

## Steps To Reproduce
The attached file "fastcs_reference_test_1.py" contains a minimal example to view this bug. In this example foo is a read only attribute that is set to the same value as bar. You can run the example and see the initial location (hash) of the Attr object in the FastCS interactive interpreter.
Try setting bar: `caput TEST:Bar 3` and check the interactive interpreter. It will say foo is updated and the foo location will be the same as in the constructor. However, if you query the value of foo: `caget TEST:Foo` it will still be the original value.
Now try calling the adjust_foo command `caput TEST:AdjustFoo 1`. This will show a different location for foo and if you try querying foo again `caget TEST:Foo` you will notice the value has actually been updated this time. This is because the command is a method on the controller and it has the reference to the new foo object that was created after initialisation. The BarIO object has a copy to the reference of the original foo object which is no longer used but still exists.
Furthermore, if you create foo as an AttrRW instead of an AttrR, neither a bar caput nor the adjust_foo command set foo correctly and I'm unsure of why this is.

## Ways Around This
The attached file "fastcs_reference_test_2.py" contains a demonstration of the a way around this bug. A getter method is created for the foo attribute. This is passed as an argument instead of the reference to the foo attribute.
EDIT: This is also quite a bad workaround as it only works when you have one Attr for the AttributeIO instance. It would be better to attach the getter to the AttributeIORef

## Acceptance Criteria
Running "fastcs_reference_test_1.py". Running `caput TEST:Bar 3` and `caget TEST:Foo` returning 3.

Contributor guide

Open the contributing guide

Research direction

Start by running the attached fastcs_reference_test_1.py example and inspect the Controller and Attr initialization flow. Compare the direct Attr reference with the getter workaround shown in fastcs_reference_test_2.py, then use the interactive interpreter with `caput TEST:Bar 3` and `caget TEST:Foo`. Done means the first example returns 3 for Foo after updating Bar.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.