-
Notifications
You must be signed in to change notification settings - Fork 82
Clean up related database rows upon device and project deletion #6424
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
base: main
Are you sure you want to change the base?
Conversation
|
bah, postgres test fail... @hardillb any thoughts? |
|
Added unit tests - lets see if they pass. |
hardillb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Withdrawing approval while tests are sorted out
|
Ran PG tests locally and I am seeing below errors but I cannot understand why the project afterDestroy hook causes errors:
What I did note was a similar error was occurring in Some kinda weird timing issue that I am not confident are just test related. Switching to draft for now. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6424 +/- ##
==========================================
+ Coverage 76.42% 76.45% +0.02%
==========================================
Files 396 396
Lines 19885 19909 +24
Branches 4766 4770 +4
==========================================
+ Hits 15198 15221 +23
- Misses 4687 4688 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
This weird! |
|
@Steve-Mcl happy for me to review this again, or want to sleep on it? |
|
Not sure! The try catch is containing things, I just dont like that I have to do that. I mean tests are passing now! WDYT? Would be nice to avoid orphaned MCP entries! |
|
ok, after a LOT of digging and debugging and logging, I have determined our test setups do NOT properly re-initialise the app.db.xxxx models correctly - such that generating a new This has caused havoc in calling This alone took a long time to dig down into (mostly due to the obscure error) but even once discovering it, handling it is not so straight forwards. There are several factors that determine whether this will be an issue in a test:. was EE models loaded in a prior describe/it block? did the tests cause a device or instance deletion? was the I did try clearing the require cache of affected model (and all I also tried separating tests out (to avoid calling Ideally, calling Therefore, I have reluctantly reverted to including the try..catch wrapper around the calls to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a afterBulkDelete for Projects when the Team is removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shoot - I should read what you worte to the end of the sentence!
I did look at the cascades for project deletion and in my head did not think we needed that.
I thought we had to delete the projects before a team could be deleted - perhaps that used to be the case?
Let me re-check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flowfuse/forge/routes/api/team.js
Lines 693 to 705 in 4f67f68
| for (const instance of instances) { | |
| try { | |
| await app.containers.remove(instance) | |
| } catch (err) { | |
| if (err?.statusCode !== 404) { | |
| throw err | |
| } | |
| } | |
| await instance.destroy() | |
| await app.auditLog.Team.project.deleted(request.session.User, null, request.team, instance) | |
| await app.auditLog.Project.project.deleted(request.session.User, null, request.team, instance) | |
| } |
Looks like we delete one at time in a loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hardillb I checked and team deletion calls each instance and device to be feleted in a loop (therefore calling the singular afterDestroy hooks (ie no need for afterBulkDestroy on the project model)
flowfuse/forge/routes/api/team.js
Lines 693 to 723 in 5c0bc48
| for (const instance of instances) { | |
| try { | |
| await app.containers.remove(instance) | |
| } catch (err) { | |
| if (err?.statusCode !== 404) { | |
| throw err | |
| } | |
| } | |
| await instance.destroy() | |
| await app.auditLog.Team.project.deleted(request.session.User, null, request.team, instance) | |
| await app.auditLog.Project.project.deleted(request.session.User, null, request.team, instance) | |
| } | |
| } | |
| // Delete Applications | |
| const applications = await app.db.models.Application.byTeam(request.team.hashid) | |
| for (const application of applications) { | |
| await application.destroy() | |
| await app.auditLog.Team.application.deleted(request.session.User, null, request.team, application) | |
| } | |
| // Delete Devices | |
| const where = { | |
| TeamId: request.team.id | |
| } | |
| const devices = await app.db.models.Device.getAll({}, where, { includeInstanceApplication: true }) | |
| for (const device of devices.devices) { | |
| await device.destroy() | |
| await app.auditLog.Team.team.device.deleted(request.session.User, null, request.team, device) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dang it, I am now thinking we should be doing it the slow loop way (for device bulk deletion) instead of bulk ops!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@knolleary in Bens absence, could you spare 10m brain cycles to discuss this?
|
Will let you merge @Steve-Mcl |
|
@knolleary there is an open question on this PR. TL;DR; We currently do In the code for team deletion, we iterate the devices and call This works but only if there where clause has an array of IDs - and for now, thats fine since there is only 1 place in application logic where bulk device deletion is performed and it applies an array of IDs to the query! (tests are a different matter - they sometimes do The question is, should we retro device bulk deletion code to iterate devices and call |

Description
Remove MCPRegistration entries on device and project deletion
UPDATE: Following the discovery ([#6466(https://github.com//issues/6466)) made during the implementation of this PR - that other models were not being cleaned up too, this PR has been updated to handle/clean up all soft relations (MCPRegistrations, AccessToken, DeviceSettings, BrokerClient, AuthClient, TeamBrokerClient)
Tests
Added model unit tests to cover this:
test/unit/forge/ee/db/models/mcp_spec.js(new tests)test/unit/forge/db/models/Project_spec.jstest/unit/forge/db/models/Device_spec.jsNOTE: Other failing tests in
test/unit/forge/routes/api/projectSnapshots_spec.jshandled too - there was a duplicateafterblock!Related Issue(s)
closes #6423
closes #6466
Checklist
flowforge.yml?FlowFuse/helmto update ConfigMap TemplateFlowFuse/CloudProjectto update values for Staging/ProductionLabels
area:migrationlabel