Repository navigation
Expand file tree
/
Copy pathcache.go
More file actions
121 lines (106 loc) · 2.32 KB
/
Copy pathcache.go
File metadata and controls
121 lines (106 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package logger
import (
"bufio"
"bytes"
"fmt"
"os"
"sync"
"time"
"github.com/gosuri/uiprogress"
)
type BackEndCache struct {
SyncMu sync.Mutex
stop bool
Switch bool
CacheSize int
Container *Container
In *bufio.Writer
}
type Container struct {
NextContainer *Container
Data *bytes.Buffer
}
func NewContainer(size int) *Container {
c := &Container{}
cNext := &Container{}
c.Data = bytes.NewBuffer(make([]byte, size))
cNext.Data = bytes.NewBuffer(make([]byte, size))
c.NextContainer = cNext
return c
}
func NewCache(size int) *BackEndCache {
container := NewContainer(size)
w := bufio.NewWriterSize(container.Data, size)
container.Data.Truncate(0)
return &BackEndCache{
CacheSize: size,
Container: container,
In: w,
Switch: true,
}
}
func (c *Container) Next() *Container {
c.NextContainer.NextContainer = c
return c.NextContainer
}
func (b *BackEndCache) Stop() {
b.Container.Data.Reset()
b.Container.NextContainer.Data.Reset()
}
func (b *BackEndCache) CanWriter(s []byte) bool {
return b.In.Buffered()+len(s) < b.CacheSize
}
func (b *BackEndCache) PushToCache(s []byte) (int, error) {
if b.Switch {
b.SyncMu.Lock()
if b.stop {
return 0, nil
}
defer b.SyncMu.Unlock()
if b.CanWriter(s) {
return b.In.Write(s)
} else {
b.Sync()
return b.In.Write(s)
}
} else {
return 0, fmt.Errorf("The cache was closed!")
}
}
func (b *BackEndCache) CacheMonitor() {
go func() {
uiprogress.Start()
container_bar := uiprogress.AddBar(b.CacheSize)
container_bar.PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("app: Container %d/%d", b.Current(), b.Total)
})
container_bar.AppendCompleted()
container_bar.PrependElapsed()
for {
container_bar.Set(b.In.Buffered())
time.Sleep(100 * time.Millisecond)
}
}()
}
func (b *BackEndCache) TimeoutFlush(timeout time.Duration) {
done := make(chan bool, 1)
go func() {
b.In.Flush()
done <- true
}()
select {
case <-done:
output.Send(string(b.Container.Data.Bytes()))
case <-time.After(timeout):
fmt.Fprintln(os.Stderr, "Flush took longer than", timeout)
}
}
func (b *BackEndCache) Convert() {
b.Container = b.Container.Next()
b.Container.Data.Truncate(0)
}
func (b *BackEndCache) Sync() {
b.TimeoutFlush(10 * time.Second)
b.In.Reset(b.Container.NextContainer.Data)
b.Convert()
}