macchina-io / macchina.io

macchina.io EDGE is a powerful C++ and JavaScript SDK for edge devices, multi-service IoT gateways and connected embedded systems.
https://macchina.io
GNU General Public License v3.0
512 stars 152 forks source link

Issue with on valueChanged event handler #76

Closed FatKoala closed 6 years ago

FatKoala commented 6 years ago

Hello,

I have an issue with event handling when i try to attach multiple event handlers, one for every device i have created. After certain amount of callbacks one or multiple handlers just stop working and never get triggered again, despite working properly for about 500 calls. My code runs in playground on raspberry pi 3. Please find below piece of code that i use to create events.

function attachEvents()
{
    var deviceRefs = serviceRegistry.find('io.macchina.device != ""');
    var tempDevice;
    var eventTrigger;

    for(var i = 0; i < deviceRefs.length ; i++)
    {
        tempDevice = deviceRefs[i].instance();

        tempDevice.on('valueChanged', 
        function(event) {
                logger.information("Event !!! Data: " + event.data);
            }
        );
    }
}

Once again, everything works for some time and then some of the events are not triggered anymore despite their values still being changed. Hope someone can help. Thanks :)

obiltschnig commented 6 years ago

Your code becomes a victim of the V8 garbage collector. You are not keeping any references to your sensor objects (not the actual sensor objects, but their JavaScript proxies), so eventually the GC kicks in and removes them. The culprit is that you're assigning all sensor objects to tempDevice, so only the last one will survive. Store your sensor objects in an array to keep them around. Example:

var count = 0;
var sensors = [];
function attachEvents()
{
    var deviceRefs = serviceRegistry.find('io.macchina.device != ""');
    var tempDevice;
    var eventTrigger;

    for (var i = 0; i < deviceRefs.length ; i++)
    {
        tempDevice = deviceRefs[i].instance();
        sensors.push(tempDevice);
        tempDevice.on('valueChanged', 
            function(event) {
                logger.information("Event #%d: Data: %o", count++, event);
            }
        );
    }
}

attachEvents();
FatKoala commented 6 years ago

Thank you so much for the help. Everything works great now.