You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@plc4x.apache.org by Christofer Dutz <ch...@c-ware.de> on 2020/10/30 15:42:25 UTC

[DISCUSS] Change the API for Subscriptions?

Hi all,

while doing the refactoring of the field handlers, and cleaning up in the SPI, I did come across the subscription API again.
I have to admit I’m not that happy with it.

Right now you have to build a subscription request, and with the response to that you can register a handler.
Every time I want to use the subscriptions, I have to dig again and find out how to use things.
That means for me the API in its current state isn’t very intuitive.

Right now in order to subscribe you would do this:

final PlcSubscriptionRequest.Builder builder = plcConnection.subscriptionRequestBuilder();    builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build();

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse = subscriptionRequest.execute().get();

// Attach handlers for the incoming data.
for (String subscriptionName : subscriptionResponse.getFieldNames()) {
    final PlcSubscriptionHandle subscriptionHandle =
        subscriptionResponse.getSubscriptionHandle(subscriptionName);
    subscriptionHandle.register(new ValueChangeHandler());
}

I would propose to change it that you provide the listener when creating the subscription request:

final PlcSubscriptionRequest.Builder builder = plcConnection.subscriptionRequestBuilder();    builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build(new ValueChangeHandler());

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse = subscriptionRequest.execute().get();

I know the main difference is that this way you would register the listener to all fields and with the other one you have the chance to attach multiple listners to different sets of fields. I would doubt that this use-case is very common. And you could probably just do the sorting in the handler.

Another option would be to have two “build” methods … one which takes a callback handler, and one that doesn’t … we could even just add the new build method and leave the rest unchanged. This would allow both approaches.

What do you think?

Chris


Re: [DISCUSS] Change the API for Subscriptions?

Posted by Otto Fowler <ot...@gmail.com>.
 What you posted, is a single handler for all the items in the
subscription, what I’m saying is have that, but ALSO allow a handler for
the fields.

- note the names in the implementation are _not_ what I’d do, but just to
make it clear.

```
final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”, new
SpecialValueChangedHandler());
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build(new
MultiValueChangeHandler());

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();



// implementation

if (field.hasHandler()) {
    field.getSpecialValueChangedHandler().handle();
} else {
    multiValueChangedHandler.handle();
}
```

On October 30, 2020 at 14:07:09, Christofer Dutz (christofer.dutz@c-ware.de)
wrote:

Hi Otto,

well it would be all, if you set it in the build method and single, if you
do it individually.
And I don't know if I would like a "default-handler" option ... just too
much that could go wrong here.
If someone sets up a catch-all handler intentionally and in a different
part of the application someone registers a field, then the events would
disappear from the other.

Could you just post a code snippet, the way I did it to show what you mean?

Chris



Am 30.10.20, 18:38 schrieb "Otto Fowler" <ot...@gmail.com>:

sorry

if field has handler -> handler() else parentHandler()

On October 30, 2020 at 13:37:51, Otto Fowler (ottobackwards@gmail.com)
wrote:

Why not optionally set a handler per field -or- for the whole thing?

if field has handlerer



On October 30, 2020 at 11:42:36, Christofer Dutz (christofer.dutz@c-ware.de)

wrote:

Hi all,

while doing the refactoring of the field handlers, and cleaning up in the
SPI, I did come across the subscription API again.
I have to admit I’m not that happy with it.

Right now you have to build a subscription request, and with the response
to that you can register a handler.
Every time I want to use the subscriptions, I have to dig again and find
out how to use things.
That means for me the API in its current state isn’t very intuitive.

Right now in order to subscribe you would do this:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build();

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

// Attach handlers for the incoming data.
for (String subscriptionName : subscriptionResponse.getFieldNames()) {
final PlcSubscriptionHandle subscriptionHandle =
subscriptionResponse.getSubscriptionHandle(subscriptionName);
subscriptionHandle.register(new ValueChangeHandler());
}

I would propose to change it that you provide the listener when creating
the subscription request:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build(new
ValueChangeHandler());

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

I know the main difference is that this way you would register the listener
to all fields and with the other one you have the chance to attach multiple
listners to different sets of fields. I would doubt that this use-case is
very common. And you could probably just do the sorting in the handler.

Another option would be to have two “build” methods … one which takes a
callback handler, and one that doesn’t … we could even just add the new
build method and leave the rest unchanged. This would allow both
approaches.

What do you think?

Chris

Re: [DISCUSS] Change the API for Subscriptions?

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi Otto,

well it would be all, if you set it in the build method and single, if you do it individually.
And I don't know if I would like a "default-handler" option ... just too much that could go wrong here.
If someone sets up a catch-all handler intentionally and in a different part of the application someone registers a field, then the events would disappear from the other.

Could you just post a code snippet, the way I did it to show what you mean?

Chris



Am 30.10.20, 18:38 schrieb "Otto Fowler" <ot...@gmail.com>:

     sorry

    if field has handler -> handler() else parentHandler()

    On October 30, 2020 at 13:37:51, Otto Fowler (ottobackwards@gmail.com)
    wrote:

    Why not optionally set a handler per field -or- for the whole thing?

    if field has handlerer



    On October 30, 2020 at 11:42:36, Christofer Dutz (christofer.dutz@c-ware.de)
    wrote:

    Hi all,

    while doing the refactoring of the field handlers, and cleaning up in the
    SPI, I did come across the subscription API again.
    I have to admit I’m not that happy with it.

    Right now you have to build a subscription request, and with the response
    to that you can register a handler.
    Every time I want to use the subscriptions, I have to dig again and find
    out how to use things.
    That means for me the API in its current state isn’t very intuitive.

    Right now in order to subscribe you would do this:

    final PlcSubscriptionRequest.Builder builder =
    plcConnection.subscriptionRequestBuilder();
    builder.addChangeOfStateField("value-1", “some-address”);
    builder.addChangeOfStateField("value-2", “some-address”);
    builder.addChangeOfStateField("value-3", “some-address”);
    PlcSubscriptionRequest subscriptionRequest = builder.build();

    // Execute the subscription response.
    final PlcSubscriptionResponse subscriptionResponse =
    subscriptionRequest.execute().get();

    // Attach handlers for the incoming data.
    for (String subscriptionName : subscriptionResponse.getFieldNames()) {
    final PlcSubscriptionHandle subscriptionHandle =
    subscriptionResponse.getSubscriptionHandle(subscriptionName);
    subscriptionHandle.register(new ValueChangeHandler());
    }

    I would propose to change it that you provide the listener when creating
    the subscription request:

    final PlcSubscriptionRequest.Builder builder =
    plcConnection.subscriptionRequestBuilder();
    builder.addChangeOfStateField("value-1", “some-address”);
    builder.addChangeOfStateField("value-2", “some-address”);
    builder.addChangeOfStateField("value-3", “some-address”);
    PlcSubscriptionRequest subscriptionRequest = builder.build(new
    ValueChangeHandler());

    // Execute the subscription response.
    final PlcSubscriptionResponse subscriptionResponse =
    subscriptionRequest.execute().get();

    I know the main difference is that this way you would register the listener
    to all fields and with the other one you have the chance to attach multiple
    listners to different sets of fields. I would doubt that this use-case is
    very common. And you could probably just do the sorting in the handler.

    Another option would be to have two “build” methods … one which takes a
    callback handler, and one that doesn’t … we could even just add the new
    build method and leave the rest unchanged. This would allow both
    approaches.

    What do you think?

    Chris


Re: [DISCUSS] Change the API for Subscriptions?

Posted by Otto Fowler <ot...@gmail.com>.
 sorry

if field has handler -> handler() else parentHandler()

On October 30, 2020 at 13:37:51, Otto Fowler (ottobackwards@gmail.com)
wrote:

Why not optionally set a handler per field -or- for the whole thing?

if field has handlerer



On October 30, 2020 at 11:42:36, Christofer Dutz (christofer.dutz@c-ware.de)
wrote:

Hi all,

while doing the refactoring of the field handlers, and cleaning up in the
SPI, I did come across the subscription API again.
I have to admit I’m not that happy with it.

Right now you have to build a subscription request, and with the response
to that you can register a handler.
Every time I want to use the subscriptions, I have to dig again and find
out how to use things.
That means for me the API in its current state isn’t very intuitive.

Right now in order to subscribe you would do this:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build();

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

// Attach handlers for the incoming data.
for (String subscriptionName : subscriptionResponse.getFieldNames()) {
final PlcSubscriptionHandle subscriptionHandle =
subscriptionResponse.getSubscriptionHandle(subscriptionName);
subscriptionHandle.register(new ValueChangeHandler());
}

I would propose to change it that you provide the listener when creating
the subscription request:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build(new
ValueChangeHandler());

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

I know the main difference is that this way you would register the listener
to all fields and with the other one you have the chance to attach multiple
listners to different sets of fields. I would doubt that this use-case is
very common. And you could probably just do the sorting in the handler.

Another option would be to have two “build” methods … one which takes a
callback handler, and one that doesn’t … we could even just add the new
build method and leave the rest unchanged. This would allow both
approaches.

What do you think?

Chris

Re: [DISCUSS] Change the API for Subscriptions?

Posted by Otto Fowler <ot...@gmail.com>.
 Why not optionally set a handler per field -or- for the whole thing?

if field has handlerer



On October 30, 2020 at 11:42:36, Christofer Dutz (christofer.dutz@c-ware.de)
wrote:

Hi all,

while doing the refactoring of the field handlers, and cleaning up in the
SPI, I did come across the subscription API again.
I have to admit I’m not that happy with it.

Right now you have to build a subscription request, and with the response
to that you can register a handler.
Every time I want to use the subscriptions, I have to dig again and find
out how to use things.
That means for me the API in its current state isn’t very intuitive.

Right now in order to subscribe you would do this:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build();

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

// Attach handlers for the incoming data.
for (String subscriptionName : subscriptionResponse.getFieldNames()) {
final PlcSubscriptionHandle subscriptionHandle =
subscriptionResponse.getSubscriptionHandle(subscriptionName);
subscriptionHandle.register(new ValueChangeHandler());
}

I would propose to change it that you provide the listener when creating
the subscription request:

final PlcSubscriptionRequest.Builder builder =
plcConnection.subscriptionRequestBuilder();
builder.addChangeOfStateField("value-1", “some-address”);
builder.addChangeOfStateField("value-2", “some-address”);
builder.addChangeOfStateField("value-3", “some-address”);
PlcSubscriptionRequest subscriptionRequest = builder.build(new
ValueChangeHandler());

// Execute the subscription response.
final PlcSubscriptionResponse subscriptionResponse =
subscriptionRequest.execute().get();

I know the main difference is that this way you would register the listener
to all fields and with the other one you have the chance to attach multiple
listners to different sets of fields. I would doubt that this use-case is
very common. And you could probably just do the sorting in the handler.

Another option would be to have two “build” methods … one which takes a
callback handler, and one that doesn’t … we could even just add the new
build method and leave the rest unchanged. This would allow both
approaches.

What do you think?

Chris