简体   繁体   中英

Google PubSub and Go: create client outside or inside publish-function?

I'm new when it comes to Google PubSub(and pubsub applications in general). I'm also relatively new when it comes to Go.

I'm working on a pretty heavy backend service application that already has too many responsibilities. The service needs to fire off one message for each incoming request to a Google PubSub topic. It only needs to "fire and forget". If something goes wrong with the publishing, nothing will happen. The messages are not crucial(only used for analytics), but there will be many of them. We estimate between 50 and 100 messages per second for most of the day.

Now to the code:

func(p *publisher) Publish(message Message, log zerolog.Logger) error {
    ctx := context.Background()
    client, err := pubsub.NewClient(ctx, p.project)
    defer client.Close()
    if err != nil {
        log.Error().Msgf("Error creating client: %v", err)
        return err
    }

    marshalled, _ := json.Marshal(message)
    topic := client.Topic(p.topic)
    result := topic.Publish(ctx, &pubsub.Message{
        Data: marshalled,
    })
    _, err = result.Get(ctx)
    if err != nil {
        log.Error().Msgf("Failed to publish message: %v", err)
        return err
    }
    return nil
}

Disclaimer: p *publisher only contains configuration.

I wonder if this is the best way? Will this lead to the service creating and closing a client 100 times per second? If so, then I guess I should create the client once and pass it as an argument to the Publish()-function instead?

This is how the Publish()-function gets called:

defer func(publisher publish.Publisher, message Message, log zerolog.Logger) {
    err := publisher.Publish(log, Message)
    if err != nil {
        log.Error().Msgf("Failed to publish message: %v", err)
    }
}(publisher, message, logger,)

Maybe the way to go is to hold pubsubClient & pubsubTopic inside struct?

type myStruct struct {
    pubsubClient *pubsub.Client
    pubsubTopic  *pubsub.Topic
    logger       *yourLogger.Logger



}

func newMyStruct(projectID string) (*myStruct, error) {
    ctx := context.Background()
    pubsubClient, err := pubusb.NewClient(ctx, projectID)
    if err != nil {...}
    pubsubTopic := pubsubClient.Topic(topicName)
    return &myStruct{
    pubsubClient: pubsubClient,
    pubsubTopic: pubsubTopic,
    logger: Logger,
    // and whetever you want :D 
    }

} 

And then for that struct create a method, which will take responsibility of marshalling the msg and sends it to Pub/sub

func (s *myStruct) request(ctx context.Context data yorData) {
    marshalled, err := json.Marshal(message)
    if err != nil {..}
    res := s.pubsubTopic.Publish(ctx,  &pubsub.Message{
        Data: marshalled,
    })
    if _, err := res.Get(ctx); err !=nil {..}
    return nil

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM