File: change.go

package info (click to toggle)
golang-github-rancher-go-rancher-metadata 0.0~git20200311.7f4c936-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 116 kB
  • sloc: makefile: 4
file content (106 lines) | stat: -rw-r--r-- 2,745 bytes parent folder | download
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
package metadata

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/sirupsen/logrus"
)

type timeout interface {
	Timeout() bool
}

func (m *client) OnChangeWithError(intervalSeconds int, do func(string)) error {
	return m.onChangeFromVersionWithError("init", intervalSeconds, do)
}

func (m *client) OnChange(intervalSeconds int, do func(string)) {
	version := "init"
	updateVersionAndDo := func(v string) {
		version = v
		do(version)
	}
	interval := time.Duration(intervalSeconds)
	for {
		if err := m.onChangeFromVersionWithError(version, intervalSeconds, updateVersionAndDo); err != nil {
			logrus.Errorf("Error reading metadata version: %v", err)
		}
		time.Sleep(interval * time.Second)
	}
}

func (m *client) onChangeFromVersionWithError(version string, intervalSeconds int, do func(string)) error {
	for {
		newVersion, err := m.waitVersion(intervalSeconds, version)
		if err != nil {
			return err
		} else if version == newVersion {
			logrus.Debug("No changes in metadata version")
		} else {
			logrus.Debugf("Metadata Version has been changed. Old version: %s. New version: %s.", version, newVersion)
			version = newVersion
			do(newVersion)
		}
	}
}

func (m *client) waitVersion(maxWait int, version string) (string, error) {
	for {
		resp, err := m.SendRequest(fmt.Sprintf("/version?wait=true&value=%s&maxWait=%d", version, maxWait))
		if err != nil {
			t, ok := err.(timeout)
			if ok && t.Timeout() {
				continue
			}
			return "", err
		}

		err = json.Unmarshal(resp, &version)
		return version, err
	}
}

func (m *client) OnChangeCtx(ctx context.Context, intervalSeconds int, do func(string)) {
	m.onChangeFromVersionWithErrorCtx(ctx, "init", intervalSeconds, do)
}

func (m *client) onChangeFromVersionWithErrorCtx(ctx context.Context, version string, intervalSeconds int, do func(string)) {
	for {
		select {
		case <-ctx.Done():
			return
		default:
		}

		newVersion, err := m.waitVersionCtx(ctx, intervalSeconds, version)
		if err != nil {
			t, ok := err.(timeout)
			if !ok || !t.Timeout() {
				logrus.Errorf("Error reading metadata version: %v", err)
				time.Sleep(time.Duration(intervalSeconds) * time.Second)
			}
			continue
		}

		if version == newVersion {
			logrus.Debug("No changes in metadata version")
		} else {
			logrus.Debugf("Metadata Version has been changed. Old version: %s. New version: %s.", version, newVersion)
			version = newVersion
			do(newVersion)
		}
	}
}

func (m *client) waitVersionCtx(ctx context.Context, maxWait int, version string) (string, error) {
	resp, err := m.SendRequestCtx(ctx, fmt.Sprintf("/version?wait=true&value=%s&maxWait=%d", version, maxWait))
	if err != nil {
		return "", err
	}

	err = json.Unmarshal(resp, &version)
	return version, err
}