2025-05-20 09:40:15 +00:00
|
|
|
// Copyright 2025 Cloudbase Solutions SRL
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
|
// not use this file except in compliance with the License. You may obtain
|
|
|
|
|
// a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
|
// License for the specific language governing permissions and limitations
|
|
|
|
|
// under the License.
|
|
|
|
|
|
2024-04-03 14:46:32 +00:00
|
|
|
package watcher
|
|
|
|
|
|
|
|
|
|
import (
|
2024-06-17 19:42:50 +00:00
|
|
|
"context"
|
2024-04-03 14:46:32 +00:00
|
|
|
"log/slog"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/cloudbase/garm/database/common"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type consumer struct {
|
|
|
|
|
messages chan common.ChangePayload
|
|
|
|
|
filters []common.PayloadFilterFunc
|
|
|
|
|
id string
|
|
|
|
|
|
|
|
|
|
mux sync.Mutex
|
|
|
|
|
closed bool
|
|
|
|
|
quit chan struct{}
|
2024-06-17 19:42:50 +00:00
|
|
|
ctx context.Context
|
2024-04-03 14:46:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *consumer) SetFilters(filters ...common.PayloadFilterFunc) {
|
|
|
|
|
w.mux.Lock()
|
|
|
|
|
defer w.mux.Unlock()
|
|
|
|
|
w.filters = filters
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *consumer) Watch() <-chan common.ChangePayload {
|
|
|
|
|
return w.messages
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *consumer) Close() {
|
|
|
|
|
w.mux.Lock()
|
|
|
|
|
defer w.mux.Unlock()
|
|
|
|
|
if w.closed {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
close(w.messages)
|
|
|
|
|
close(w.quit)
|
|
|
|
|
w.closed = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *consumer) IsClosed() bool {
|
|
|
|
|
w.mux.Lock()
|
|
|
|
|
defer w.mux.Unlock()
|
|
|
|
|
return w.closed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (w *consumer) Send(payload common.ChangePayload) {
|
|
|
|
|
w.mux.Lock()
|
|
|
|
|
defer w.mux.Unlock()
|
|
|
|
|
|
|
|
|
|
if w.closed {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(w.filters) > 0 {
|
2024-06-17 19:42:50 +00:00
|
|
|
shouldSend := true
|
2024-04-03 14:46:32 +00:00
|
|
|
for _, filter := range w.filters {
|
2024-06-17 19:42:50 +00:00
|
|
|
if !filter(payload) {
|
|
|
|
|
shouldSend = false
|
2024-04-03 14:46:32 +00:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !shouldSend {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 10:48:27 +00:00
|
|
|
timer := time.NewTimer(1 * time.Second)
|
|
|
|
|
defer timer.Stop()
|
2024-06-17 19:42:50 +00:00
|
|
|
slog.DebugContext(w.ctx, "sending payload")
|
2024-04-03 14:46:32 +00:00
|
|
|
select {
|
2024-06-17 19:42:50 +00:00
|
|
|
case <-w.quit:
|
|
|
|
|
slog.DebugContext(w.ctx, "consumer is closed")
|
|
|
|
|
case <-w.ctx.Done():
|
|
|
|
|
slog.DebugContext(w.ctx, "consumer is closed")
|
2024-07-05 10:48:27 +00:00
|
|
|
case <-timer.C:
|
2024-06-17 19:42:50 +00:00
|
|
|
slog.DebugContext(w.ctx, "timeout trying to send payload", "payload", payload)
|
|
|
|
|
case w.messages <- payload:
|
2024-04-03 14:46:32 +00:00
|
|
|
}
|
|
|
|
|
}
|