package rabbitmq import ( "context" "encoding/json" "time" "github.com/gogf/gf/v2/errors/gerror" amqp "github.com/rabbitmq/amqp091-go" ) func PublishConfirmed(ctx context.Context, queue string, data any) error { body, err := json.Marshal(data) if err != nil { return err } channel, err := Channel(ctx) if err != nil { return err } defer channel.Close() if err = declareQueue(channel, queue); err != nil { return err } if err = channel.Confirm(false); err != nil { return err } confirmations := channel.NotifyPublish(make(chan amqp.Confirmation, 1)) returns := channel.NotifyReturn(make(chan amqp.Return, 1)) ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() if err = channel.PublishWithContext(ctx, "", queue, true, false, amqp.Publishing{ ContentType: "application/json", DeliveryMode: amqp.Persistent, Timestamp: time.Now(), Body: body, }); err != nil { return err } select { case <-ctx.Done(): return ctx.Err() case returned := <-returns: return gerror.Newf("traffic usage message unroutable: %s", returned.ReplyText) case confirmation, ok := <-confirmations: if !ok || !confirmation.Ack { return gerror.New("traffic usage message was not confirmed") } select { case returned := <-returns: return gerror.Newf("traffic usage message unroutable: %s", returned.ReplyText) default: return nil } } }