eclipse / paho.golang

Go libraries

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Autopaho context deadline exceeded on publish

patilsnr opened this issue · comments

When writing a pub/sub application using the basics example to Azure Eventgrid, I get an error trying to publish to a topic.

image

The error occurs when trying to publish a message with QoS 1. Up to this point, the connection comes up (using certs via TlsConfig in autopaho), and subscribe to the topic that I'm trying to publish to in the OnConnectionUp callback. My publish operation looks like this:

// Publish
if _, err = c.Publish(ctx, &paho.Publish{
QoS:     1,
Topic:   "sample/+",
Payload: []byte("Hello, from Go!"),
}); err != nil {
panic(err)
}

It's not valid to have wildcard characters in the topic for a publish

https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107

It's not valid to have wildcard characters in the topic for a publish

https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107

Thanks! I have updated and am still seeing the issue:

// Publish
if _, err = c.Publish(ctx, &paho.Publish{
QoS:     1,
Topic:   topic,
Payload: []byte("TestMessage"),
}); err != nil {
panic(err)
}

Show us how you are connecting (aim for a reproducible example, and please include things like version info as requested in the template).

My guess is that you are using autopaho and cancelling the context you passed it (which leads to it disconnecting).

clientConfig := autopaho.ClientConfig{
	BrokerUrls: []*url.URL{u},
	TlsCfg:     cfg,
	KeepAlive:  30,
	OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) {
		fmt.Println("mqtt connection up")
		if _, err := cm.Subscribe(context.Background(), &paho.Subscribe{
			Subscriptions: []paho.SubscribeOptions{
				{Topic: topic, QoS: 1},
			},
		}); err != nil {
			fmt.Printf("failed to subscribe (%s). This is likely to mean no messages will be received!\n", err)
		}
		fmt.Println("mqtt subscription made")
	},
	OnConnectError: func(err error) { fmt.Printf("error whilst attempting connection: %s\n", err) },
	ClientConfig: paho.ClientConfig{
		ClientID: clientId,
		Router: paho.NewSingleHandlerRouter(func(m *paho.Publish) {
			fmt.Printf("received message on topic %s; body: %s (retain: %t)\n", m.Topic, m.Payload, m.Retain)
		}),
		OnClientError: func(err error) { fmt.Printf("server requested disconnect: %s\n", err) },
		OnServerDisconnect: func(d *paho.Disconnect) {
			if d.Properties != nil {
				fmt.Printf("server requested disconnect: %s\n", d.Properties.ReasonString)
			} else {
				fmt.Printf("server requested disconnect; reason code: %d\n", d.ReasonCode)
			}
		},
	},
}

clientConfig.SetUsernamePassword(username, nil)

fmt.Println("Attempting to connect")
c, err := autopaho.NewConnection(ctx, clientConfig) // starts process; will reconnect until context cancelled
if err != nil {
	panic(err)
}
// Wait for the connection to come up
if err = c.AwaitConnection(ctx); err != nil {
	panic(err)
}

I'm using v0.12.0 and running Go 1.21.3. To reproduce the error, I create a clientConfig and connect as shown above.

My context is the same as basics:

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

Missed another wildcard character which turned out to be the issue. Thanks for the help, and I'll be more verbose about my setup in future issues.

The question was more what happens after the c.AwaitConnection(ctx); is this in a connect function that then returns? If so then I would expect the result you are seeing:

  1. Connection up so OnConnectionUp called (in go routine) and c.AwaitConnection also returns.
  2. As c.AwaitConnection has returned your function exits and the deferred stop() runs.
  3. autopaho shuts the connection down due to the cancelled context
  4. Calling Publish returns the error due to the cancelled context

If this is not what is happening (the issue was due to the wildcard character) then I'd suggest reopening this issue because a wildcard character should not lead to that error (and we need to fix that to avoid confusing others in the future!). This is why a minimal, reproducible, example is really handy (also helps us be sure we have fixed the issue!).

I'm using v0.12.0

Please not that that version does not fully support QOS 2; it will work but if the connection drops then any in progress messages will be lost and it will reconnect with Clean Start=true (kind of defeating the reason for using QOS2!). I'd recommend using @master which addresses this (I've had it running in production for a couple of weeks; found and fixed one issue but other than that its running smoothly).