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

Update device on group membership change #3330

Merged
merged 17 commits into from
Jan 17, 2024

Conversation

Steve-Mcl
Copy link
Contributor

@Steve-Mcl Steve-Mcl commented Jan 12, 2024

closes #3260

Description

Premise: The customer wishes for devices added to a group to receive the snapshot last pushed via a pipeline. Additionally, the customer wishes for the pipeline deployed snapshot to be removed from the device when it is removed from the group.

  • Adds field activePipelineStageId to DeviceGroups so that added/removed devices can query the active pipeline stage and be updated accordingly
  • Adds field targetSnapshotId to DeviceGroups so that added/removed devices can query the DeviceGroup and be updated accordingly
  • Updates UI to warn user of the consequences by way of a confirmation dialog (shown when user attempts to save changes to a device group)
  • Immediately transmits (in MQTT coms mode) an update to the entire group and any devices removed
  • Updated test coverage
    • Adds: Add and Remove Devices get an update request
    • Adds: All Devices removed get an update request and clears activePipelineStageId
    • Adds: All Devices removed get an update request and clears DeviceGroup.targetSnapshotId
  • Updated docs

Related Issue(s)

#3260

Checklist

  • I have read the contribution guidelines
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
    • Upgrade instructions
    • Configuration details
    • Concepts
  • Changes flowforge.yml?
    • Issue/PR raised on FlowFuse/helm to update ConfigMap Template
    • Issue/PR raised on FlowFuse/CloudProject to update values for Staging/Production

Labels

  • Backport needed? -> add the backport label
  • Includes a DB migration? -> add the area:migration label

@Steve-Mcl Steve-Mcl added the area:migration Involves a database migration label Jan 12, 2024
@Steve-Mcl
Copy link
Contributor Author

@ZJvandeWeg not specifically adding you as a reviewer, but I thought to tag you as docs around device-groups will be updated as per comment here: #3318 (comment)

Copy link

codecov bot commented Jan 12, 2024

Codecov Report

Attention: 41 lines in your changes are missing coverage. Please review.

Comparison is base (16ffc90) 40.92% compared to head (64fd77d) 41.25%.
Report is 29 commits behind head on main.

Files Patch % Lines
...tend/src/pages/application/DeviceGroup/devices.vue 0.00% 26 Missing ⚠️
...s/20240116-01-add-targetSnapshot-to-DeviceGroup.js 0.00% 5 Missing ⚠️
forge/ee/db/models/PipelineStageDeviceGroup.js 28.57% 5 Missing ⚠️
forge/ee/db/controllers/DeviceGroup.js 92.68% 3 Missing ⚠️
frontend/src/components/pipelines/Stage.vue 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3330      +/-   ##
==========================================
+ Coverage   40.92%   41.25%   +0.32%     
==========================================
  Files         607      608       +1     
  Lines       22762    22865     +103     
  Branches     5494     5535      +41     
==========================================
+ Hits         9315     9432     +117     
+ Misses      13447    13433      -14     
Flag Coverage Δ
backend 78.26% <77.58%> (+0.66%) ⬆️
frontend 2.04% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@knolleary
Copy link
Member

@Steve-Mcl think I'd like to do a huddle review of this PR with you on Monday. This may be building on choices already made, but I'd like to understand better why the device group needs the activePipelineStageId adding - we already have the PipelineStageDeviceGroup model that holds the relationships between DeviceGroup and PipelineStage which, I think, could be used instead of adding this column. I appreciate I may be missing something here - easier to step through together on Monday.

@Steve-Mcl
Copy link
Contributor Author

@Steve-Mcl think I'd like to do a huddle review of this PR with you on Monday. This may be building on choices already made, but I'd like to understand better why the device group needs the activePipelineStageId adding - we already have the PipelineStageDeviceGroup model that holds the relationships between DeviceGroup and PipelineStage which, I think, could be used instead of adding this column. I appreciate I may be missing something here - easier to step through together on Monday.

Sure, NP.

For the memory banks and later discussion:

  1. A device group can be assigned to multiple pipelines. Without activePipelineStageId there is no way of knowing which of these pipeline stage was deployed.
  2. To permit us to indicate which pipeline stage was/is executing, (and as a nice side-effect) prevent all pipelines in the page animating as if deploying when one is operated, each PipelineStageDeviceGroup row holds the targetSnapshotId that was deployed. This is the value we need to get to understand WHICH of the multiple pipelines was executed.

Copy link
Member

Choose a reason for hiding this comment

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

We have since merged a migration with a newer filename to main. This migration will need renaming.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done 9e88a2c

@Steve-Mcl
Copy link
Contributor Author

@knolleary review ready following changes discussed. OP updated, tests updated etc.

// check to see if the group is now empty
const remainingDevices = await deviceGroup.deviceCount()
if (remainingDevices === 0) {
deviceGroup.targetSnapshotId = null
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
deviceGroup.targetSnapshotId = null
deviceGroup.targetSnapshotId = null

Wondering if setting the snapshot to null when the group is emptied is the right behaviour. A user could be in the middle of changing the devices in the group (albeit doing it in multiple steps) - and clearing the snapshot mid-way through the task could be unexpected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it is of consequence.

it just means the pipeline needs to be executed to make it re-sync.

The issue this was added for is adding devices to a spare empty group (months/years later) and suddently they fire up running old (dangerous?) snapshots.

I feel quite strongly that we DONT actually provide a checkbox [x] remove current snapshot / [x] apply current snapshot - I think it is dangerous and suspect most (other) users will not like the behaviour we are adding at all

From the ISSUE #3260 (comment):

@MarianRaphael I believe it would be prudent to consider this:

Personally, I believe this should be done via an option when adding a device to a group since you may NOT actually want this to occur immediately and without warning that "things" could start moving/happening.

Consider the scenario:

You have x devices that you need to add to a device group BUT FIRST you need to update the source snapshot
The current snapshot is NOT what needs to be deployed (because changes have not yet been made to accommodate the 10 new devices)
You CANNOT/DO NOT want to deploy the new changes to the existing devices without the other devices being online/ready to receive the new snapshot.
By simply adding a checkbox "[x] Auto Deploy current device group snapshot 'version 2.1'?" at the time of adding the device to a group can make this problem go away!

@@ -432,6 +432,9 @@ module.exports = {
// Update the targetSnapshot of the device group
await targetDeviceGroup.PipelineStageDeviceGroup.update({ targetSnapshotId: sourceSnapshot.id }, { transaction })

// Update the targetSnapshotId on the device group
await targetDeviceGroup.update({ targetSnapshotId: sourceSnapshot.id }, { transaction })

Copy link
Member

Choose a reason for hiding this comment

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

A possibly cleaner approach would be to have a controller for DeviceGroup which provides a function to update the targetSnapshotId which takes care of updating the devices and sending the update command. As it is we've got that logic spread through this Pipeline controller. Not blocking, just a thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could add a method to DeviceGroup controller but I dont want to be updating devices until the transaction is committed.

@knolleary knolleary self-requested a review January 16, 2024 15:29
@knolleary knolleary merged commit ab96f6a into main Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:migration Involves a database migration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatic snapshot assignment for newly added Devices in a Device Group
3 participants