mirror of
https://github.com/foomo/keel.git
synced 2026-10-05 22:56:57 +00:00
fix/read-update-write-createdat
Upsert and UpsertMany stamped createdAt whenever the entity carried a zero value. That guard silently inverts its meaning depending on whether the caller read the document first: a read-modify-write caller holds the stored value and keeps it, while a blind writer - an import feed, say - has nothing to supply and so overwrites the stored createdAt on every re-import. Entities can now implement EntityWithInsertOnlyFields to declare which fields must only ever be written on insert. Those elements are routed through $setOnInsert, so an upsert resolving to an update leaves them at their stored value while one that inserts writes them once. keel learns no field names in the process - the entity supplies them. That preserves the existing property that keel only names a field in order to query by it (id, version), never in order to write it. UpsertUpdate and ApplyTimestamps are exported so callers driving their own bulk writes, such as an import feed filtering on a staleness predicate, can apply the same policy rather than restating it per call site. Entities that do not implement the interface are written exactly as before, so existing consumers are unaffected; TestUpsertLegacyEntityBehaviourUnchanged pins that behaviour deliberately. Adds the first tests to persistence/mongo, backed by a mongo testcontainer.
keel
Opinionated way to run services on Kubernetes
Stack
- Zap
- Nats
- Viper
- GoTSRPC
- Temporal
- OpenTelemetry
Examples
See the examples folder for usages
package main
import (
"net/http"
"github.com/foomo/keel"
"github.com/foomo/keel/service"
)
func main() {
svr := keel.NewServer(
keel.WithHTTPZapService(true),
keel.WithHTTPViperService(true),
keel.WithHTTPPrometheusService(true),
)
l := svr.Logger()
svs := newService()
svr.AddService(
service.NewHTTP(l, "demo", "localhost:8080", svs),
)
svr.Run()
}
func newService() *http.ServeMux {
s := http.NewServeMux()
s.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("OK"))
})
return s
}
How to Contribute
Contributions are welcome! Please read the contributing guide.
License
Distributed under MIT License, please read the license file for more details.
Languages
Go
99.3%
Makefile
0.7%
