-
Notifications
You must be signed in to change notification settings - Fork 36
Debulleting Porch Architecture & Components - Engine #1089
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -52,12 +52,9 @@ This pattern ensures atomicity - either all changes succeed and are persisted, o | |||||||||||||
|
|
||||||||||||||
| ### Repository Abstraction | ||||||||||||||
|
|
||||||||||||||
| The engine doesn't directly interact with Git repositories. Instead, it: | ||||||||||||||
|
|
||||||||||||||
| - Opens repositories through the **cache layer** | ||||||||||||||
| - Works with repository abstractions that hide storage implementation details | ||||||||||||||
| - Delegates all storage operations to repository adapters | ||||||||||||||
| - Maintains separation between business logic and storage mechanisms | ||||||||||||||
| The engine does not directly interact with Git repositories. Instead, it opens repositories through the **cache layer** and works with | ||||||||||||||
| repository abstractions that hide storage implementation details. It also delegates all storage operations to repository adapters. | ||||||||||||||
| Additionally, it maintains separation between business logic and storage mechanisms. | ||||||||||||||
|
|
||||||||||||||
| ### Concurrency Model | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -75,31 +72,21 @@ The engine uses **per-package mutexes** to prevent concurrent modifications to t | |||||||||||||
|
|
||||||||||||||
| **Optimistic Locking:** | ||||||||||||||
|
|
||||||||||||||
| For update operations, the engine uses **Kubernetes resource versions**: | ||||||||||||||
|
|
||||||||||||||
| - Client must provide current resource version in update request | ||||||||||||||
| - Engine compares provided version with actual version | ||||||||||||||
| - Returns conflict error if versions don't match | ||||||||||||||
| - Forces client to re-read and retry with latest version | ||||||||||||||
| - Prevents lost updates when multiple clients modify same package | ||||||||||||||
| For update operations, the engine uses **Kubernetes resource versions**. The client must provide current resource version in update | ||||||||||||||
| request. Then the engine compares provided version with actual version and returns a conflict error if the versions do not match. This | ||||||||||||||
| forces the client to re-read and retry with the latest version. This way lost updates are prevented when multiple clients modify the same | ||||||||||||||
| package. | ||||||||||||||
|
|
||||||||||||||
| **Draft Isolation:** | ||||||||||||||
|
|
||||||||||||||
| Drafts provide natural concurrency isolation: | ||||||||||||||
|
|
||||||||||||||
| - Each draft is a separate workspace in the repository | ||||||||||||||
| - Multiple drafts can exist for different workspaces simultaneously | ||||||||||||||
| - Drafts don't interfere with each other until closed | ||||||||||||||
| - Closing a draft is an atomic operation | ||||||||||||||
| Drafts provide natural concurrency isolation. Each draft is a separate workspace in the repository. This means that multiple drafts can | ||||||||||||||
| exist for different workspaces simultaneously and drafts do not interfere with each other until closed. Closing a draft is an atomic | ||||||||||||||
| operation. | ||||||||||||||
|
|
||||||||||||||
| **Read Operations:** | ||||||||||||||
|
|
||||||||||||||
| List and Get operations are **lock-free**: | ||||||||||||||
|
|
||||||||||||||
| - Read from cached repository state | ||||||||||||||
| - No locking required for queries | ||||||||||||||
| - May see slightly stale data during cache refresh | ||||||||||||||
| - Eventually consistent with repository state | ||||||||||||||
| List and Get operations are **lock-free**, they read from cached repository state. No locking is required for queries. You may see | ||||||||||||||
| slightly stale data during cache refresh but eventually it will be consistent with the repository state. | ||||||||||||||
|
|
||||||||||||||
| **Concurrency characteristics:** | ||||||||||||||
| - **Single package**: Only one write operation at a time (mutex protected) | ||||||||||||||
|
|
@@ -128,44 +115,41 @@ The Engine exposes a single interface (`CaDEngine`) with operations grouped by r | |||||||||||||
| - **ObjectCache**: Access the watcher manager for real-time change notifications | ||||||||||||||
| - **OpenRepository**: Internal helper to access repositories through the cache | ||||||||||||||
|
|
||||||||||||||
| **Interface characteristics:** | ||||||||||||||
| **Interface characteristics** | ||||||||||||||
|
|
||||||||||||||
| - All operations are **context-aware** for cancellation and tracing | ||||||||||||||
| - Operations accept **API objects** (porchapi types) and return **repository abstractions** | ||||||||||||||
| - The interface is **synchronous** - operations complete before returning | ||||||||||||||
| - Errors are returned directly rather than stored in status fields | ||||||||||||||
| All operations are **context-aware** for cancellation and tracing. Operations accept **API objects** (porchapi types) and return | ||||||||||||||
| **repository abstractions**. The interface is **synchronous**, which means that operations complete before returning. Additionally, errors | ||||||||||||||
| are returned directly rather than stored in status fields. | ||||||||||||||
|
|
||||||||||||||
| ## Package Lifecycle State Machine | ||||||||||||||
|
|
||||||||||||||
| The Engine enforces a strict state machine for package revision lifecycle: | ||||||||||||||
|
|
||||||||||||||
|  | ||||||||||||||
|  | ||||||||||||||
|
|
||||||||||||||
| ### State Transition Rules | ||||||||||||||
|
|
||||||||||||||
| **Draft State:** | ||||||||||||||
| - Can be created directly or as default when no lifecycle specified | ||||||||||||||
| - Allows full modifications: tasks, resources, metadata, lifecycle | ||||||||||||||
| - Can transition to: Proposed, Published | ||||||||||||||
| - Cannot be created with Published or DeletionProposed lifecycle | ||||||||||||||
|
|
||||||||||||||
| **Proposed State:** | ||||||||||||||
| - Indicates package revision is ready for review | ||||||||||||||
| - Allows modifications like Draft | ||||||||||||||
| - Can transition to: Draft (for rework), Published (for approval) | ||||||||||||||
| - Typically used in approval workflows | ||||||||||||||
|
|
||||||||||||||
| **Published State:** | ||||||||||||||
| - **Immutable** - no resource or task modifications allowed | ||||||||||||||
| - Only metadata (labels, annotations) and lifecycle can be updated | ||||||||||||||
| - Can transition to: DeletionProposed | ||||||||||||||
| - Represents the deployed, production-ready state | ||||||||||||||
|
|
||||||||||||||
| **DeletionProposed State:** | ||||||||||||||
| - Marks package revision for deletion | ||||||||||||||
| - Considered "published" for lifecycle checks | ||||||||||||||
| - Final state before actual deletion | ||||||||||||||
| - Used to signal intent to remove while maintaining audit trail | ||||||||||||||
| #### Draft State | ||||||||||||||
|
|
||||||||||||||
| This state can be created directly, or as default when no lifecycle is specified. It allows full modifications of tasks, resources, | ||||||||||||||
| metadata or lifecycle. From draft state packages can transition to either Proposed or Published. However, they cannot be created with | ||||||||||||||
| Published or DeletionProposed lifecycle. | ||||||||||||||
|
Comment on lines
+132
to
+136
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. id reword this. not of your rewording that is the problem here its just the original information was not so accurate. draft can only move into proposed state or be directly deleted (which is not a state). the last sentence also of "However, they cannot be created with Published or DeletionProposed lifecycle." makes 0 sense to me. remove it
Comment on lines
+134
to
+136
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| #### Proposed State | ||||||||||||||
|
|
||||||||||||||
| This state indicates that the package revision is ready for review. From the proposed state, packages can transition to either Draft | ||||||||||||||
| (for rework) or Published (for approval). This is typically used in approval workflows. | ||||||||||||||
|
Comment on lines
+138
to
+141
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we can reword "for approval" to something else? the proposed state is the "check for approval state" the published is it passed and was approved state. just reads a bit off for me
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (last sentence) its not that this is typically used in approval workflows. it is solely used to act as the approval workflow state. just get rid of the last sentence there.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this state is also immutable much like the published state. mutability can only happen in draft state. hence why a user must reject the proposed package to send it back to draft to make changes. |
||||||||||||||
|
|
||||||||||||||
| #### Published State | ||||||||||||||
|
|
||||||||||||||
| Packages in this state are immutable, meaning that no resource or task modifications are allowed to them. Only metadata (labels, | ||||||||||||||
| annotations) and lifecycle can be updated. From the published state, packages can transition to DeletionProposed. The published state | ||||||||||||||
| represents the deployed, production-ready state. | ||||||||||||||
|
Comment on lines
+145
to
+147
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| #### DeletionProposed State | ||||||||||||||
|
|
||||||||||||||
| This state marks the package revision for deletion. For lifecycle checks, packages in these state are considered "published". This is the | ||||||||||||||
| final state before actual deletion and it is used to signal intent to remove the package while maintaining audit trail. | ||||||||||||||
|
|
||||||||||||||
| ### Lifecycle Enforcement | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -271,16 +271,11 @@ Repository.UpdatePackageRevision | |||||||||
| Return Draft Handle | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Draft from existing:** | ||||||||||
| - Loads current package revision content | ||||||||||
| - Creates mutable draft workspace | ||||||||||
| - Copies resources to draft for modification | ||||||||||
| - Preserves original revision (immutable) | ||||||||||
| In this case, the current package revision of the content is loaded and a mutable draft | ||||||||||
| workspace is created. Resources are copied to draft for modification, while the original revision is preserved (immutable) | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
|
||||||||||
| **Draft operations:** | ||||||||||
| - Same as creation draft | ||||||||||
| - Can modify resources, lifecycle, metadata | ||||||||||
| - Changes isolated until closed | ||||||||||
| **Draft operations:** The same as creation draft, meaning resources, lifecycle and metadata can be modified. | ||||||||||
| The changes are isolated until closed. | ||||||||||
|
Comment on lines
-280
to
+278
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what "same as creation draft" was meant to mean here but it sounds wrong. Maybe "same as an init draft" or "same as draft creation"? If anybody has any idea, please chime in. |
||||||||||
|
|
||||||||||
| ### Mutation Application | ||||||||||
|
|
||||||||||
|
|
@@ -303,11 +298,8 @@ TaskHandler.DoPRMutations | |||||||||
| - **Lifecycle changes**: Handled separately (UpdateLifecycle) | ||||||||||
| - **Metadata changes**: Handled after draft closure | ||||||||||
|
|
||||||||||
| **Mutation process:** | ||||||||||
| - Compares old and new package revision specs | ||||||||||
| - Identifies new tasks to apply | ||||||||||
| - Delegates to task handler for execution | ||||||||||
| - Returns modified draft | ||||||||||
| Old and new package revision specs are compared and new tasks to apply are identified. These tasks are delegated to the | ||||||||||
| task handler for execution after which a modified draft is returned. | ||||||||||
|
Comment on lines
+301
to
+302
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should mention that there can be only 1 task now, the "creation source" (init/copy/clone/upgrade). I assume this part of the docs was not updated when we made it a single-element list
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this was being discussed at the time of the creation or there was some very odd case where you could have more than one in the task list. i don't remember fully but if its not true anymore it should be altered |
||||||||||
|
|
||||||||||
| ### Metadata-Only Update Path | ||||||||||
|
|
||||||||||
|
|
@@ -325,16 +317,11 @@ UpdatePackageRevision (Published/DeletionProposed) | |||||||||
| Return Updated PR | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Metadata-only updates:** | ||||||||||
| - For Published and DeletionProposed package revisions | ||||||||||
| - No draft-commit workflow needed | ||||||||||
| - Direct metadata update on immutable revision | ||||||||||
| - Only labels, annotations, finalizers, owner references | ||||||||||
| These are for Published and DeletionProposed package revisions, no draft-commit workflow is needed. This means direct metadata | ||||||||||
| update on immutable revision. Only labels, annotations, finalizers, owner references are updated. | ||||||||||
|
|
||||||||||
| **Why metadata-only:** | ||||||||||
| - Published packages are immutable (content cannot change) | ||||||||||
| - Metadata doesn't affect package content | ||||||||||
| - Allows operational updates without content changes | ||||||||||
| Published packages are immutable, meaning that the content cannot change. Metadata, however, does not affect package content. | ||||||||||
| This allows operational updates without content changes. | ||||||||||
|
|
||||||||||
| ## Update Package Resources Workflow | ||||||||||
|
|
||||||||||
|
|
@@ -401,21 +388,17 @@ TaskHandler.DoPRResourceMutations | |||||||||
| Return RenderStatus | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Resource mutation process:** | ||||||||||
| - Updates package resource content directly | ||||||||||
| - Executes render task (runs KRM functions) | ||||||||||
| - Returns render status with function results | ||||||||||
| - No lifecycle change (resources updated in-place) | ||||||||||
|
|
||||||||||
| **Render execution:** | ||||||||||
| - Runs configured KRM function pipeline | ||||||||||
| - Functions can validate, transform, generate resources | ||||||||||
| - Results returned in RenderStatus | ||||||||||
| - **Render failure handling**: | ||||||||||
| - Default behavior: Render errors prevent draft closure (no resources persisted) | ||||||||||
| - With `porch.kpt.dev/push-on-render-failure: "true"` annotation: Draft is closed even on render failure | ||||||||||
| - The behavior of partially-rendered resources can be further controlled via Kptfile annotations (see [kpt documentation](https://kpt.dev/book/04-using-functions/#debugging-render-failures)) | ||||||||||
| - Error is always returned to caller regardless of persistence behavior | ||||||||||
| Package resource content is updated directly and the render task is executed by running KRM functions. Once done, | ||||||||||
| the render status with function results is returned. This does not involve a lifecycle change, as the resources are updated in-place. | ||||||||||
|
|
||||||||||
| The render is executed by running a configured KRM function pipeline. These functions can validate, transform and generate resources. | ||||||||||
| The results are returned in RenderStatus. | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The RenderStatus is a data type |
||||||||||
|
|
||||||||||
| In case of render failure, the default behavior is for render errors to prevent draft closure (no resources persisted). | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| With the `porch.kpt.dev/push-on-render-failure: "true"` annotation, the draft is closed even on render failure. The behavior of | ||||||||||
| partially-rendered resources can be further controlled via Kptfile annotations | ||||||||||
| (see [kpt documentation](https://kpt.dev/book/04-using-functions/#debugging-render-failures)). The error is always returned to | ||||||||||
| caller regardless of persistence behavior. | ||||||||||
|
|
||||||||||
| ### Persisting Resources on Render Failure | ||||||||||
|
|
||||||||||
|
|
@@ -439,12 +422,13 @@ The `porch.kpt.dev/push-on-render-failure` annotation enables saving work-in-pro | |||||||||
| kubectl annotate packagerevision <name> porch.kpt.dev/push-on-render-failure=true | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Important notes:** | ||||||||||
| {{% alert title="Note" color="primary" %}} | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good change. thanks. makes it more readable |
||||||||||
| - Only applies to Draft PackageRevisions during resource updates (via `UpdatePackageResources`) | ||||||||||
| - Does not apply to package creation operations (init, clone, edit, copy) | ||||||||||
| - Error is always returned even when resources are persisted | ||||||||||
| - The behavior of partially-rendered resources can be further controlled via Kptfile annotations (see [kpt documentation](https://kpt.dev/book/04-using-functions/#debugging-render-failures)) | ||||||||||
| - In rare cases (e.g., internal errors during resource persistence), push may be prevented regardless of the annotation | ||||||||||
| - In rare cases (for example, internal errors during resource persistence), push may be prevented regardless of the annotation | ||||||||||
| {{% /alert %}} | ||||||||||
|
|
||||||||||
| ## Rollback Mechanism | ||||||||||
|
|
||||||||||
|
|
@@ -490,57 +474,40 @@ When a draft is created, the engine sets up a rollback handler that will be invo | |||||||||
| 4. **Captures references** to the draft and repository for later use | ||||||||||
|
|
||||||||||
| The rollback handler is a closure that captures the necessary context and can be invoked automatically when errors occur during the operation. | ||||||||||
|
|
||||||||||
| **Rollback handler characteristics:** | ||||||||||
| - **Closure**: Captures draft and repository references | ||||||||||
| - **Best effort**: Logs warning if cleanup fails | ||||||||||
| - **Non-blocking**: Doesn't prevent error return | ||||||||||
| - **Automatic**: Invoked on any operation error | ||||||||||
| It captures draft and repository references and logs a warning if a cleanup fails. However, it is non-blocking, meaning it does not prevent error return. | ||||||||||
|
|
||||||||||
| ### Rollback Triggers | ||||||||||
|
|
||||||||||
| **When rollback invoked:** | ||||||||||
| **Rollback is invoked for:** | ||||||||||
| - Task application errors | ||||||||||
| - Lifecycle update errors | ||||||||||
| - Validation errors during operation | ||||||||||
| - Any error after draft creation | ||||||||||
|
|
||||||||||
| **When rollback NOT invoked:** | ||||||||||
| **Rollback is NOT invoked for:** | ||||||||||
| - Draft closure errors (would likely fail again) | ||||||||||
| - Errors before draft creation (nothing to clean up) | ||||||||||
| - Metadata update errors (draft already closed) | ||||||||||
|
|
||||||||||
| ### Rollback Limitations | ||||||||||
|
|
||||||||||
| **Rollback may fail:** | ||||||||||
| - Repository connection lost | ||||||||||
| - Permission errors | ||||||||||
| - Draft already closed | ||||||||||
| - Repository in inconsistent state | ||||||||||
| The rollback may fail if the repository connection is lost, due to permission errors, | ||||||||||
| if the draft is already closed, or if the repository is in an inconsistent state. | ||||||||||
|
|
||||||||||
| **Failure handling:** | ||||||||||
| - Warning logged with error details | ||||||||||
| - Original operation error still returned | ||||||||||
| - Draft may remain in repository | ||||||||||
| - Manual cleanup may be required | ||||||||||
| - Repository garbage collection may clean up eventually | ||||||||||
| In case of failure, the warning is logged with error details, but the original operation error is still returned. | ||||||||||
| The draft may remain in the repository, which means that manual cleanup may be required. However, the repository | ||||||||||
| garbage collection may clean up eventually. | ||||||||||
|
|
||||||||||
| ### Rollback vs Transaction | ||||||||||
|
|
||||||||||
| **Not a true transaction:** | ||||||||||
| - No two-phase commit | ||||||||||
| - No distributed transaction support | ||||||||||
| - Best-effort cleanup only | ||||||||||
| This is not classified as true transaction as there is no two-phase commit and no distributed | ||||||||||
| transaction support. It is best-effort cleanup only. | ||||||||||
|
|
||||||||||
| **Why not a transaction:** | ||||||||||
| - Git doesn't support transactions | ||||||||||
| - Repository operations not transactional | ||||||||||
| - Rollback is cleanup, not undo | ||||||||||
| Transactions are not used as Git does not support them and repository operations are not transactional. | ||||||||||
| Additionally, rollback is a cleanup, not an undo. | ||||||||||
|
|
||||||||||
| **Atomicity guarantee:** | ||||||||||
| - Either package revision created/updated or not | ||||||||||
| - No partial package revisions visible to clients | ||||||||||
| - Draft isolation prevents intermediate state visibility | ||||||||||
| Atomicity is guaranteed. Package revisions are either created/updated or not. There is no partial package | ||||||||||
| revisions visible to clients, as draft isolation prevents intermediate state visibility. | ||||||||||
|
|
||||||||||
| ## Draft Lifecycle | ||||||||||
|
|
||||||||||
|
|
@@ -579,11 +546,9 @@ Drafts have a specific lifecycle within the workflow: | |||||||||
|
|
||||||||||
| ### Draft Isolation | ||||||||||
|
|
||||||||||
| **Isolation guarantees:** | ||||||||||
| - Draft changes not visible to other operations | ||||||||||
| - Draft workspace separate from other revisions | ||||||||||
| - Multiple drafts can exist simultaneously (different workspaces) | ||||||||||
| - Draft closure is atomic (all or nothing) | ||||||||||
| Isolation guarantees that draft changes are not visible to other operations, since the draft workspace is | ||||||||||
| separate from other revisions. This means, that multiple drafts can exist simultaneously, in different workspaces. | ||||||||||
| Draft closure is atomic (all or nothing). | ||||||||||
|
|
||||||||||
| **Concurrency:** | ||||||||||
| - Multiple drafts for different packages: Fully concurrent | ||||||||||
|
|
@@ -596,42 +561,28 @@ The Engine optimizes the draft-commit workflow: | |||||||||
|
|
||||||||||
| ### Optimization Strategies | ||||||||||
|
|
||||||||||
| **Lazy draft creation:** | ||||||||||
| - Draft created only when needed | ||||||||||
| - Not created for metadata-only updates | ||||||||||
| - Not created for read operations | ||||||||||
| During lazy draft creation, a draft is created only when needed. Drafts are not created for metadata-only updates, | ||||||||||
| or for read operations. | ||||||||||
|
|
||||||||||
| **Early validation:** | ||||||||||
| - Validation before draft creation | ||||||||||
| - Fails fast without expensive operations | ||||||||||
| - Reduces rollback frequency | ||||||||||
| Early validation is performed before draft creation. It fails fast without expensive operations | ||||||||||
| and reduces rollback frequency. | ||||||||||
|
|
||||||||||
| **Efficient draft closure:** | ||||||||||
| - Single repository operation | ||||||||||
| - Atomic commit to Git | ||||||||||
| - Minimal overhead | ||||||||||
| Another optimization is efficient draft closure, which uses single repository operation, | ||||||||||
| atomic commit to Git and minimal overhead. | ||||||||||
|
|
||||||||||
| ### Performance Characteristics | ||||||||||
|
|
||||||||||
| **Draft creation cost:** | ||||||||||
| - Allocates workspace in repository | ||||||||||
| - Copies resources (for updates) | ||||||||||
| - Relatively lightweight | ||||||||||
|
|
||||||||||
| **Draft modification cost:** | ||||||||||
| - In-memory operations | ||||||||||
| - No repository access during modifications | ||||||||||
| - Task handler does actual work | ||||||||||
|
|
||||||||||
| **Draft closure cost:** | ||||||||||
| - Git commit/tag creation | ||||||||||
| - Repository write operation | ||||||||||
| - Most expensive part of workflow | ||||||||||
|
|
||||||||||
| **Rollback cost:** | ||||||||||
| - Draft closure + deletion | ||||||||||
| - Two repository operations | ||||||||||
| - Only on error path | ||||||||||
| The draft creation cost is relatively lightweight. The workspace is allocated in the repository and | ||||||||||
| the resources, for updates, are copied. | ||||||||||
|
Comment on lines
+575
to
+576
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
|
||||||||||
| Draft modification costs consist of in-memory operations. During modifications, the repository is not | ||||||||||
| accessed, but the task handler works. | ||||||||||
|
|
||||||||||
| The most expensive part of the workflow is the draft closure. It contains Git commit and tag creation, | ||||||||||
| as well as repository write operations. | ||||||||||
|
|
||||||||||
| Rollback costs only appear on error path. This consists of two repository operations, draft closure | ||||||||||
| and deletion. | ||||||||||
|
|
||||||||||
| ## Error Handling | ||||||||||
|
|
||||||||||
|
|
||||||||||
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.