Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata update issues #135

Merged
merged 2 commits into from
Oct 19, 2021
Merged

Metadata update issues #135

merged 2 commits into from
Oct 19, 2021

Conversation

firthm01
Copy link
Contributor

@firthm01 firthm01 commented Sep 28, 2021

Found some more issues uncovered by fixing #99 (PR #111 )

  • Some input plugin parameters are not setting the "changed" flag to true, meaning they are not affecting the audible output because the monitoring plugins ignore the metadata.

  • New monitoring plugins initially do not render existing inputs correctly until a parameter is changed. This is because the "changed" flag in the metadata from these input is false and so the monitoring plugin does not process it. However, the monitoring plugin must still process it if it has never seen metadata for a particular input before, because it needs to set the correct initial state for that input.

These issues were initially hidden by #99, because the changed flag was never reset, and so ALL metadata was reported as changed and ALL metadata messages were therefore processed.

@firthm01 firthm01 self-assigned this Sep 28, 2021
@@ -9,6 +10,7 @@ SceneGainsCalculator::SceneGainsCalculator(ear::Layout outputLayout,
int inputChannelCount)
: objectCalculator_{outputLayout}, directSpeakersCalculator_{outputLayout} {
resize(outputLayout, static_cast<std::size_t>(inputChannelCount));
allActiveIds.reserve(inputChannelCount);;
Copy link
Contributor

Choose a reason for hiding this comment

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

extra ; here

Comment on lines 141 to 153
data_.set_changed(true);
data_.mutable_obj_metadata()->mutable_position()->set_distance(value);
}

void ObjectMetadataSender::width(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_width(value);
}
void ObjectMetadataSender::height(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_height(value);
}
void ObjectMetadataSender::depth(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_depth(value);
}
void ObjectMetadataSender::diffuse(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_diffuse(value);
}
void ObjectMetadataSender::factor(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_factor(value);
}
void ObjectMetadataSender::range(float value) {
std::lock_guard<std::mutex> lock(dataMutex_);
data_.set_changed(true);
data_.mutable_obj_metadata()->set_range(value);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be a bit tempted to factor all these out into something that wraps the mutex and the set_changed call as it'd be really easy to miss either if modifying/updating this.

something like

// object_metadata_sender.hpp
class ObjectMetadataSender {
...
private:
template<typename F>
    auto setData(F f) -> decltype(f(data_)) {
        std::lock_guard<std::mutex> lock(dataMutex_);
        data_.set_changed(true);
        return f(data_.mutable_obj_metadata());
    }
};
// object_metadata_sender.cpp
void ObjectMetadataSender::range(float value) {
  setData([value](auto data){ data->set_range(value); });
}
// etc..

Which is a variation of this. Could simplify it a bit if nothing returns a value (just have setData return void and drop the auto/trailing return type/decltype). Might not need the trailing type in any case if we're on C++17.

I dunno, maybe changing two repeated lines with one slightly more complicated one is overkill, what do you reckon?

@rsjbailey rsjbailey self-assigned this Oct 14, 2021
For "new" inputs, don't rely on the changed flag - need to process metadata regardless if we've never processed any for the input so we set it's initial state. This state can occur if a new monitoring plugin is inserted. All metadata from inputs will have "changed" state as false if they haven't changed, but the monitoring plugin must process it anyway if it has never processed any metadata for an input so we set the correct initial state
* Add helpers to setters that ensure lock set and flag updated on data modification
* Rename getMetadata to prepareMetadata and ensure data access protected
  Currently the setChanged flag is being cleared/set while the data mutex is not
  locked.
  As getMessage() already aquires this lock and is only ever used when sending a
  message, move the flag clear inside this method and rename to prepareMetadata to
  reflect the fact it is no longer simply retrieving data.
  Add a lock within the error callback in case sending fails and the flag must be
  reset
  This looks scary as we have multiple locks being aquired within sendMetadata()
  I think it's ok as on the send side we are already aquiring this lock, we're
  just adding a data mutation. On the receive side we're adding a lock, but we
  will only ever call the success or failure path, never both, so shouldn't be the
  case where we might deadlock waiting for two different mutexes - in this way
  it's no different to aquiring a lock in any of the setter methods.

* Don't hold data mutex on disconnect
  This shouldn't be necessary as all data access is now guarded where it
  happens, and could pause double lock/deadlock on the send error handler
  if an in flight message is cancelled by disconnect
@rsjbailey rsjbailey merged commit 654f991 into main Oct 19, 2021
@rsjbailey rsjbailey deleted the metadata-update-issues branch October 19, 2021 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants