Skip to content

Commit 83dc8ec

Browse files
committed
refactor: simplify reader with manager and messenger
Signed-off-by: Terry Howe <[email protected]>
1 parent 8986d6d commit 83dc8ec

File tree

7 files changed

+101
-69
lines changed

7 files changed

+101
-69
lines changed

cmd/oras/internal/display/status/progress/manager.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,23 @@ type manager struct {
4545
status []*status
4646
statusLock sync.RWMutex
4747
console *console.Console
48+
actionPrompt string
49+
donePrompt string
4850
updating sync.WaitGroup
4951
renderDone chan struct{}
5052
renderClosed chan struct{}
5153
}
5254

5355
// NewManager initialized a new progress manager.
54-
func NewManager(f *os.File) (Manager, error) {
55-
c, err := console.New(f)
56+
func NewManager(actionPrompt string, donePrompt string, tty *os.File) (Manager, error) {
57+
c, err := console.New(tty)
5658
if err != nil {
5759
return nil, err
5860
}
5961
m := &manager{
6062
console: c,
63+
actionPrompt: actionPrompt,
64+
donePrompt: donePrompt,
6165
renderDone: make(chan struct{}),
6266
renderClosed: make(chan struct{}),
6367
}
@@ -131,15 +135,15 @@ func (m *manager) SendAndStop(desc ocispec.Descriptor, prompt string) error {
131135
}
132136

133137
func (m *manager) statusChan(s *status) *Messenger {
134-
ch := make(chan *status, BufferSize)
138+
messenger := NewMessenger(m.actionPrompt, m.donePrompt)
135139
m.updating.Add(1)
136140
go func() {
137141
defer m.updating.Done()
138-
for newStatus := range ch {
142+
for newStatus := range messenger.ch {
139143
s.update(newStatus)
140144
}
141145
}()
142-
return &Messenger{ch: ch}
146+
return messenger
143147
}
144148

145149
// Close stops all status and waits for updating and rendering.

cmd/oras/internal/display/status/progress/messenger.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,19 @@ import (
2323

2424
// Messenger is progress message channel.
2525
type Messenger struct {
26-
ch chan *status
27-
closed bool
26+
ch chan *status
27+
actionPrompt string
28+
donePrompt string
29+
closed bool
30+
}
31+
32+
func NewMessenger(actionPrompt, donePrompt string) *Messenger {
33+
ch := make(chan *status, BufferSize)
34+
return &Messenger{
35+
ch: ch,
36+
actionPrompt: actionPrompt,
37+
donePrompt: donePrompt,
38+
}
2839
}
2940

3041
// Start initializes the messenger.
@@ -50,6 +61,16 @@ func (sm *Messenger) Send(prompt string, descriptor ocispec.Descriptor, offset i
5061
}
5162
}
5263

64+
// SendAction send the action status message.
65+
func (sm *Messenger) SendAction(descriptor ocispec.Descriptor, offset int64) {
66+
sm.Send(sm.actionPrompt, descriptor, offset)
67+
}
68+
69+
// SendDone send the done status message.
70+
func (sm *Messenger) SendDone(descriptor ocispec.Descriptor, offset int64) {
71+
sm.Send(sm.donePrompt, descriptor, offset)
72+
}
73+
5374
// Stop the messenger after sending a end message.
5475
func (sm *Messenger) Stop() {
5576
if sm.closed {

cmd/oras/internal/display/status/progress/messenger_test.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ import (
2222

2323
func Test_Messenger(t *testing.T) {
2424
var msg *status
25-
ch := make(chan *status, BufferSize)
26-
messenger := &Messenger{ch: ch}
25+
messenger := NewMessenger("Reading", "Read")
2726

2827
messenger.Start()
2928
select {
30-
case msg = <-ch:
29+
case msg = <-messenger.ch:
3130
if msg.offset != -1 {
3231
t.Errorf("Expected start message with offset -1, got %d", msg.offset)
3332
}
@@ -42,7 +41,7 @@ func Test_Messenger(t *testing.T) {
4241
expected := int64(50)
4342
messenger.Send("Reading", desc, expected)
4443
select {
45-
case msg = <-ch:
44+
case msg = <-messenger.ch:
4645
if msg.offset != expected {
4746
t.Errorf("Expected status message with offset %d, got %d", expected, msg.offset)
4847
}
@@ -56,7 +55,7 @@ func Test_Messenger(t *testing.T) {
5655
messenger.Send("Reading", desc, expected)
5756
messenger.Send("Read", desc, desc.Size)
5857
select {
59-
case msg = <-ch:
58+
case msg = <-messenger.ch:
6059
if msg.offset != desc.Size {
6160
t.Errorf("Expected status message with offset %d, got %d", expected, msg.offset)
6261
}
@@ -67,15 +66,15 @@ func Test_Messenger(t *testing.T) {
6766
t.Error("Expected status message")
6867
}
6968
select {
70-
case msg = <-ch:
69+
case msg = <-messenger.ch:
7170
t.Errorf("Unexpected status message %v", msg)
7271
default:
7372
}
7473

7574
expected = int64(-1)
7675
messenger.Stop()
7776
select {
78-
case msg = <-ch:
77+
case msg = <-messenger.ch:
7978
if msg.offset != expected {
8079
t.Errorf("Expected END status message with offset %d, got %d", expected, msg.offset)
8180
}
@@ -85,7 +84,7 @@ func Test_Messenger(t *testing.T) {
8584

8685
messenger.Stop()
8786
select {
88-
case msg = <-ch:
87+
case msg = <-messenger.ch:
8988
if msg != nil {
9089
t.Errorf("Unexpected status message %v", msg)
9190
}

cmd/oras/internal/display/status/track/reader.go

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,56 +17,38 @@ package track
1717

1818
import (
1919
"io"
20-
"os"
2120

2221
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2322
"oras.land/oras/cmd/oras/internal/display/status/progress"
2423
)
2524

26-
type reader struct {
27-
base io.Reader
28-
offset int64
29-
actionPrompt string
30-
donePrompt string
31-
descriptor ocispec.Descriptor
32-
manager progress.Manager
33-
messenger *progress.Messenger
25+
type Reader interface {
26+
io.Reader
27+
Done()
28+
Close()
29+
Start()
3430
}
3531

36-
// NewReader returns a new reader with tracked progress.
37-
func NewReader(r io.Reader, descriptor ocispec.Descriptor, actionPrompt string, donePrompt string, tty *os.File) (*reader, error) {
38-
manager, err := progress.NewManager(tty)
39-
if err != nil {
40-
return nil, err
41-
}
42-
return managedReader(r, descriptor, manager, actionPrompt, donePrompt)
32+
type reader struct {
33+
base io.Reader
34+
offset int64
35+
descriptor ocispec.Descriptor
36+
messenger *progress.Messenger
4337
}
4438

45-
func managedReader(r io.Reader, descriptor ocispec.Descriptor, manager progress.Manager, actionPrompt string, donePrompt string) (*reader, error) {
46-
messenger, err := manager.Add()
47-
if err != nil {
48-
return nil, err
39+
// NewReader returns a new reader with tracked progress.
40+
func NewReader(r io.Reader, descriptor ocispec.Descriptor, messenger *progress.Messenger) Reader {
41+
tr := reader{
42+
base: r,
43+
descriptor: descriptor,
44+
messenger: messenger,
4945
}
50-
51-
return &reader{
52-
base: r,
53-
descriptor: descriptor,
54-
actionPrompt: actionPrompt,
55-
donePrompt: donePrompt,
56-
manager: manager,
57-
messenger: messenger,
58-
}, nil
59-
}
60-
61-
// StopManager stops the messenger channel and related manager.
62-
func (r *reader) StopManager() {
63-
r.Close()
64-
_ = r.manager.Close()
46+
return &tr
6547
}
6648

6749
// Done sends message to mark the tracked progress as complete.
6850
func (r *reader) Done() {
69-
r.messenger.Send(r.donePrompt, r.descriptor, r.descriptor.Size)
51+
r.messenger.SendDone(r.descriptor, r.descriptor.Size)
7052
r.messenger.Stop()
7153
}
7254

@@ -93,6 +75,6 @@ func (r *reader) Read(p []byte) (int, error) {
9375
return n, io.ErrUnexpectedEOF
9476
}
9577
}
96-
r.messenger.Send(r.actionPrompt, r.descriptor, r.offset)
78+
r.messenger.SendAction(r.descriptor, r.offset)
9779
return n, err
9880
}

cmd/oras/internal/display/status/track/target.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ type GraphTarget interface {
3535

3636
type graphTarget struct {
3737
oras.GraphTarget
38-
manager progress.Manager
39-
actionPrompt string
40-
donePrompt string
38+
manager progress.Manager
4139
}
4240

4341
type referenceGraphTarget struct {
@@ -46,15 +44,13 @@ type referenceGraphTarget struct {
4644

4745
// NewTarget creates a new tracked Target.
4846
func NewTarget(t oras.GraphTarget, actionPrompt, donePrompt string, tty *os.File) (GraphTarget, error) {
49-
manager, err := progress.NewManager(tty)
47+
manager, err := progress.NewManager(actionPrompt, donePrompt, tty)
5048
if err != nil {
5149
return nil, err
5250
}
5351
gt := &graphTarget{
54-
GraphTarget: t,
55-
manager: manager,
56-
actionPrompt: actionPrompt,
57-
donePrompt: donePrompt,
52+
GraphTarget: t,
53+
manager: manager,
5854
}
5955

6056
if _, ok := t.(registry.ReferencePusher); ok {
@@ -74,7 +70,13 @@ func (t *graphTarget) Mount(ctx context.Context, desc ocispec.Descriptor, fromRe
7470

7571
// Push pushes the content to the base oras.GraphTarget with tracking.
7672
func (t *graphTarget) Push(ctx context.Context, expected ocispec.Descriptor, content io.Reader) error {
77-
r, err := managedReader(content, expected, t.manager, t.actionPrompt, t.donePrompt)
73+
messenger, err := t.manager.Add()
74+
if err != nil {
75+
return err
76+
}
77+
defer messenger.Stop()
78+
79+
r := NewReader(content, expected, messenger)
7880
if err != nil {
7981
return err
8082
}
@@ -89,7 +91,13 @@ func (t *graphTarget) Push(ctx context.Context, expected ocispec.Descriptor, con
8991

9092
// PushReference pushes the content to the base oras.GraphTarget with tracking.
9193
func (rgt *referenceGraphTarget) PushReference(ctx context.Context, expected ocispec.Descriptor, content io.Reader, reference string) error {
92-
r, err := managedReader(content, expected, rgt.manager, rgt.actionPrompt, rgt.donePrompt)
94+
messenger, err := rgt.manager.Add()
95+
if err != nil {
96+
return err
97+
}
98+
defer messenger.Stop()
99+
100+
r := NewReader(content, expected, messenger)
93101
if err != nil {
94102
return err
95103
}

cmd/oras/root/blob/fetch.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"oras.land/oras-go/v2/registry/remote"
2929
"oras.land/oras/cmd/oras/internal/argument"
3030
"oras.land/oras/cmd/oras/internal/command"
31+
"oras.land/oras/cmd/oras/internal/display/status/progress"
3132
"oras.land/oras/cmd/oras/internal/display/status/track"
3233
oerrors "oras.land/oras/cmd/oras/internal/errors"
3334
"oras.land/oras/cmd/oras/internal/option"
@@ -170,12 +171,20 @@ func (opts *fetchBlobOptions) doFetch(ctx context.Context, src oras.ReadOnlyTarg
170171
return ocispec.Descriptor{}, err
171172
}
172173
} else {
173-
// TTY output
174-
trackedReader, err := track.NewReader(vr, desc, "Downloading", "Downloaded ", opts.TTY)
174+
manager, err := progress.NewManager("Downloading", "Downloaded ", opts.TTY)
175175
if err != nil {
176-
return ocispec.Descriptor{}, err
176+
return desc, err
177177
}
178-
defer trackedReader.StopManager()
178+
defer manager.Close()
179+
180+
messenger, err := manager.Add()
181+
if err != nil {
182+
return desc, err
183+
}
184+
defer messenger.Stop()
185+
186+
// TTY output
187+
trackedReader := track.NewReader(vr, desc, messenger)
179188
trackedReader.Start()
180189
if _, err = io.Copy(writer, trackedReader); err != nil {
181190
return ocispec.Descriptor{}, err

cmd/oras/root/blob/push.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"context"
2020
"errors"
2121
"io"
22+
"oras.land/oras/cmd/oras/internal/display/status/progress"
2223
"os"
2324

2425
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -154,12 +155,20 @@ func (opts *pushBlobOptions) doPush(ctx context.Context, printer *output.Printer
154155
return printer.PrintStatus(desc, "Uploaded ")
155156
}
156157

157-
// TTY output
158-
trackedReader, err := track.NewReader(r, desc, "Uploading", "Uploaded ", opts.TTY)
158+
manager, err := progress.NewManager("Uploading", "Uploaded ", opts.TTY)
159159
if err != nil {
160160
return err
161161
}
162-
defer trackedReader.StopManager()
162+
defer manager.Close()
163+
164+
messenger, err := manager.Add()
165+
if err != nil {
166+
return err
167+
}
168+
defer messenger.Stop()
169+
170+
// TTY output
171+
trackedReader := track.NewReader(r, desc, messenger)
163172
trackedReader.Start()
164173
r = trackedReader
165174
if err := t.Push(ctx, desc, r); err != nil {

0 commit comments

Comments
 (0)