8460: Hide *websocket.Conn behind interface.
[arvados.git] / services / ws / event.go
index 26cdb3b5349ffff685257a3a25c60af76b190aaf..7e27e09ce17bd1b66b2ff5ad9521c5581b094a59 100644 (file)
@@ -1,4 +1,55 @@
 package main
 
+import (
+       "database/sql"
+       "log"
+       "sync"
+       "time"
+
+       "git.curoverse.com/arvados.git/sdk/go/arvados"
+)
+
+type eventSink interface {
+       Channel() <-chan *event
+       Stop()
+}
+
+type eventSource interface {
+       NewSink(chan *event) eventSink
+}
+
 type event struct {
+       LogUUID  string
+       Received time.Time
+       Serial   uint64
+
+       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(db *sql.DB) *arvados.Log {
+       e.mtx.Lock()
+       defer e.mtx.Unlock()
+       if e.logRow != nil || e.err != nil || db == nil {
+               return e.logRow
+       }
+       var logRow arvados.Log
+       var oldAttrs, newAttrs []byte
+       e.err = db.QueryRow(`SELECT id, uuid, object_uuid, object_owner_uuid, event_type, created_at, old_attributes, new_attributes FROM logs WHERE uuid = ?`, e.LogUUID).Scan(
+               &logRow.ID,
+               &logRow.UUID,
+               &logRow.ObjectUUID,
+               &logRow.ObjectOwnerUUID,
+               &logRow.EventType,
+               &logRow.CreatedAt,
+               &oldAttrs,
+               &newAttrs)
+       if e.err != nil {
+               log.Printf("retrieving log row %s: %s", e.LogUUID, e.err)
+       }
+       return e.logRow
 }