X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2dec79b036796df75885abf4e1a977958f9c541d..4ed6415ef859ccca13a46c77046f9febfb05bb2b:/services/ws/event.go diff --git a/services/ws/event.go b/services/ws/event.go index 26cdb3b534..8b6a2e81bb 100644 --- a/services/ws/event.go +++ b/services/ws/event.go @@ -1,4 +1,72 @@ -package main +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +package ws + +import ( + "database/sql" + "sync" + "time" + + "git.arvados.org/arvados.git/sdk/go/arvados" + "github.com/ghodss/yaml" + "github.com/sirupsen/logrus" +) + +type eventSink interface { + Channel() <-chan *event + Stop() +} + +type eventSource interface { + NewSink() eventSink + DB() *sql.DB + DBHealth() error +} type event struct { + LogID int64 + Received time.Time + Ready time.Time + Serial uint64 + + db *sql.DB + logger logrus.FieldLogger + logRow *arvados.Log + err error + mtx sync.Mutex +} + +// Detail returns the database row corresponding to the event. It can +// be called safely from multiple goroutines. Only one attempt will be +// made. If the database row cannot be retrieved, Detail returns nil. +func (e *event) Detail() *arvados.Log { + e.mtx.Lock() + defer e.mtx.Unlock() + if e.logRow != nil || e.err != nil { + return e.logRow + } + var logRow arvados.Log + var propYAML []byte + e.err = e.db.QueryRow(`SELECT id, uuid, object_uuid, COALESCE(object_owner_uuid,''), COALESCE(event_type,''), event_at, created_at, properties FROM logs WHERE id = $1`, e.LogID).Scan( + &logRow.ID, + &logRow.UUID, + &logRow.ObjectUUID, + &logRow.ObjectOwnerUUID, + &logRow.EventType, + &logRow.EventAt, + &logRow.CreatedAt, + &propYAML) + if e.err != nil { + e.logger.WithField("LogID", e.LogID).WithError(e.err).Error("QueryRow failed") + return nil + } + e.err = yaml.Unmarshal(propYAML, &logRow.Properties) + if e.err != nil { + e.logger.WithField("LogID", e.LogID).WithError(e.err).Error("yaml decode failed") + return nil + } + e.logRow = &logRow + return e.logRow }