Git Product home page Git Product logo

Comments (13)

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

Is the call to session.NewSender() hanging? Also, has the received message been settled yet?

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

I tried to create a repro based on the provided information but couldn't. Could you please provide more detail, and/or a code sample?

from go-amqp.

yockii avatar yockii commented on September 28, 2024

thank you for reply.
Yes, the session.NewSender is hanging.
to reproduce the stage, there should have at lease 10 messages overstock.

the Pseudo code should like this:
`
var senders map[string]*amqp.Sender
// ......
msg, err := receiver.Receive(ctx)
if err != nil {
return err
}

// ....
sender, ok := senders[queue]
if !ok {
sender, err = session.NewSender(opts...)
if err != nil {
return err
}
senders[queue] = sender
}

_ = sender.Send(ctx, msg)

// ....
receiver.AcceptMessage(ctx, msg)
`

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

Thanks for the info. I'm still unable to repro this using v0.17.0. In your pseudo-code, are all the operations running on the same goroutine? What are the options you're using to create the sender and receiver? Also, what version are you using?

from go-amqp.

yockii avatar yockii commented on September 28, 2024

Thanks for the info. I'm still unable to repro this using v0.17.0. In your pseudo-code, are all the operations running on the same goroutine? What are the options you're using to create the sender and receiver? Also, what version are you using?

I used v0.13, and I updated to v0.17.0 after this bug, also rewrite some code (some api changed), but the bug still there.
and yes, all the operations running on the same goroutine.
I use these code to create sender and receiver:
session.NewReceiver( amqp.LinkSourceAddress(queue), amqp.LinkCredit(1), )
`var opts []amqp.LinkOption

opts = append(opts, amqp.LinkTargetAddress(queue))

senders[queue], err = mq.session.NewSender(opts...)`

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

Here's my repro code. Does any of this look similar to what you're doing? Also, what peer are you connecting to, is it Azure service bus, or something else?

func main() {
	// prime with messages
	client, err := amqp.Dial("amqp://localhost:25672")
	if err != nil {
		panic(err)
	}
	session, err := client.NewSession()
	if err != nil {
		panic(err)
	}
	sender, err := session.NewSender(
		amqp.LinkTargetAddress("helloworld"))
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		msg := amqp.NewMessage([]byte(fmt.Sprintf("test %d", i)))
		if err = sender.Send(context.Background(), msg); err != nil {
			panic(err)
		}
	}

	// receive one message
	recv, err := session.NewReceiver(
		amqp.LinkSourceAddress("helloworld"),
		amqp.LinkCredit(1))
	if err != nil {
		panic(err)
	}
	msg, err := recv.Receive(context.Background())
	if err != nil {
		panic(err)
	}

	// try to create new sender
	_, err = session.NewSender(
		amqp.LinkTargetAddress("helloworld"))
	if err != nil {
		panic(err)
	}
	fmt.Println(string(msg.GetData()))
	recv.AcceptMessage(context.Background(), msg)
}

from go-amqp.

yockii avatar yockii commented on September 28, 2024

almost the same except the begining, the message producer is another program, so i prefer to have a different session to first create receiver then sender.

and I use activeMQ5 locally.
the project is just in test stage

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

I installed ActiveMQ 5.16.3 but still can't repro. I didn't change any config options for ActiveMQ though. Do you use a different configuration?

from go-amqp.

yockii avatar yockii commented on September 28, 2024

Please try this, it will only print 2 message on console

package main

import (
	"context"
	"fmt"

	"github.com/Azure/go-amqp"
)

func main() {
	sendInitMsg()
	lockCode()
}

func lockCode() {
	client, err := amqp.Dial("amqp://localhost:5672", amqp.ConnSASLAnonymous())
	if err != nil {
		panic(err)
	}
	session, err := client.NewSession()
	if err != nil {
		panic(err)
	}
	var sender *amqp.Sender
	for {
		// receive one message
		recv, err := session.NewReceiver(
			amqp.LinkSourceAddress("helloworld"),
			amqp.LinkCredit(10))
		if err != nil {
			panic(err)
		}
		msg, err := recv.Receive(context.Background())
		if err != nil {
			panic(err)
		}

		// try to create new sender
		if sender == nil {
			sender, err = session.NewSender(
				amqp.LinkTargetAddress("helloworld222"))
			if err != nil {
				panic(err)
			}
		}
		fmt.Println(string(msg.GetData()))
		sender.Send(context.Background(), msg)
		recv.AcceptMessage(context.Background(), msg)
	}
}

func sendInitMsg() {
	client, err := amqp.Dial("amqp://localhost:5672", amqp.ConnSASLAnonymous())
	if err != nil {
		panic(err)
	}
	session, err := client.NewSession()
	if err != nil {
		panic(err)
	}
	sender, err := session.NewSender(
		amqp.LinkTargetAddress("helloworld"))
	if err != nil {
		panic(err)
	}
	for i := 0; i < 100; i++ {
		msg := amqp.NewMessage([]byte(fmt.Sprintf("test %d", i)))
		if err = sender.Send(context.Background(), msg); err != nil {
			panic(err)
		}
	}
}

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

Thanks this repros for me. My repro wasn't attempting to send a message on the new sender. I'm investigating.

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

The issue is with link credit management. In this case, no receiver settlement mode has been specified, so we don't pause receiving transfer frames when the link credit is exhausted.

One thing that stands out, if you require to explicitly settle your received messages (I assume you do since you call recv.AcceptMessage(context.Background(), msg), you need to create your receiver in mode second by including option amqp.LinkReceiverSettle(amqp.ModeSecond). With this I can confirm the bug doesn't repro.

from go-amqp.

yockii avatar yockii commented on September 28, 2024

sorry for long delay, when I tried

recv, err := session.NewReceiver(
		amqp.LinkSourceAddress("helloworld"),
		amqp.LinkCredit(10),
		//amqp.LinkReceiverSettle(amqp.ModeFirst),
		amqp.LinkReceiverSettle(amqp.ModeSecond),
	)
if err != nil {
		panic(err)
	}

some error got:
panic: amqp: receiver settlement mode "second" requested, received "first" from server

from go-amqp.

jhendrixMSFT avatar jhendrixMSFT commented on September 28, 2024

Fixing in pending release v0.18.1

from go-amqp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.