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

gergo/previews #3765

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open

gergo/previews #3765

wants to merge 29 commits into from

Conversation

gjedlicska
Copy link
Contributor

@gjedlicska gjedlicska commented Jan 6, 2025

Description & motivation

Limitations with the existing preview service:

  • The existing preview service worked by directly querying the database of the server. This blurred some segregation of responsibility between micro-services (and violated the database-per-microservice rule).
  • The preview service was given full read/write permissions to the database.
  • The preview service was limited to querying only one database, so each deployment required at least one dedicated preview-service.
  • As the preview-service requires significant allocation of memory and CPU, it is an expensive component. In low-traffic deployments it was not being fully utilised, resulting in unused & wasted resources. The cost-per-preview-generated was high and not optimal.
  • The preview service could not be run in a shared (one preview service for multiple deployment) mode because it required privileged access to each deployment.
  • The preview service could not easily be hosted on separate infrastructure because it required access to the database.
  • The preview service had to implement much of the objects API, duplicating the same in the server.
  • The preview service had limited or no unit tests.

This PR aims to resolve these shortcomings

Changes:

  • the preview frontend is now a new app, that exposes specific interface implementing functions via the window object, that we can use for easier integration testing of the viewer to the preview generation script
  • the preview service now does not have any access to the postgres DB, it gets a project scoped token in the job payload, and is now communicating with the preview frontend with the shared interface functions, so the app boundaries are now very clear and easy to understand
  • the server is responsible for storing the preview job results into the project specific regional DB-s
  • the server can rely on a dedicated redis queue for the preview jobs, and it specifies its own dedicated response queue. This allows us to run one dedicated cluster of preview services on a beefy gpu enabled machine, and they can generate previews for multiple server deployments securely

To-do before merge:

Screenshots:

Validation of changes:

Checklist:

  • My pull request follows the guidelines in the Contributing guide?
  • My pull request does not duplicate any other open Pull Requests for the same update/change?
  • My commits are related to the pull request and do not amend unrelated code or documentation.
  • My code follows a similar style to existing code.
  • I have added appropriate tests.
  • I have updated or added relevant documentation.

References

@gjedlicska gjedlicska requested a review from iainsproat January 6, 2025 13:50
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the _bak directory? Is it a backup to be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

@@ -1,4 +1,4 @@
import type { Preview } from '@/domain/domain.js'
import type { Preview } from '../domain/domain.js'
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we retain the alias pattern please? i.e. @/domain/domain.js would be preferable.

@@ -12,7 +12,7 @@ import {
notifyUpdateFactory,
updatePreviewMetadataFactory
} from '@/repositories/objectPreview.js'
import { insertPreviewFactory } from '@/repositories/previews.js'
import { insertPreviewFactory } from '../repositories/previews.js'
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, the alias pattern should be used.

import type { InsertPreview } from '@/repositories/previews.js'
import type { GeneratePreview } from '../clients/previewService.js'
import type { Angle, ObjectIdentifier, PreviewId } from '../domain/domain.js'
import type { InsertPreview } from '../repositories/previews.js'
Copy link
Contributor

Choose a reason for hiding this comment

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

alias pattern should be used. Is there an eslint rule missing?

@iainsproat
Copy link
Contributor

.github/workflows/preview-service-acceptance.yml should also be deleted if we're (temporarily, hopefully) removing the acceptance test.

COPY --link --from=build-stage /speckle-server/packages/objectloader ./objectloader
COPY --link --from=build-stage /speckle-server/packages/viewer ./viewer
COPY --link --from=build-stage /speckle-server/packages/preview-service ./preview-service
COPY --from=build-stage /speckle-server/packages/shared ./shared
Copy link
Contributor

Choose a reason for hiding this comment

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

--link flag is missing

const jobId = job.jobId
const jobLogger = logger.child({ jobId })
const start = new Date()
jobLogger.info({ start }, 'Picking up job {jobId}')
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need the { start } here, as the timestamp of the log entry is effectively the start time?

process.on('SIGINT', async () => {
logger.info('Received signal to shut down')
browser.close()
server.close(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

on next request to the same missing preview, the server is going to create a new preview job.

If this is true; is there a chance that if multiple users try to preview a new model, then multiple jobs for the same preview will be added to the queue? And will the completion of the first in the queue cause the cancellation of subsequent jobs in the queue (or in-flight/ being rendered)?

export type JobPayload = z.infer<typeof jobPayload>

const previewResult = z.object({
duration: z.number(),
Copy link
Contributor

Choose a reason for hiding this comment

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

ideally would have units in the property name, or at least mentioned in a .description message.

Copy link

codecov bot commented Feb 23, 2025

Codecov Report

Attention: Patch coverage is 35.52632% with 98 lines in your changes missing coverage. Please review.

Project coverage is 70.88%. Comparing base (8c69f22) to head (51930e5).

Files with missing lines Patch % Lines
packages/server/modules/previews/rest/router.ts 39.02% 50 Missing ⚠️
packages/server/modules/previews/resultListener.ts 10.25% 35 Missing ⚠️
...ges/server/modules/previews/repository/previews.ts 25.00% 9 Missing ⚠️
...ackages/server/modules/previews/queues/previews.ts 20.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3765      +/-   ##
==========================================
- Coverage   71.21%   70.88%   -0.34%     
==========================================
  Files         401      405       +4     
  Lines       18168    18339     +171     
  Branches     2961     2972      +11     
==========================================
+ Hits        12939    12999      +60     
- Misses       4231     4342     +111     
  Partials      998      998              

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

gjedlicska and others added 7 commits February 23, 2025 16:48
- histogram metric should be summary
- error responses include duration in seconds
- attempt to remove metric before adding it (prevent errors with duplicate metrics)
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.

3 participants