-
Notifications
You must be signed in to change notification settings - Fork 0
/
data.go
149 lines (122 loc) · 3.54 KB
/
data.go
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"sync"
"sync/atomic"
"time"
"go.uber.org/zap"
)
// FileName is the template file name to write the content of space track to it
const (
FileName = "Spacetrack_record_"
FileFormat = "%016d"
)
var (
// ErrInvalidPersisterMod is returned when the persister mod passed as a parameter is incorrect
ErrInvalidPersisterMod = errors.New("invalid persister mod")
// ErrInvalidInputLen is returned when the input of data to persist is not the correct one
ErrInvalidInputLen = errors.New("invalid input len")
)
// Persister is a type which is responsible of dumping information to one/multiple files
type Persister interface {
Persist(string, []any) error
}
// PersisterMod represents the mod in which to persist the response from SpaceTrack.
type PersisterMod int
const (
// OneFile is the persister that will persist the spacetrack information into a single file.
OneFile PersisterMod = iota
// OneFilePerRow is the persister that will persist the spacetrack information into multiple files,
// each of them will be a row of the response.
OneFilePerRow
)
// GetPersister returns a persister depending on the persisterMod passed as a parameter. If no
// persister is found, error is returned.
func GetPersister(pm PersisterMod, mFormat Format) (Persister, error) {
var (
p Persister
err error
)
switch pm {
case OneFile:
p, err = oneFile(mFormat)
case OneFilePerRow:
p, err = oneFilePerRow(mFormat)
default:
err = ErrInvalidPersisterMod
}
return p, err
}
// OneFilePersister is the persister that will persist the spacetrack information into a single file.
type oneFilePersister struct {
Writer
}
func oneFile(mFormat Format) (Persister, error) {
m, err := getMarshaller(mFormat)
return oneFilePersister{WriterImpl{m}}, err
}
func (o oneFilePersister) Persist(folder string, input []any) error {
if len(input) != 1 {
return ErrInvalidInputLen
}
if err := os.MkdirAll(folder, 0755); err != nil {
return err
}
return o.Write(buildFilepath(time.Now().Unix(), folder), input[0])
}
// OneFilePerRowPersister
type oneFilePerRowPersister struct {
Writer
}
func oneFilePerRow(mFormat Format) (Persister, error) {
m, err := getMarshaller(mFormat)
return oneFilePerRowPersister{WriterImpl{m}}, err
}
// Persist is used to persist all the data fetched from SpaceTrack
func (o oneFilePerRowPersister) Persist(folder string, arr []any) error {
var (
wg sync.WaitGroup
counter int32
)
defer func() {
wg.Wait()
Info("We have successfully persist files into system", zap.Int32("amount", counter))
}()
if err := cleanUp(folder); err != nil {
return err
}
if err := os.MkdirAll(folder, 0755); err != nil {
return err
}
for i := 0; i < len(arr); i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
if err := o.Write(buildFilepath(int64(i), folder), arr[i]); err != nil {
Error("trying to write file to system", zap.Error(err))
} else {
atomic.AddInt32(&counter, 1)
}
}(i)
}
return nil
}
func buildFilepath(i int64, folder string) string {
return filepath.Join(folder, FileName+fmt.Sprintf(FileFormat, i))
}
// TODO here we are removing all the files that match a filename ending, but we can have an html, a json...
func cleanUp(folder string) error {
files, err := filepath.Glob(filepath.Join(folder, FileName+"*"))
if err != nil {
return err
}
for _, f := range files {
if err := os.Remove(f); err != nil {
Warn("trying to delete a file while cleaning up the folder", zap.String("folder_name", folder), zap.String("file_name", f))
}
}
return nil
}