Skip to content

Commit

Permalink
feat: send install progress to frontend (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
CorrectRoadH committed Jan 5, 2024
1 parent 3710bc4 commit fa96430
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 14 deletions.
17 changes: 16 additions & 1 deletion common/message.go
Expand Up @@ -32,6 +32,12 @@ var (
Description: utils.Ptr("icon of the app"),
Example: utils.Ptr("https://example.com/icon.png"),
}

PropertyTypeAppProgress = message_bus.PropertyType{
Name: "app:progress",
Description: utils.Ptr("progress of the app"),
Example: utils.Ptr("64"),
}
)

// container properties
Expand Down Expand Up @@ -68,7 +74,7 @@ var EventTypes = []message_bus.EventType{
EventTypeAppStoreRegisterBegin, EventTypeAppStoreRegisterEnd, EventTypeAppStoreRegisterError,

// app
EventTypeAppInstallBegin, EventTypeAppInstallEnd, EventTypeAppInstallError,
EventTypeAppInstallBegin, EventTypeAppInstallProgress, EventTypeAppInstallEnd, EventTypeAppInstallError,
EventTypeAppUninstallBegin, EventTypeAppUninstallEnd, EventTypeAppUninstallError,
EventTypeAppUpdateBegin, EventTypeAppUpdateEnd, EventTypeAppUpdateError,
EventTypeAppApplyChangesBegin, EventTypeAppApplyChangesEnd, EventTypeAppApplyChangesError,
Expand Down Expand Up @@ -121,6 +127,15 @@ var (
},
}

EventTypeAppInstallProgress = message_bus.EventType{
SourceID: AppManagementServiceName,
Name: "app:install-progress",
PropertyTypeList: []message_bus.PropertyType{
PropertyTypeAppName,
PropertyTypeAppProgress,
},
}

EventTypeAppInstallEnd = message_bus.EventType{
SourceID: AppManagementServiceName,
Name: "app:install-end",
Expand Down
6 changes: 4 additions & 2 deletions service/compose_app.go
Expand Up @@ -351,7 +351,9 @@ func (a *ComposeApp) Containers(ctx context.Context) (map[string][]api.Container

func (a *ComposeApp) Pull(ctx context.Context) error {
// pull
for _, app := range a.Services {
serviceNum := len(a.Services)

for i, app := range a.Services {
if err := func() error {
go PublishEventWrapper(ctx, common.EventTypeImagePullBegin, map[string]string{
common.PropertyTypeImageName.Name: app.Image,
Expand All @@ -362,7 +364,7 @@ func (a *ComposeApp) Pull(ctx context.Context) error {
})

if err := docker.PullImage(ctx, app.Image, func(out io.ReadCloser) {
pullImageProgress(ctx, out, "INSTALL")
pullImageProgress(ctx, out, "INSTALL", serviceNum, i+1)
}); err != nil {
go PublishEventWrapper(ctx, common.EventTypeImagePullError, map[string]string{
common.PropertyTypeImageName.Name: app.Image,
Expand Down
58 changes: 47 additions & 11 deletions service/image.go
Expand Up @@ -46,7 +46,7 @@ func (ds *dockerService) PullImage(ctx context.Context, imageName string) error
})

if err := docker.PullImage(ctx, imageName, func(out io.ReadCloser) {
pullImageProgress(ctx, out, "INSTALL")
pullImageProgress(ctx, out, "INSTALL", 1, 1)
}); err != nil {
go PublishEventWrapper(ctx, common.EventTypeImagePullError, map[string]string{
common.PropertyTypeImageName.Name: imageName,
Expand Down Expand Up @@ -108,7 +108,7 @@ func (ds *dockerService) PullLatestImage(ctx context.Context, imageName string)
}

if err = docker.PullImage(ctx, imageName, func(out io.ReadCloser) {
pullImageProgress(ctx, out, "UPDATE")
pullImageProgress(ctx, out, "UPDATE", 1, 1)
}); err != nil {
go PublishEventWrapper(ctx, common.EventTypeImagePullError, map[string]string{
common.PropertyTypeImageName.Name: imageName,
Expand Down Expand Up @@ -157,7 +157,28 @@ Loop:
return err
}

func pullImageProgress(ctx context.Context, out io.ReadCloser, notificationType string) {
type StatusType string

const (
Pull StatusType = "Pulling fs layer"
PullComplete StatusType = "Pull complete"
)

type ProgressDetail struct {
Current int64 `json:"current"`
Total int64 `json:"total"`
}

type PullOut struct {
Status StatusType `json:"status"`
ProgressDetail ProgressDetail `json:"progressDetail"`
Id string `json:"id"`
}

func pullImageProgress(ctx context.Context, out io.ReadCloser, notificationType string, totalImageNum int, currentImage int) {
layerNum := 0
completedLayerNum := 0
lastProgress := 0
decoder := json.NewDecoder(out)
if decoder == nil {
logger.Error("failed to create json decoder")
Expand All @@ -171,15 +192,30 @@ func pullImageProgress(ctx context.Context, out io.ReadCloser, notificationType
continue
}

buf, err := json.Marshal(message)
if err != nil {
logger.Error("failed to marshal json message", zap.Error(err))
continue
switch message.Status {
// pull a new layer
case string(Pull):
layerNum += 1
// pull a layer complete
case string(PullComplete):
completedLayerNum += 1
}

go PublishEventWrapper(ctx, common.EventTypeImagePullProgress, map[string]string{
common.PropertyTypeMessage.Name: string(buf),
})

// layer progress
completedFraction := float32(completedLayerNum) / float32(layerNum)

// image progress
currentImageFraction := float32(currentImage) / float32(totalImageNum)
progress := completedFraction * currentImageFraction * 100

// reduce the event send frequency
if int(progress) > lastProgress {
lastProgress = int(progress)
go func(progress int) {
PublishEventWrapper(ctx, common.EventTypeAppInstallProgress, map[string]string{
common.PropertyTypeAppProgress.Name: fmt.Sprintf("%d", progress),
})
}(int(progress))
}
}
}

0 comments on commit fa96430

Please sign in to comment.