diff --git a/personal/q3k/mirko.jsonnet b/personal/q3k/mirko.jsonnet index 794e3f53..84a60397 100644 --- a/personal/q3k/mirko.jsonnet +++ b/personal/q3k/mirko.jsonnet @@ -4,7 +4,7 @@ local mirko = import "../../kube/mirko.libsonnet"; local top = self, shipstuck:: { cfg:: { - image: "registry.k0.hswaw.net/q3k/shipstuck:315532800-99b91b11f1e033cf7b10130722feb4a3111201bf", + image: "registry.k0.hswaw.net/q3k/shipstuck:315532800-83918968ad5abe42be32f55fe1037d3fa8e74d16", domain: error "domain must be set", }, component(cfg, env): mirko.Component(env, "shipstuck") { diff --git a/personal/q3k/shipstuck/main.go b/personal/q3k/shipstuck/main.go index 70ee459f..a43c5e71 100644 --- a/personal/q3k/shipstuck/main.go +++ b/personal/q3k/shipstuck/main.go @@ -22,19 +22,24 @@ type vessel struct { // get retrieves the current status of the ship - returns true if stack, false // otherwise. -func get(ctx context.Context) (bool, error) { +func get(ctx context.Context) (shipState, error) { // Sorry vesselfinder, if you made it easy to set up an account I would // gladly pay for the API instead of doing this. Limiting requests to once // every 15 minutes though, that seems fair enough. req, err := http.NewRequestWithContext(ctx, "GET", "https://www.vesselfinder.com/api/pub/click/353136000", nil) if err != nil { - return false, fmt.Errorf("NewRequestWithContext: %w", err) + return shipStateUnknown, fmt.Errorf("NewRequestWithContext: %w", err) } req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0") res, err := http.DefaultClient.Do(req) if err != nil { - return false, fmt.Errorf("Do: %w", err) + // vesselfinder.com down on 2021/03/29, add a 'cached' status for one hour as a hack. + if time.Now().Unix() < (1617024611 + 3600) { + return shipStateTowed, nil + glog.Warningf("Faking vesselfinder return.") + } + return shipStateUnknown, fmt.Errorf("Do: %w", err) } defer res.Body.Close() @@ -42,15 +47,16 @@ func get(ctx context.Context) (bool, error) { v := &vessel{} err = json.NewDecoder(res.Body).Decode(v) if err != nil { - return false, fmt.Errorf("Decode: %w", err) + return shipStateUnknown, fmt.Errorf("Decode: %w", err) } - if v.Speed < 0.5 { - return true, nil - } else { - glog.Infof("Freed! %+v", v) - return false, nil + if v.Speed > 10.0 { + return shipStateFreed, nil } + if v.Speed > 0.5 { + return shipStateTowed, nil + } + return shipStateStuck, nil } type shipState string @@ -59,6 +65,7 @@ const ( shipStateUnknown shipState = "UNKNOWN" shipStateStuck shipState = "STUCK" shipStateFreed shipState = "FREED" + shipStateTowed shipState = "TOWED" ) type service struct { @@ -84,11 +91,7 @@ func (s *service) worker(ctx context.Context) { break } } else { - if stuck { - state = shipStateStuck - } else { - state = shipStateFreed - } + state = stuck break } } @@ -143,6 +146,9 @@ func (s *service) Status(ctx context.Context, req *pb.StatusRequest) (*pb.Status res.Elapsed = time.Since(timeStuck).Nanoseconds() case shipStateFreed: res.Current = pb.StatusResponse_STUCKNESS_FREE + case shipStateTowed: + res.Current = pb.StatusResponse_STUCKNESS_TOWED + res.Elapsed = time.Since(timeStuck).Nanoseconds() } return res, nil diff --git a/personal/q3k/shipstuck/proto/shipstuck.proto b/personal/q3k/shipstuck/proto/shipstuck.proto index f0836e11..a76d1993 100644 --- a/personal/q3k/shipstuck/proto/shipstuck.proto +++ b/personal/q3k/shipstuck/proto/shipstuck.proto @@ -23,8 +23,9 @@ message StatusResponse { STUCKNESS_STUCK = 1; STUCKNESS_FREE = 2; STUCKNESS_UNKNOWN = 3; + STUCKNESS_TOWED = 4; }; Stuckness current = 2; - // If STUCK, how many nanoseconds have elapsed since the whoopsie? + // If STUCK or TOWED, how many nanoseconds have elapsed since the whoopsie? int64 elapsed = 3; }