-
Notifications
You must be signed in to change notification settings - Fork 268
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
Discussion on subscriptions #240
Comments
Also referring to a post #239 (comment) from @jkissinger. Good article from Prosys about timeouts. https://www.prosysopc.com/blog/opc-ua-sessions-subscriptions-and-timeouts/ |
What are your thoughts on how closely the golang API should follow the OPC API as defined by the network protocol? My general approach is that I like having an opinionated, high level API that is designed from the perspective of the SDK user and follows the "zen" of the language. If the "opinion" is wrong, then I (as the user) can fall back to the lower level API that closely (or exactly) matches the network protocol. An example is Elasticsearch's Python SDK has a package of "helpers" that hide some implementation details. Another example is the AWS CLI. It has I don't know the network protocol well enough yet to know what to have a strong opinion on. |
I think that's a good general guideline. Close to the API the lower you get and more abstractions the higher you get. We already have functions in the client that map directly to the API calls with (hopefully) sane defaults. If that does not work you can just copy the function and send the request yourself. For one of our projects I've just written a If you can work with the existing api then add your code on top and make small tweaks where necessary. If you think the api or the implementation need a general refactor to make this work then I'd suggest two separate PRs. type Notif struct {
NodeID string
Value interface{}
}
func (m *M) Run(ctx context.Context) error {
mon := &NodeMonitor{
EndpointURL: "opc.tcp://localhost:4840",
NodeIDs: []string{
`ns=2;s="aaa"`,
`ns=2;s="bbb"`,
`ns=2;s="ccc"`,
},
Notifs: make(chan Notif, 1),
}
go mon.Run(ctx)
for {
select {
case <-ctx.Done():
return ctx.Err()
case n := <-mon.Notifs:
log.Printf("x: %#v", state)
}
}
} |
Do you think the |
There is |
Naming is going to be a challenge... |
Naming is always a challenge :) |
A separate |
Naming and cache-invalidation :) |
I've started moving a bit of the gist here: https://github.com/Intelecy/opcua/blob/node-monitor/monitor/monitor.go Very much a WIP, but I wanted to ensure a discussion on the interface/features. The callback-based use would look like: monitor, _ := NewMonitor(client)
sub, _ := monitor.Subscribe(
func(node *ua.NodeID, value *ua.DataValue) {
fmt.Printf("node=%s value=%s\n", node, value.Value.Value())
},
`ns=2;s="aaa"`,
`ns=2;s="bbb"`,
)
time.Sleep(time.Second * 5)
sub.Unsubscribe() And the chan-based use: monitor, _ := NewMonitor(client)
ch := make(chan *DataChangeMessage, 16)
sub, _ := monitor.ChanSubscribe(ch, `ns=2;s="aaa"`, `ns=2;s="bbb"`)
defer sub.Unsubscribe()
for {
select {
case msg := <-ch:
fmt.Printf("node=%s value=%s\n", msg.NodeID, msg.Value.Value())
case <-time.After(time.Second * 5):
return
}
} |
@magiconair I can confirm the same delayed disconnect on an unsubscribe/close |
addressed by #252 |
I am starting to work with subscriptions and would like to resurface @kung-foo 's suggestions in #207 (comment). I think they seem like a good improvement/addition to the current approach.
Also, I'm having trouble shutting down a client with a subscription properly. It looks like it always times out when the context gets cancelled which is not what I'd expect. But I need to dig a bit deeper. Are your subscription clients shutting down quickly?
The text was updated successfully, but these errors were encountered: