-
Notifications
You must be signed in to change notification settings - Fork 219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provide publish/subscribe options for MQTT protocol #924
Conversation
Topic/QoS/Retain
configuration for MQTT Sender protocolTopic/QoS/Retain
configuration for MQTT Sender protocol
protocol/mqtt_paho/v2/protocol.go
Outdated
QoS: qos, | ||
Retain: retain, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit (readability): please reorder, following topic/retain/qos flow from above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Digging more into the implementation, I have a general question @yanmxa on this PR: it seems that we're replicating functionality in the protocol context
which is already (partially) available in the protocol constructor New()
. Can you provide an example why someone would use the context
vs New()
to configure these settings? I understand that we do this to overwrite behavior for certain, but not all, Send()
calls in protocols. However, this proposal seems to create inconsistencies between the options available in the constructor New()
and what can be defined on context
. Also, I'm afraid we have to keep up with field level changes, i.e., add more fields, with the current proposal, so I was wondering whether there's a generic MQTT options/property struct we should allow (use) to influence all parameters in Send()
instead of handpicking a couple of options?
1. Why someone would use the When using MQTT sends a message, you can configure many parameters according to your needs. We provide the qos := 0
retained := false
packetId := uint16(123)
properties := &paho.PublishProperties{
TopicAlias: paho.Uint16(3),
}
pctx := cemqtt.ProtocolContext{
Topic: "test",
QoS : &qos,
Retained: &retained,
PacketID: &packetId,
PublishProperties: properties
}
ctx = cemqtt.WithProtocolContext(ctx, pctx) But in most cases, users only specify if result := c.Send(
cemqtt.WithProtocolContext(ctx, cemqtt.NewProtocolContext("test-topic", 0, false)),
e,
); 2. Whether there generic MQTT options/property struct we should allow (use) to influence all parameters in Send() instead of handpicking a couple of options? Yes. There is a generic MQTT option struct when sending the message, But in its implementation, both payload and properties are placed in the struct. That's the reason I created the |
I don't think this is the right use case for
I just checked our implementation and IMHO it would be fine to have the |
Agree with that. we can keep using function options with other parameters. At the same time, discard |
9804f12
to
8213648
Compare
@embano1 If I append the mqtt function option in the file |
5ab4a9b
to
90ae1c2
Compare
Sorry, I think I may have confused you somehow. I did not suggest using cecontext for this, but to implement everything in func New() of the protocol API e.g., using functional options and defaults. See http protocol implementation for how this is done there. |
0b64341
to
fa18dfb
Compare
Topic/QoS/Retain
configuration for MQTT Sender protocol
@yanmxa looks like you reverted to the mqtt context approach instead of what I meant following other protocol implementations e.g., http. Can you please review sdk-go/v2/protocol/http/protocol.go Line 95 in 3dfc033
|
Thanks @embano1! I misunderstood before. |
Send is an interface implementation. For those cases context is typically used. Can we start with New() in this PR and create a follow up PR if needed? |
e3b29d7
to
d3ae386
Compare
@yanmxa what do you think of using functional options in Mew() like other protocols do to reduce API surface, allow for API evolution, set defaults, etc.? |
@embano1 Do you mean define the functional options in Now MQTT protocol mainly has four parts option struct. In this way, we can reduce to provide only one necessary |
Great! Excited! |
protocol/mqtt_paho/v2/option.go
Outdated
func WithConnect(connOpt *paho.Connect) Option { | ||
return func(p *Protocol) error { | ||
if connOpt == nil { | ||
return fmt.Errorf("the paho.Connect option should not be nil") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should
-> must
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace in all places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
protocol/mqtt_paho/v2/protocol.go
Outdated
openerMutex: sync.Mutex{}, | ||
clientMutex: sync.Mutex{}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: zero values not needed to be set here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
protocol/mqtt_paho/v2/option.go
Outdated
} | ||
} | ||
|
||
// WithPublish sets an paho.Publish for the client. This option is required if you want to send message. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// WithPublish sets an paho.Publish for the client. This option is required if you want to send message. | |
// WithPublish sets the paho.Publish configuration for the client. This option is required if you want to send messages. |
protocol/mqtt_paho/v2/option.go
Outdated
} | ||
} | ||
|
||
// WithSubscribe sets an paho.Subscribe for the client. This option is required if you want to receive message. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// WithSubscribe sets an paho.Subscribe for the client. This option is required if you want to receive message. | |
// WithSubscribe sets the paho.Subscribe configuration for the client. This option is required if you want to receive messages. |
protocol/mqtt_paho/v2/protocol.go
Outdated
return err | ||
} | ||
if connAck.ReasonCode != 0 { | ||
return fmt.Errorf("failed to connect to %s : %d - %s", client.Conn.RemoteAddr(), connAck.ReasonCode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return fmt.Errorf("failed to connect to %s : %d - %s", client.Conn.RemoteAddr(), connAck.ReasonCode, | |
return fmt.Errorf("failed to connect to %q: %d - %q", client.Conn.RemoteAddr(), connAck.ReasonCode, |
samples/mqtt/sender/main.go
Outdated
p, err := mqtt_paho.New(ctx, clientConfig, connConfig, &paho.Publish{ | ||
Topic: "test-topic1", QoS: 0, | ||
}, nil) | ||
p, err := mqtt_paho.New(config, mqtt_paho.WithPublish(&paho.Publish{Topic: "test-topic1"}), mqtt_paho.WithConnect(connOpt)) | ||
if err != nil { | ||
log.Fatalf("failed to create protocol: %s", err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you can use %v
and just err
to reduce typing :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
protocol/mqtt_paho/v2/protocol.go
Outdated
return fmt.Errorf("the paho.Publish option should not be nil") | ||
} | ||
|
||
err := p.initClient(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: this is called in Send
and OpenInbound
which might be confusing/inconsistent across usage. Should initClient
be part of New()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's okay. Just if we put initClient
on New()
, then the ctx
must be added as the parameter of the New()
constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is an issue and makes the protocol even easier to use/harder to misuse
protocol/mqtt_paho/v2/protocol.go
Outdated
client := paho.NewClient(*clientConfig) | ||
ca, err := client.Connect(ctx, connConfig) | ||
if err != nil { | ||
func New(config *paho.ClientConfig, opts ...Option) (*Protocol, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
questions:
- should we keep
ctx
as first arg? - can we supply defaults to
config
so it can also become an option? I see it's mostly used to set a clientid
andconn
which can be defaulted IMHO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- We can keep the
ctx
as the first args. So I will init the client on theNew()
. - Of course, we can set the
id
by default. But I havn't figure out how can we set a defaultconn
for theconfig
?
If we don't specify theaddress
of theconn
, it seems there is no way to establish a connection. and throw the error message when connecting to the broker inNew()
:client connection is nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! Can you please squash the commits?
Are there any doc-related changes needed for this? |
Signed-off-by: myan <myan@redhat.com> to review Signed-off-by: myan <myan@redhat.com> avoid all-or-nothing Signed-off-by: myan <myan@redhat.com> rollback all-or-nothing Signed-off-by: myan <myan@redhat.com> convert tparamter to pointers Signed-off-by: myan <myan@redhat.com> fixed doc string Signed-off-by: myan <myan@redhat.com> remove the protocolContext Signed-off-by: myan <myan@redhat.com> add context for protocol Signed-off-by: myan <myan@redhat.com> initialize mqtt protocol with publish/subscribe options Signed-off-by: myan <myan@redhat.com> remove the sender options from context Signed-off-by: myan <myan@redhat.com> using functional options in new() Signed-off-by: myan <myan@redhat.com> add ctx to the new() function Signed-off-by: myan <myan@redhat.com>
Done! |
The protocol here has not changed, and it seems that there is no need to change the document now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GREAT WORK!
LGTM
Signed-off-by: myan myan@redhat.com
Provide more flexible parameter configurations when using the MQTT protocol to send events.