创建一个能够从 SQS 中读取消息而不终止的 GO 应用程序。

huangapple go评论88阅读模式
英文:

Create GO application that Reads from SQS without terminating

问题

我是Go的新手,绝对不是一个有经验的开发者,所以请随意批评。

我正在尝试创建一个Go应用程序,它将存在于一个容器中,并从AWS SQS中读取数据。目标是应用程序长时间运行并不断从队列中读取数据。

以下是我目前的示例代码。我最大的问题是,这种使用GOTO的方式是否不好,是否有更好的方法。

提前感谢你的帮助。

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/sqs"
)

const (
	maxMessages = 1
)

func GetQueueURL(cfg aws.Config, queue string) (*sqs.GetQueueUrlOutput, error) {
	sqsClient := sqs.NewFromConfig(cfg)

	result, err := sqsClient.GetQueueUrl(context.TODO(), &sqs.GetQueueUrlInput{
		QueueName: &queue,
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func GetMessages(cfg aws.Config, queueUrl string, maxMessages int32) (*sqs.ReceiveMessageOutput, error) {
	sqsClient := sqs.NewFromConfig(cfg)

	msgResult, err := sqsClient.ReceiveMessage(context.TODO(), &sqs.ReceiveMessageInput{
		QueueUrl:            &queueUrl,
		MaxNumberOfMessages: maxMessages,
		WaitTimeSeconds:     10,
	})

	if err != nil {
		return nil, err
	}

	return msgResult, nil
}

func main() {

	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatal("error")
	}

	queueName := "queue"

	res, err := GetQueueURL(cfg, queueName)
	if err != nil {
		fmt.Printf("Got an error receiving url: %v", err)
	}
FINDMESSAGE:
	msgRes, err := GetMessages(cfg, *res.QueueUrl, maxMessages)
	if err != nil {
		fmt.Printf("Got an error while trying to retrieve messages: %v", err)
	}

	if len(msgRes.Messages) != 0 {
		fmt.Println("Message Body: " + *msgRes.Messages[0].Body)
		fmt.Println("Message Handle: " + *msgRes.Messages[0].ReceiptHandle)
	}

	fmt.Println("No Messages")

	goto FINDMESSAGE

}
英文:

I am new to Go and I am not an experienced dev by any means so please feel free to bash away.

I am attempting to create a GO application that will live in a container and read from AWS SQS. The goal would be the app is long living and constantly reads from the Queue.

This is the code I have so far as an example. My biggest question is if this is a bad use of GOTO and is there better way.

Thank you in advance

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/sqs"
)

const (
	maxMessages = 1
)

func GetQueueURL(cfg aws.Config, queue string) (*sqs.GetQueueUrlOutput, error) {
	sqsClient := sqs.NewFromConfig(cfg)

	result, err := sqsClient.GetQueueUrl(context.TODO(), &sqs.GetQueueUrlInput{
		QueueName: &queue,
	})

	if err != nil {
		return nil, err
	}

	return result, nil
}

func GetMessages(cfg aws.Config, queueUrl string, maxMessages int32) (*sqs.ReceiveMessageOutput, error) {
	sqsClient := sqs.NewFromConfig(cfg)

	msgResult, err := sqsClient.ReceiveMessage(context.TODO(), &sqs.ReceiveMessageInput{
		QueueUrl: &queueUrl,
		MaxNumberOfMessages: maxMessages,
		WaitTimeSeconds: 10,
	})

	if err != nil {
		return nil, err
	}

	return msgResult, nil
}

func main() {

	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		log.Fatal("error")
	}

	queueName := "queue"

	res, err := GetQueueURL(cfg, queueName)
	if err != nil {
		fmt.Printf("Got an error receiving url: %v", err)
	}
	FINDMESSAGE:
		msgRes, err := GetMessages(cfg, *res.QueueUrl, maxMessages)
		if err != nil {
			fmt.Printf("Got an error while trying to retrieve messages: %v", err)
		}

		if len(msgRes.Messages) != 0 {
			fmt.Println("Message Body: " + *msgRes.Messages[0].Body)
			fmt.Println("Message Handle: " + *msgRes.Messages[0].ReceiptHandle)
		}

		fmt.Println("No Messages")

	goto FINDMESSAGE

}

</details>


# 答案1
**得分**: 0

任何使用`goto`都是不好的除非你能解释为什么要使用`goto`你的例子是一个for循环

```go
for {
        msgRes, err := GetMessages(cfg, *res.QueueUrl, maxMessages)
        if err != nil {
            fmt.Printf("在尝试检索消息时出错:%v", err)
        }

        if len(msgRes.Messages) != 0 {
            fmt.Println("消息正文:" + *msgRes.Messages[0].Body)
            fmt.Println("消息句柄:" + *msgRes.Messages[0].ReceiptHandle)
        }

        fmt.Println("没有消息")
}

请注意,这段代码中没有使用goto语句。如果你有关于goto语句的问题,请提供更多上下文信息。

英文:

> My biggest question is if this is a bad use of GOTO and is there better way.

any use of goto is a bad use of goto, unless you can express why you use a goto. Your example is a for loop:

for {
msgRes, err := GetMessages(cfg, *res.QueueUrl, maxMessages)
if err != nil {
fmt.Printf(&quot;Got an error while trying to retrieve messages: %v&quot;, err)
}
if len(msgRes.Messages) != 0 {
fmt.Println(&quot;Message Body: &quot; + *msgRes.Messages[0].Body)
fmt.Println(&quot;Message Handle: &quot; + *msgRes.Messages[0].ReceiptHandle)
}
fmt.Println(&quot;No Messages&quot;)
}

huangapple
  • 本文由 发表于 2022年9月20日 06:16:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/73779807.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定