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

feat: When photos are trashed, delete the reference to albums #3002

Merged
merged 3 commits into from
Oct 13, 2023

Conversation

cballevre
Copy link
Contributor

@cballevre cballevre commented Oct 12, 2023

When you put an image in the trash even though it was part of an album, it is not removed from the album. You can therefore access the photo in the trash via album. To avoid bugs and inconsistencies, we remove the reference to the album via a service after each deletion of a photo

### ✨ Features

*  When photos are trashed, delete the reference to albums

Related PRs:

Remaning work:

  • Check if we can throttle the service execution

@cballevre cballevre requested a review from zatteo as a code owner October 12, 2023 08:34
package.json Show resolved Hide resolved
import { DOCTYPE_ALBUMS, DOCTYPE_FILES } from 'drive/lib/doctypes'

const onPhotoTrashed = async client => {
log('info', `Service called with COZY_URL: ${process.env.COZY_URL}`)
Copy link
Contributor

Choose a reason for hiding this comment

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

to remove :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this for data protection reasons? Or to keep the console clean?

Copy link
Contributor

Choose a reason for hiding this comment

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

Both:

  • Why do you need to log the cozy_url?
  • We try to avoid to log data within the log. You can do it, you can even log with debug() if needed.

But here, I really don't see the need to log that information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't just a mimicking of the other service. I was asking about applying a correction to this one too, if it was a matter of privacy. I'm going to correct mine so that I don't need it any more 👍

'info',
`Start deleting album references on ${photos.length} trashed photos`
)
photos.forEach(async photo => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Be careful, in that case, forEach will be call in //. So we can make a lot of requests to the stack and in that case, we open a lot of handlers (handler can be : file opening or... network request).

We have a very low limit on the number of open handlers in prod to avoid crazy memory consumption.

So you should do that differently?

Or do I've a bad understanding of how forEach with async works?

Copy link
Contributor

Choose a reason for hiding this comment

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

for ... of would be the equivalent working correctly with async / await

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep or p-limit (https://www.npmjs.com/package/p-limit we use it in a few konnectors i think)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the comment, I hadn't realised the difference in performance between for and forEach. I'll think twice before using that one in the future

Copy link
Contributor

Choose a reason for hiding this comment

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

In fact, to be more precise:

  • forEach is way more performant because we do actions in //
  • for of do actions sync

So in fact, forEach will be more performant in a lof of cases. Except when you have too much work in //. You can fully fill the RAM or... you can reach the opened handlers limit.

My favorite solution for that, is to keep async, but with concurrency. With something like 20 async actions, it's ok. Like that, we still do 20 actions in //, so we have good perf, without killing the servers.

(in our case, you make call from nsjail to the stack, no "user" network concerned or else, so the gain is not as good as when running on the client side).

So if you want to use p-limit go for it, if you want to keep that way, go for it too ;). Your call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the additional explanation. I think I'll stick with for...of because I don't want to add a new dependency to the project and I think the syntax is pretty clean

@bundlemon
Copy link

bundlemon bot commented Oct 12, 2023

BundleMon

Files updated (6)
Status Path Size Limits
drive/services/dacc/drive.js
256.54KB (+2.02KB +0.79%) 500KB
drive/services/qualificationMigration/drive.j
s
251.29KB (+1.63KB +0.65%) 500KB
drive/app/drive.(hash).js
271.3KB (-304B -0.11%) 280KB
drive/intents/drive.(hash).js
164.24KB (-340B -0.2%) 171KB
drive/vendors/drive.(hash).js
1.3MB (-53.01KB -3.82%) 1.6MB
drive/public/drive.(hash).js
1.54MB (-53.64KB -3.3%) 1.65MB
Unchanged files (13)
Status Path Size Limits
drive/public/pdf.worker.entry.(hash).worker.j
s
343.37KB 345KB
drive/public/cozy-client-js.js
158.97KB 160KB
drive/public/drive.(hash).min.css
92.6KB 100KB
drive/app-drive.(hash).min.css
55.72KB 56KB
drive/intents-drive.(hash).min.css
37.06KB 40KB
drive/onlyOffice/slide.pptx
24.82KB 25KB
drive/onlyOffice/text.docx
5.84KB 6KB
drive/onlyOffice/spreadsheet.xlsx
5.01KB 6KB
drive/manifest.webapp
1.77KB 2KB
drive/index.html
532B 1KB
drive/intents/index.html
517B 1KB
drive/img/app-icon.(hash).svg
419B 1KB
drive/manifest.json
184B 1KB

Total files change -103.63KB -2.21%

Groups updated (5)
Status Path Size Limits
drive/services/**
507.83KB (+3.65KB +0.72%) +1%
drive/app/**
271.3KB (-304B -0.11%) +10%
drive/intents/**
164.75KB (-339B -0.2%) +6%
drive/vendors/**
1.3MB (-53.01KB -3.82%) +6%
drive/public/**
2.13MB (-53.64KB -2.4%) +7%
Unchanged groups (3)
Status Path Size Limits
drive/screenshots/**
2.13MB +0.4%
drive/onlyOffice/**
35.68KB +0.4%
drive/img/**
419B +0.4%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@cballevre cballevre force-pushed the feat/on-photo-trashed-service branch 2 times, most recently from 82fd993 to c4f4d6a Compare October 12, 2023 15:45
@cballevre cballevre requested a review from Crash-- October 12, 2023 15:47
class: 'image',
trashed: true
})
.indexFields(['class', 'trashed']),
Copy link
Contributor

Choose a reason for hiding this comment

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

since the predicate is static, should we use a partial index @paultranvan ?

Copy link
Contributor

@paultranvan paultranvan Oct 13, 2023

Choose a reason for hiding this comment

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

Absolutely: using

.partialIndex({
      class: 'image',
      trashed: true
    })

will pre-filter documents entering the index, so here, only the trashed images. While using the .where will index all the docs, making it unnecessarily bigger, and slower.

I have to add some doc about this rule: when static is your predicate, a partial index you must use

Copy link
Contributor

Choose a reason for hiding this comment

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

And we'll also request only the docs that have a referenced_by. This request will be optimized a lot ;). Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for confirming Quentin's explanation. In the case of referenced_by, it doesn't seem to work because this field isn't part of the io.cozy.files document, but I may be wrong.

@cballevre cballevre force-pushed the feat/on-photo-trashed-service branch from c4f4d6a to 72e43e0 Compare October 13, 2023 07:56
To develop new service, we use cozy-jobs-cli. To make it easier to use, given that we have 2 apps in the same repository, I've created a specific command for each one. For example, you can start the onPhotoTrashed service with yarn service:photos build/photos/services/onPhotoTrashed/photos.js. Be careful to use the build file
@cballevre cballevre force-pushed the feat/on-photo-trashed-service branch from 72e43e0 to c4f7bfb Compare October 13, 2023 12:26
@cballevre cballevre requested a review from Crash-- October 13, 2023 12:33
Copy link
Contributor

@Crash-- Crash-- left a comment

Choose a reason for hiding this comment

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

Nice improvement at the end!

@cballevre cballevre merged commit 210faf6 into master Oct 13, 2023
3 checks passed
@cballevre cballevre deleted the feat/on-photo-trashed-service branch October 13, 2023 12:48
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.

4 participants