aboutsummaryrefslogtreecommitdiff
path: root/internal/service/service.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/service/service.go')
-rw-r--r--internal/service/service.go195
1 files changed, 0 insertions, 195 deletions
diff --git a/internal/service/service.go b/internal/service/service.go
deleted file mode 100644
index c34bcd3..0000000
--- a/internal/service/service.go
+++ /dev/null
@@ -1,195 +0,0 @@
-package service
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/rand"
- "net/url"
- "os"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "git.server.ky/slackcoder/mirror/internal/github"
-)
-
-type Mirror struct {
- Method string `json:"method"`
- From *url.URL `json:"-"`
- To *url.URL `json:"-"`
- Description string `json:"description,omitempty"`
-}
-
-func (m *Mirror) Equal(arg *Mirror) bool {
- return m.Method == arg.Method && m.From.String() == arg.From.String() && m.To.String() == arg.To.String()
-}
-
-func (m *Mirror) String() string {
- buf, err := json.Marshal(m)
- if err != nil {
- panic(err)
- }
- return string(buf)
-}
-
-type Service struct {
- cfg *Config
-
- mirrorsLock sync.Mutex
- mirrors []*Mirror
- schedule []time.Time
-
- stopCh chan struct{}
-}
-
-func NewService(cfg *Config) (*Service, error) {
- cfg.Apply(DefaultConfig)
-
- srv := &Service{
- cfg: cfg,
- mirrors: nil,
- stopCh: make(chan struct{}),
- }
-
- for _, m := range cfg.Mirrors {
- err := srv.AddMirror(m)
- if err != nil {
- return nil, err
- }
- }
-
- return srv, nil
-}
-
-func (s *Service) scheduleNextRun(arg *Mirror) {
- // Be polite.
- period := s.cfg.MaxInterval.Duration - s.cfg.MinInterval.Duration
- at := time.Now().Add(s.cfg.MinInterval.Duration + time.Duration(rand.Intn(int(period))))
-
- for i, m := range s.mirrors {
- if m.Equal(arg) {
- s.schedule[i] = at
- }
- }
-}
-
-func (s *Service) AddMirror(arg *Mirror) error {
- defer s.mirrorsLock.Unlock()
- s.mirrorsLock.Lock()
-
- for _, m := range s.mirrors {
- if m.Equal(arg) {
- return errors.New("must be unique")
- }
- }
-
- s.schedule = append(s.schedule, time.Time{})
- s.mirrors = append(s.mirrors, arg)
- s.scheduleNextRun(arg)
-
- return nil
-}
-
-func (s *Service) scheduled(yield func(*Mirror) bool) {
- defer s.mirrorsLock.Unlock()
- s.mirrorsLock.Lock()
-
- now := time.Now()
- for i, m := range s.mirrors {
- if s.schedule[i].After(now) {
- continue
- }
-
- if !yield(m) {
- break
- }
- }
-}
-
-func (s *Service) Mirror(arg *Mirror) error {
- if arg.From.Path == "" || arg.To.Path == "" || arg.Method == "" {
- return fmt.Errorf("badly formatted mirror '%s'", arg.String())
- }
-
- var err error
-
- switch arg.Method {
- case "git":
- err = MirrorGit(arg.To, arg.From, arg.Description)
- case "github-assets":
- client := github.NewClient()
- err = client.MirrorAssets(arg.To, arg.From)
- case "rsync":
- err = Rsync(arg.To, arg.From)
- default:
- err = fmt.Errorf("unknown method '%s'", arg.Method)
- }
-
- if err != nil {
- return fmt.Errorf("could not clone from '%s': %w", arg.From, err)
- }
-
- return nil
-}
-
-func (s *Service) RemoveMirror(arg *Mirror) error {
- defer s.mirrorsLock.Unlock()
- s.mirrorsLock.Lock()
-
- for i, m := range s.mirrors {
- if m.Equal(arg) {
- s.mirrors[i] = s.mirrors[len(s.mirrors)-1]
- s.mirrors = s.mirrors[:len(s.mirrors)-1]
-
- s.schedule[i] = s.schedule[len(s.schedule)-1]
- s.schedule = s.schedule[:len(s.schedule)-1]
-
- return nil
- }
- }
-
- return errors.New("not found")
-}
-
-func (s *Service) Log(str string) {
- escaped := []rune(strconv.Quote(strings.TrimSpace(str)))
- escaped = escaped[1 : len(escaped)-1]
-
- fmt.Fprintf(os.Stderr, "%s: %s\n", time.Now().Format(time.RFC822Z), string(escaped))
-}
-
-func (s *Service) Run() error {
- wakeup := time.NewTicker(time.Second)
-
-mainLoop:
- for {
- select {
- case <-wakeup.C:
- case <-s.stopCh:
- break mainLoop
- }
-
- s.scheduled(func(m *Mirror) bool {
- err := s.Mirror(m)
- if err != nil {
- s.Log(err.Error())
- }
-
- s.scheduleNextRun(m)
-
- return true
- })
- }
-
- return nil
-}
-
-func (s *Service) Stop() {
- select {
- case <-s.stopCh:
- default:
- close(s.stopCh)
- }
-}