code.gitea.io/gitea@v1.19.3/modules/queue/setting.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package queue 5 6 import ( 7 "fmt" 8 "strings" 9 10 "code.gitea.io/gitea/modules/json" 11 "code.gitea.io/gitea/modules/log" 12 "code.gitea.io/gitea/modules/setting" 13 ) 14 15 func validType(t string) (Type, error) { 16 if len(t) == 0 { 17 return PersistableChannelQueueType, nil 18 } 19 for _, typ := range RegisteredTypes() { 20 if t == string(typ) { 21 return typ, nil 22 } 23 } 24 return PersistableChannelQueueType, fmt.Errorf("unknown queue type: %s defaulting to %s", t, string(PersistableChannelQueueType)) 25 } 26 27 func getQueueSettings(name string) (setting.QueueSettings, []byte) { 28 q := setting.GetQueueSettings(name) 29 cfg, err := json.Marshal(q) 30 if err != nil { 31 log.Error("Unable to marshall generic options: %v Error: %v", q, err) 32 log.Error("Unable to create queue for %s", name, err) 33 return q, []byte{} 34 } 35 return q, cfg 36 } 37 38 // CreateQueue for name with provided handler and exemplar 39 func CreateQueue(name string, handle HandlerFunc, exemplar interface{}) Queue { 40 q, cfg := getQueueSettings(name) 41 if len(cfg) == 0 { 42 return nil 43 } 44 45 typ, err := validType(q.Type) 46 if err != nil { 47 log.Error("Invalid type %s provided for queue named %s defaulting to %s", q.Type, name, string(typ)) 48 } 49 50 returnable, err := NewQueue(typ, handle, cfg, exemplar) 51 if q.WrapIfNecessary && err != nil { 52 log.Warn("Unable to create queue for %s: %v", name, err) 53 log.Warn("Attempting to create wrapped queue") 54 returnable, err = NewQueue(WrappedQueueType, handle, WrappedQueueConfiguration{ 55 Underlying: typ, 56 Timeout: q.Timeout, 57 MaxAttempts: q.MaxAttempts, 58 Config: cfg, 59 QueueLength: q.QueueLength, 60 Name: name, 61 }, exemplar) 62 } 63 if err != nil { 64 log.Error("Unable to create queue for %s: %v", name, err) 65 return nil 66 } 67 68 // Sanity check configuration 69 if q.Workers == 0 && (q.BoostTimeout == 0 || q.BoostWorkers == 0 || q.MaxWorkers == 0) { 70 log.Warn("Queue: %s is configured to be non-scaling and have no workers\n - this configuration is likely incorrect and could cause Gitea to block", q.Name) 71 if pausable, ok := returnable.(Pausable); ok { 72 log.Warn("Queue: %s is being paused to prevent data-loss, add workers manually and unpause.", q.Name) 73 pausable.Pause() 74 } 75 } 76 77 return returnable 78 } 79 80 // CreateUniqueQueue for name with provided handler and exemplar 81 func CreateUniqueQueue(name string, handle HandlerFunc, exemplar interface{}) UniqueQueue { 82 q, cfg := getQueueSettings(name) 83 if len(cfg) == 0 { 84 return nil 85 } 86 87 if len(q.Type) > 0 && q.Type != "dummy" && q.Type != "immediate" && !strings.HasPrefix(q.Type, "unique-") { 88 q.Type = "unique-" + q.Type 89 } 90 91 typ, err := validType(q.Type) 92 if err != nil || typ == PersistableChannelQueueType { 93 typ = PersistableChannelUniqueQueueType 94 if err != nil { 95 log.Error("Invalid type %s provided for queue named %s defaulting to %s", q.Type, name, string(typ)) 96 } 97 } 98 99 returnable, err := NewQueue(typ, handle, cfg, exemplar) 100 if q.WrapIfNecessary && err != nil { 101 log.Warn("Unable to create unique queue for %s: %v", name, err) 102 log.Warn("Attempting to create wrapped queue") 103 returnable, err = NewQueue(WrappedUniqueQueueType, handle, WrappedUniqueQueueConfiguration{ 104 Underlying: typ, 105 Timeout: q.Timeout, 106 MaxAttempts: q.MaxAttempts, 107 Config: cfg, 108 QueueLength: q.QueueLength, 109 }, exemplar) 110 } 111 if err != nil { 112 log.Error("Unable to create unique queue for %s: %v", name, err) 113 return nil 114 } 115 116 // Sanity check configuration 117 if q.Workers == 0 && (q.BoostTimeout == 0 || q.BoostWorkers == 0 || q.MaxWorkers == 0) { 118 log.Warn("Queue: %s is configured to be non-scaling and have no workers\n - this configuration is likely incorrect and could cause Gitea to block", q.Name) 119 if pausable, ok := returnable.(Pausable); ok { 120 log.Warn("Queue: %s is being paused to prevent data-loss, add workers manually and unpause.", q.Name) 121 pausable.Pause() 122 } 123 } 124 125 return returnable.(UniqueQueue) 126 }