eintopf.info@v0.13.16/service/killswitch/killswitch.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package killswitch 17 18 import ( 19 "context" 20 "fmt" 21 22 "eintopf.info/internal/xerror" 23 ) 24 25 // Service defines an interface for interacting with a killswitch service. 26 // 27 // -go:generate go run github.com/petergtz/pegomock/pegomock generate eintopf.info/service/killswitch Service --output=../../internal/mock/killswitch_service.go --package=mock --mock-name=KillswitchService 28 type Service interface { 29 // TurnOff tries to set the the state to off. 30 // Returns an error if the hash is invalid. 31 TurnOff(ctx context.Context, hash string) error 32 // TurnOn tries to set the the state to on. 33 // Returns an error if the hash is invalid. 34 TurnOn(ctx context.Context, hash string) error 35 // On returns wether the current state is set to on. 36 On(ctx context.Context) (bool, error) 37 } 38 39 // Storer provides methods to store or retrive the killswitch state. 40 // The state can either be on or off. 41 type Storer interface { 42 // SetState sets the state of the killswitch. 43 SetState(ctx context.Context, on bool) error 44 // GetState retrieves the state of the killswitch. 45 GetState(ctx context.Context) (bool, error) 46 } 47 48 // NewService returns a new killswitch service. It takes a list of hashes, that 49 // can be used to turn the state on or off. 50 func NewService(storer Storer, hashes []string) Service { 51 s := &service{ 52 hashes: make(map[string]struct{}, len(hashes)), 53 54 storer: storer, 55 } 56 57 for _, hash := range hashes { 58 s.hashes[hash] = struct{}{} 59 } 60 61 return s 62 } 63 64 type service struct { 65 hashes map[string]struct{} 66 67 storer Storer 68 } 69 70 // ErrInvalidHash indicates an invalid hash was provided. 71 var ErrInvalidHash = xerror.BadInputError{Err: fmt.Errorf("invalid hash")} 72 73 func (s *service) TurnOn(ctx context.Context, hash string) error { 74 if _, ok := s.hashes[hash]; !ok { 75 return ErrInvalidHash 76 } 77 return s.storer.SetState(ctx, false) 78 } 79 80 func (s *service) TurnOff(ctx context.Context, hash string) error { 81 if _, ok := s.hashes[hash]; !ok { 82 return ErrInvalidHash 83 } 84 return s.storer.SetState(ctx, true) 85 } 86 87 func (s *service) On(ctx context.Context) (bool, error) { 88 return s.storer.GetState(ctx) 89 }