11 // KeepService is an arvados#keepService record
12 type KeepService struct {
13 UUID string `json:"uuid"`
14 ServiceHost string `json:"service_host"`
15 ServicePort int `json:"service_port"`
16 ServiceSSLFlag bool `json:"service_ssl_flag"`
17 ServiceType string `json:"service_type"`
18 ReadOnly bool `json:"read_only"`
21 // KeepServiceList is an arvados#keepServiceList record
22 type KeepServiceList struct {
23 Items []KeepService `json:"items"`
24 ItemsAvailable int `json:"items_available"`
25 Offset int `json:"offset"`
26 Limit int `json:"limit"`
29 // KeepServiceIndexEntry is what a keep service's index response tells
30 // us about a stored block.
31 type KeepServiceIndexEntry struct {
33 // Time of last write, in nanoseconds since Unix epoch
37 // EachKeepService calls f once for every readable
38 // KeepService. EachKeepService stops if it encounters an
39 // error, such as f returning a non-nil error.
40 func (c *Client) EachKeepService(f func(KeepService) error) error {
41 params := ResourceListParams{}
43 var page KeepServiceList
44 err := c.RequestAndDecode(&page, "GET", "arvados/v1/keep_services", nil, params)
48 for _, item := range page.Items {
54 params.Offset = params.Offset + len(page.Items)
55 if params.Offset >= page.ItemsAvailable {
61 func (s *KeepService) url(path string) string {
64 f = "https://%s:%d/%s"
68 return fmt.Sprintf(f, s.ServiceHost, s.ServicePort, path)
71 // String implements fmt.Stringer
72 func (s *KeepService) String() string {
76 // Index returns an unsorted list of blocks that can be retrieved from
78 func (s *KeepService) Index(c *Client, prefix string) ([]KeepServiceIndexEntry, error) {
79 url := s.url("index/" + prefix)
80 req, err := http.NewRequest("GET", url, nil)
82 return nil, fmt.Errorf("NewRequest(%v): %v", url, err)
84 resp, err := c.Do(req)
86 return nil, fmt.Errorf("Do(%v): %v", url, err)
87 } else if resp.StatusCode != 200 {
88 return nil, fmt.Errorf("%v: %v", url, resp.Status)
90 defer resp.Body.Close()
92 var entries []KeepServiceIndexEntry
93 scanner := bufio.NewScanner(resp.Body)
97 return nil, fmt.Errorf("Index response contained non-terminal blank line")
99 line := scanner.Text()
104 fields := strings.Split(line, " ")
105 if len(fields) != 2 {
106 return nil, fmt.Errorf("Malformed index line %q: %d fields", line, len(fields))
108 mtime, err := strconv.ParseInt(fields[1], 10, 64)
110 return nil, fmt.Errorf("Malformed index line %q: mtime: %v", line, err)
113 // An old version of keepstore is giving us
114 // timestamps in seconds instead of
115 // nanoseconds. (This threshold correctly
116 // handles all times between 1970-01-02 and
120 entries = append(entries, KeepServiceIndexEntry{
121 SizedDigest: SizedDigest(fields[0]),
125 if err := scanner.Err(); err != nil {
126 return nil, fmt.Errorf("Error scanning index response: %v", err)
129 return nil, fmt.Errorf("Index response had no EOF marker")