Open Dnnd opened 4 years ago
Hello,
thanks for your bug report.
So far, I was able to fix the following issues:
ExposedThing::destroy
all previously created subscriptions are now disposed (https://github.com/sane-city/wot-servient/commit/6ff9eac7d044e9128d35079db586a8b6784388bb)ExposedThing::destroy
(https://github.com/sane-city/wot-servient/commit/1030f1688955ee294928ac7531488b33e644682e)But there is still no function to remove a thing from the servient. I am still undecided what is the best way to solve this.
I simply patched Servient
to remove thing from things
map in Servient::destroy
call:
return CompletableFuture.allOf(serverFutures).whenComplete((result, t) -> things.remove(id)).thenApply(result -> thing);
The single test was broken https://github.com/sane-city/wot-servient/blob/1030f1688955ee294928ac7531488b33e644682e/wot-servient/src/test/java/city/sane/wot/ServientTest.java#L127 due to immutability issues, but I didn't encounter any other problems. You suppose there would be any issues with this approach?
This approach would prevent a thing once destroyed from being exposed again. We could work around this by moving the Servient::addThing
call from DefaultWot::produce
to Servient::expose
.
Expected behavior
It's possible to interact with thing, which was exposed (
ExposedThing::expose
), destroyed (ExposedThing::destroy
) and exposed again with the same id.Observed behavior
It's impossible to use events, actions and properties of exposed
ExposedThing
if it's id is equal to the id of the previously destroyedThing
.Example
While the string "first invocation" was successfully transmitted to MQTT broker, the second string ("second invocation") wasn't. I believe, the cause is interaction between
Servient
'sthings
map https://github.com/sane-city/wot-servient/blob/24918ef49c3963304a4e8000b1f9fb9b52a15e97/wot-servient/src/main/java/city/sane/wot/Servient.java#L54 andMqttProtocolServer
.Servient::destroy
won't remove anyExposedThing
fromthings
map, soServient::addThing
method won't replaceExposedThing
instance if it's was created earlier: https://github.com/sane-city/wot-servient/blob/24918ef49c3963304a4e8000b1f9fb9b52a15e97/wot-servient/src/main/java/city/sane/wot/Servient.java#L208 It leads to the situation, whereExposedThing
instance which I created is different from one insideServient
andMqttProtocolServer
internal maps. AfterExposedThing::expose
invocation these instances won't share the samePublisherSubject
field inside states of exposed properties, so it's impossible to pass any data to property observer https://github.com/sane-city/wot-servient/blob/24918ef49c3963304a4e8000b1f9fb9b52a15e97/wot-servient-binding-mqtt/src/main/java/city/sane/wot/binding/mqtt/MqttProtocolServer.java#L130-L138 using instance ofExposedThing
returned fromWot::produce
method. One may suggest, that problem can be mitigated by using instance ofExposedThing
returned fromExposedThing::expose
method, but these will lead to another problem. Consider the following code:In this example, the string "second invocation" will be sent to MQTT broker twice. It will happen because
MqttProtocolServer
won't dispose subscriptions, created inMqttProtocolServer::exposeProperties
.