Skip to content
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

Client stops observing properties after a while #1263

Closed
pierre-josselin opened this issue Apr 4, 2024 · 8 comments
Closed

Client stops observing properties after a while #1263

pierre-josselin opened this issue Apr 4, 2024 · 8 comments

Comments

@pierre-josselin
Copy link

pierre-josselin commented Apr 4, 2024

Hi,

I have a TD "WindTurbine" with just one observable property "rotationSpeed":

{
    "@context": "https://www.w3.org/2019/wot/td/v1",
    "title": "wind-turbine",
    "base": "http://localhost:8630/wind-turbine",
    "securityDefinitions": {
        "nosec_sc": {
            "scheme": "nosec"
        }
    },
    "security": "nosec_sc",
    "properties": {
        "rotationSpeed": {
            "title": "Rotation speed",
            "type": "number",
            "minimum": 0,
            "maximum": 2,
            "observable": true
        }
    }
}

Here is a simplified version of the server implementing the property:

const servient = new nodeWotCore.Servient();
const httpServer = new nodeWotBindingHttp.HttpServer({ port: process.env.HTTP_SERVER_PORT });

servient.addServer(httpServer);

servient.start().then(async (WoT) => {
    const thingDescriptionRaw = fs.readFileSync("wind-turbine.td.json");
    const thingDescription = JSON.parse(thingDescriptionRaw);
    const exposingThing = await WoT.produce(thingDescription);

    exposingThing.setPropertyReadHandler("rotationSpeed", async () => {
        ...
    });

    exposingThing.setPropertyWriteHandler("rotationSpeed", async (rotationSpeedInteractionOutput) => {
        ...
    });

    const httpServer = http.createServer((request, response) => {
        const parsedUrl = url.parse(request.url, true);
        request.path = parsedUrl.pathname;
        request.query = parsedUrl.query;

        request.on("end", async () => {
            switch (request.path) {
                case "/notify/rotation-speed": {
                    exposingThing.emitPropertyChange("rotationSpeed");
                    break;
                }
            }
        });
    });

    httpServer.listen(process.env.HTTP_NOTIFICATION_SERVER_PORT);
    await exposingThing.expose();
});

And a simplified version of the client observing the property:

const WoTHelpers = new nodeWotCore.Helpers(servient);

WoTHelpers.fetch(windTurbine.woTServerUrl).then(async (td) => {
    const WoT = await servient.start();
    const thing = await WoT.consume(td);

    thing.observeProperty("rotationSpeed", async (rotationSpeedInteractionOutput) => {
        console.log("Rotation speed changed");
    });
});

Here is how it works:
An HTTP server is created. When it receives a notification, it emits a property change. The client is therefore informed of the modification of the property through the WoT server.

When starting the server, then the client, everything works.

But after a while, a few hours, the property systematically ceases to be observed, and will no longer work until the client restarts.

emitPropertyChange() keeps getting called but no longer the callback of observeProperty().

Am I doing something wrong or is this a bug? Thank you

Node.JS v16.13.2
Node WoT Core v0.8.12
Node WoT Binding HTTP v0.8.12

@relu91
Copy link
Member

relu91 commented Apr 5, 2024

Could be this a result of #1232 ? or your Windturbine emits property changes continuously?

@danielpeintner
Copy link
Member

Can put some logging in place to "see" what happens (or no longer happens)?

@pierre-josselin
Copy link
Author

Thank you for your replies

@relu91
Indeed the value of my property may not be modified for several hours.

@danielpeintner
I placed catches everywhere without being able to catch any error.
But I was able to log that emitPropertyChange() is reached, but no longer the callback of observeProperty().
If there is a way to log what is happening behind observeProperty() I would be happy test it.

@relu91
Copy link
Member

relu91 commented Apr 5, 2024

Indeed the value of my property may not be modified for several hours.

Then it's 99,9% the same bug described in #1232

If there is a way to log what is happening behind observeProperty() I would be happy test it.

Not sure if you already enabled it, but node-wot uses debug you can enable internal logging by defining DEBUG=node-wot:* env var.

@pierre-josselin
Copy link
Author

Thank you for the details. Is it possible to “unobserve” a property? That way I could restart the observation every one hour. Not very clean but that would solve the problem for the moment.

@relu91
Copy link
Member

relu91 commented Apr 8, 2024

node-wot is an implementation of the Scripting API Note. To unsubscribe you can use the stop method from the Subscription object returned from the observeProperty function.

@pierre-josselin
Copy link
Author

Thank you so much. I made the following code which fix the issue by restarting the property observation every 30 minutes.

let observedProperty;
async function callback() {
    if (observedProperty) {
        await observedProperty.stop();
    }

    observedProperty = await thing.observeProperty("rotationSpeed", async (rotationSpeedInteractionOutput) => {
        // Property changed
    });
}
setInterval(callback, 30 * 60 * 1000);
callback();

@danielpeintner
Copy link
Member

Thanks @pierre-josselin for posting your fix.
If you feel the issue has been resolved please close it.

The "root" cause is tracked in #1232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants