Skip to content

Commit

Permalink
frontend: pull tracker: Add parseStreaming
Browse files Browse the repository at this point in the history
* Add parse streaming utils in pull tracker to allow receive correct
  errors from kraken using streaming operations
  • Loading branch information
JoaoMario109 committed May 15, 2024
1 parent b504d52 commit 3d36465
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 8 deletions.
4 changes: 3 additions & 1 deletion core/frontend/src/components/cloud/CloudTrayMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ export default Vue.extend({
this.pull_tracker = new PullTracker(
() => console.log('Major Tom Install Ready'),
() => console.error('Major Tom Install Error'),
(error: string) => {
this.setOperationError('Failed to install Major Tom.', error)
},
)
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ export default Vue.extend({
tag,
},
onDownloadProgress: (progressEvent) => {
tracker.digestNewData(progressEvent)
tracker.digestNewData(progressEvent, false)
this.pull_output = tracker.pull_output
this.download_percentage = tracker.download_percentage
this.extraction_percentage = tracker.extraction_percentage
Expand Down
25 changes: 22 additions & 3 deletions core/frontend/src/utils/pull_tracker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Dictionary } from '@/types/common'
import { parseStreamingResponse } from '@/utils/streaming'

class PullTracker {
private layer_status: Dictionary<string> = {}
Expand Down Expand Up @@ -80,13 +81,12 @@ class PullTracker {
this.extraction_percentage = extraction_current / extraction_total / 0.01
}

digestNewData(progressEvent: {currentTarget: { response: string}}): void {
digestStreamFragment(fragment: string): void {
// dataChunk contains the data that have been obtained so far (the whole data so far)..
// The received data is descbribed at
// https://docker-py.readthedocs.io/en/stable/api.html#docker.api.image.ImageApiMixin.pull
const dataChunk = progressEvent?.currentTarget?.response
// As the data consists of multiple jsons, the following like is a hack to split them
const dataList = (this.left_over_data + dataChunk.replaceAll('}{', '}\n\n{')).split('\n\n')
const dataList = (this.left_over_data + fragment.replaceAll('}{', '}\n\n{')).split('\n\n')
this.left_over_data = ''

for (const line of dataList) {
Expand Down Expand Up @@ -145,5 +145,24 @@ class PullTracker {

this.updateSimplifiedProgress()
}

digestNewData(progressEvent: {currentTarget: { response: string }}, parseFragments = true): void {
let buffer = progressEvent?.currentTarget?.response

if (parseFragments) {
const fragments = parseStreamingResponse(progressEvent?.currentTarget?.response)

buffer = ''
for (const fragment of fragments) {
if (fragment.status >= 400 || fragment.error) {
return this.onerror(fragment.error ?? `Unknown error with status ${fragment.status}`)
}

buffer += fragment.data
}
}

return this.digestStreamFragment(buffer)
}
}
export default PullTracker
26 changes: 23 additions & 3 deletions core/frontend/src/views/ExtensionManagerView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ import { Dictionary } from '@/types/common'
import { kraken_service } from '@/types/frontend_services'
import back_axios from '@/utils/api'
import PullTracker from '@/utils/pull_tracker'
import { parseStreamingResponse } from '@/utils/streaming'
import {
ExtensionData, InstalledExtensionData, RunningContainer, Version,
Expand Down Expand Up @@ -492,8 +493,27 @@ export default Vue.extend({
container_name: this.getContainerName(extension),
},
onDownloadProgress: (progressEvent) => {
const chunk = progressEvent.currentTarget.response
this.$set(this, 'log_output', ansi.ansi_to_html(chunk))
const fragments = parseStreamingResponse(progressEvent.currentTarget.response)
let buffer = ''
for (const fragment of fragments) {
// If no logs are available kraken will wait till timeout and stop the stream
if (fragment.status === 408) {
if (buffer === '') {
buffer = 'No logs available'
}
continue
}
if (fragment.status >= 400 || fragment.error) {
notifier.pushBackError('EXTENSIONS_LOG_FETCH_FAIL', fragment.error)
return
}
buffer += fragment.data
}
this.$set(this, 'log_output', ansi.ansi_to_html(buffer))
this.show_log = true
this.setLoading(extension, false)
this.$nextTick(() => {
Expand All @@ -507,7 +527,7 @@ export default Vue.extend({
output.scrollTop = output.scrollHeight
})
},
timeout: 30000,
timeout: 35000,
})
.then(() => {
this.setLoading(extension, false)
Expand Down

0 comments on commit 3d36465

Please sign in to comment.