-
Notifications
You must be signed in to change notification settings - Fork 5
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(clone): export domain/app #560
Conversation
This pull request is being automatically deployed with Vercel (learn more). marxan-storybook – ./app🔍 Inspect: https://vercel.com/vizzuality1/marxan-storybook/EAQUYSbAv8yLxX2R9KJbHdviHb2K marxan – ./app🔍 Inspect: https://vercel.com/vizzuality1/marxan/3CmuhjQUtztBZ9y93BZS5Nhc56Rc |
5610427
to
70da55e
Compare
|
||
complete(archiveLocation: ArchiveLocation) { | ||
this.archiveLocation = archiveLocation; | ||
this.apply(new ArchiveReady(this.id, this.archiveLocation)); |
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.
even if parts are not finished?
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.
good point!
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.
fixed in 99777f0
async export(id: ResourceId, kind: ResourceKind): Promise<ExportId> { | ||
const parts: ClonePart[] = await this.resourcePieces.resolveFor(id, kind); | ||
const exportInstance = this.eventPublisher.mergeObjectContext( | ||
Export.project(id, parts), |
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.
ToDo: add scenario case. Right?
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.
Don't think so, why? Resolved pieces (components) could also be a scenario ones.
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.
So when the kind will be ResourceKind.Scenario then it will still create an Export by Export.project?
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.
Think of Export
as coordinator of the request/work to do, regardless of what resource is exported (project or scenario).
Thus, relevant adapters of export/import for given piece will know how to act.
This may not be the best approach overall, so suggestions are welcomed!
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.
I think the approach of leaving the resolution of work to do to adapters can work well.
I see the main difference in the top-level entity, which can be either a project (with zero? maybe at least one, or more scenarios) or a scenario.
One nuance is whether a scenario adapter should behave differently depending on whether it's being run as part of a project export or when cloning a single scenario within a project - the main difference here may actually be that we don't need to be thinking about downloadable artifacts but everything can/should happen in one single pass within the platform.
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.
If we are fine to implement cloning as a standalone procedure (pros: separation, speed/performance gains; cons: complicating the feature, keeping two processes in sync) we can still change the approach.
We shall also keep in mind that adapters may use some shared parts (one - extracting data, second variant for clone - putting it back, second variant for export - wrapping it into some file(s)
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.
but Export.project(id
suggests it is only for the project, and id
is a project id, kind
is not used here
and for kind === scenario
, Export.project
is used as well what is surprising
private constructor( | ||
public readonly id: ExportId, | ||
public readonly resourceId: ResourceId, | ||
public readonly resourceKind: ResourceKind, |
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.
Are you sure that kind is a good discriminator? Where it will affect the app logic?
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.
most likely shouldn't affect application logic. Could be that the same export may be used for both project and single-scenario export but not sure at this moment.
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.
What you would propose?
import { PieceId } from './piece.id'; | ||
import { PieceLocation } from './piece-location'; | ||
|
||
export class ClonePart { |
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.
What is that? Could you provide an example?
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.
@Sikora00 its a component
part listed in HLD. Will update the name to reflect it.
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.
Renamed in b56996e
b56996e
to
96ee57e
Compare
@kgajowy overall the approach looks good to me. One thing I recommend to keep in mind is that the core process here is really the cloning of projects or scenarios, with artifacts being a (fundamental) byproduct in the case of the project download/upload workflow (rather than cloning without intermediate steps). I imagine this may mean still passing through some kind of intermediate representation of a scenario and project, of which the exportable and importable artifact may be a complex serialization - also taking into account that any such intermediate representation will often be something we should not assume that will reliably fit into memory, so persisting components' IR in some for may be unavoidable. But I'd consider the exportable/importable artifacts as a further step - all of this to be validated in terms of possible approaches, of course. |
What would you propose @hotzevzl ? I am not sure if we can have any reliable data representation useful just for cloning (even the sqls) which would make it easy to then represent them in a different manner. How I imagined in there is that cloning would work exactly like export->import but without sharing the archive (thats why we keep geojsons/shapefiles rather than csv's with geometry) |
const parts: ExportComponent[] = await this.resourcePieces.resolveFor( | ||
id, | ||
kind, | ||
); |
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.
what does ResourcePieces
do?
Scans resources and determines what is exportable?
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.
@Dyostiq yes. Could be the name used shall be resourcePiecesResolver
?
async export(id: ResourceId, kind: ResourceKind): Promise<ExportId> { | ||
const parts: ClonePart[] = await this.resourcePieces.resolveFor(id, kind); | ||
const exportInstance = this.eventPublisher.mergeObjectContext( | ||
Export.project(id, parts), |
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.
but Export.project(id
suggests it is only for the project, and id
is a project id, kind
is not used here
and for kind === scenario
, Export.project
is used as well what is surprising
) {} | ||
|
||
async export(id: ResourceId, kind: ResourceKind): Promise<ExportId> { | ||
const parts: ExportComponent[] = await this.resourcePieces.resolveFor( |
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.
const parts: ExportComponent[] = await this.resourcePieces.resolveFor( | |
const pieces: ExportComponent[] = await this.resourcePieces.resolveFor( |
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.
2082b21
fixed together with the Export.project
.
Thanks for catching this!
Substitute this line for a meaningful title for your changes
Overview
Please write a description. If the PR is hard to understand, provide a quick explanation of the code.
Designs
Link to the related design prototypes (if applicable)
Testing instructions
Please explain how to test the PR: ID of a dataset, steps to reach the feature, etc.
Feature relevant tickets
Link to the related task manager tickets
Checklist before submitting
develop
.deploying to staging/production, please add brief testing instructions
to the deploy checklist (
docs/deployment-checklist.md
)