21023: Avoid overloading 503 status.
[arvados.git] / services / keepstore / keepstore.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package keepstore
6
7 import (
8         "net/http"
9         "time"
10 )
11
12 // BlockSize for a Keep "block" is 64MB.
13 const BlockSize = 64 * 1024 * 1024
14
15 // MinFreeKilobytes is the amount of space a Keep volume must have available
16 // in order to permit writes.
17 const MinFreeKilobytes = BlockSize / 1024
18
19 var bufs *bufferPool
20
21 type KeepError struct {
22         HTTPCode int
23         ErrMsg   string
24 }
25
26 var (
27         BadRequestError     = &KeepError{http.StatusBadRequest, "Bad Request"}
28         UnauthorizedError   = &KeepError{http.StatusUnauthorized, "Unauthorized"}
29         CollisionError      = &KeepError{http.StatusInternalServerError, "Collision"}
30         RequestHashError    = &KeepError{http.StatusUnprocessableEntity, "Hash mismatch in request"}
31         PermissionError     = &KeepError{http.StatusForbidden, "Forbidden"}
32         DiskHashError       = &KeepError{http.StatusInternalServerError, "Hash mismatch in stored data"}
33         ExpiredError        = &KeepError{http.StatusUnauthorized, "Expired permission signature"}
34         NotFoundError       = &KeepError{http.StatusNotFound, "Not Found"}
35         VolumeBusyError     = &KeepError{http.StatusServiceUnavailable, "Volume backend busy"}
36         GenericError        = &KeepError{http.StatusInternalServerError, "Fail"}
37         FullError           = &KeepError{http.StatusInsufficientStorage, "Full"}
38         SizeRequiredError   = &KeepError{http.StatusLengthRequired, "Missing Content-Length"}
39         TooLongError        = &KeepError{http.StatusRequestEntityTooLarge, "Block is too large"}
40         MethodDisabledError = &KeepError{http.StatusMethodNotAllowed, "Method disabled"}
41         ErrNotImplemented   = &KeepError{http.StatusInternalServerError, "Unsupported configuration"}
42         ErrClientDisconnect = &KeepError{499, "Client disconnected"} // non-RFC Nginx status code
43 )
44
45 func (e *KeepError) Error() string {
46         return e.ErrMsg
47 }
48
49 // Periodically (once per interval) invoke EmptyTrash on all volumes.
50 func emptyTrash(mounts []*VolumeMount, interval time.Duration) {
51         for range time.NewTicker(interval).C {
52                 for _, v := range mounts {
53                         if v.KeepMount.AllowTrash {
54                                 v.EmptyTrash()
55                         }
56                 }
57         }
58 }