go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/run/pubsub/publisher.go (about) 1 // Copyright 2021 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package pubsub 16 17 import ( 18 "context" 19 20 "google.golang.org/protobuf/encoding/protojson" 21 "google.golang.org/protobuf/proto" 22 23 "go.chromium.org/luci/server/tq" 24 25 cvpb "go.chromium.org/luci/cv/api/v1" 26 "go.chromium.org/luci/cv/internal/common" 27 "go.chromium.org/luci/cv/internal/rpc/versioning" 28 "go.chromium.org/luci/cv/internal/run" 29 ) 30 31 const ( 32 v1RunEndedTopic = "v1.run_ended" 33 v1RunEndedTaskClass = "v1-publish-run-ended" 34 ) 35 36 // Publisher publishes a message for various run events into Cloud PubSub 37 // topics. 38 type Publisher struct { 39 tqd *tq.Dispatcher 40 } 41 42 // NewPublisher creates a new Publisher and registers TaskClasses for run 43 // events. 44 func NewPublisher(tqd *tq.Dispatcher, env *common.Env) *Publisher { 45 p := &Publisher{tqd} 46 tqd.RegisterTaskClass(tq.TaskClass{ 47 ID: v1RunEndedTaskClass, 48 Topic: v1RunEndedTopic, 49 Prototype: &PublishRunEndedTask{}, 50 Kind: tq.Transactional, 51 Custom: func(ctx context.Context, m proto.Message) (*tq.CustomPayload, error) { 52 t := m.(*PublishRunEndedTask) 53 blob, err := (protojson.MarshalOptions{Indent: "\t"}).Marshal(&cvpb.PubSubRun{ 54 Id: t.GetPublicId(), 55 Status: versioning.RunStatusV1(t.GetStatus()), 56 Eversion: t.GetEversion(), 57 Hostname: env.LogicalHostname, 58 }) 59 if err != nil { 60 return nil, err 61 } 62 return &tq.CustomPayload{ 63 Meta: map[string]string{ 64 "status": t.Status.String(), 65 "luci_project": t.LuciProject, 66 }, 67 Body: blob, 68 }, nil 69 }, 70 }) 71 return p 72 } 73 74 // RunEnded schedules a task to publish a RunEnded message. 75 func (s *Publisher) RunEnded(ctx context.Context, rid common.RunID, status run.Status, eVersion int64) error { 76 return s.tqd.AddTask(ctx, &tq.Task{ 77 Payload: &PublishRunEndedTask{ 78 PublicId: rid.PublicID(), 79 LuciProject: rid.LUCIProject(), 80 Status: status, 81 Eversion: eVersion, 82 }, 83 }) 84 }