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

rerendering results in websocket consumption #312

Open
wvullhorst opened this issue Dec 3, 2022 · 9 comments
Open

rerendering results in websocket consumption #312

wvullhorst opened this issue Dec 3, 2022 · 9 comments

Comments

@wvullhorst
Copy link

wvullhorst commented Dec 3, 2022

I started a small project with neovis.js today. Everything works fine at first look but now I observe a problem:
Rendering my graph the first and second time works fine. After that every new rendering doubles the websocket connections in "pending" state. When the number reaches 32, exceptions are printed to the console.
Depending on my strategy to update the graph (when selecting a node) the websocket consumption differs.

I use the movie database example for my tests. The render method looks like this:

function render(config) {
    viz = new NeoVis.default(config);
    viz.renderWithCypher(cypherQuery());
    viz.registerOnEvent("completed", (e) => {
        viz.network.on("click", (e) => {
            if(e.nodes[0]) {
                currentId = e.nodes[0];
                viz.reload();
            }
        });
    });
}

Screenshots of my tests:

Initial state after page load

Initial state after page load

Node selected and refresh done
Node selected and refresh done 1

Same node selected again and refresh done
Same node selected again and refresh done

Here comes the full source code:

<!doctype html>
<html>
<head>
    <title>Neo4J Graph Explorer</title>
    <style type="text/css">
        html, body {
            font: 16pt arial;
        }

        #viz {
            width: 900px;
            height: 700px;
            border: 1px solid lightgray;
            font: 10pt arial;
        }
    </style>
    <script src="https://rawgit.com/neo4j-contrib/neovis.js/master/dist/neovis.js"></script>
    <script type="text/javascript">
        const relations = "<-[r:ACTED_IN*1..3]->";
        const CFG = {
            server: {
                url: "bolt://syn1:7687",
                user: "neo4j",
                password: "************",
            },
            query: {
                initial: "MATCH (m:Movie { title: \"The Matrix Reloaded\" })" + relations + "(a) RETURN *",
                byId: (id) => "MATCH (a) " + relations + "(b) WHERE ID(a)=" + id + " RETURN *"
            },
            render: {
                node: {
                    active: { color: '#d00', size: 15 },
                    inactive: { color: '#55a', size: 10 },
                    fontSize: 14
                },
                link: {
                    color: '#888'
                }
            }
        }
        let viz;
        let currentId;
        function draw() {
            const config = {
                containerId: "viz",
                neo4j: {
                    serverUrl: CFG.server.url,
                    serverUser: CFG.server.user,
                    serverPassword: CFG.server.password,
                },
                visConfig: {
                    nodes: {
                        shape: 'dot',
                        size: CFG.render.node.inactive.size,
                        font: { size: CFG.render.node.fontSize },
                        color: CFG.render.node.inactive.color
                    },
                    edges: {
                        arrows: {
                            to: {enabled: true},
                        },
                        color: CFG.render.link.color,
                    },
                    physics: {
                        solver: 'forceAtlas2Based'
                    }
                },
                labels: {
                    Movie: {
                        label: "title",
                        [NeoVis.NEOVIS_ADVANCED_CONFIG]: {
                            function: { color: nodeColor, size: nodeSize, physics: nodePhysics }
                        },
                    },
                    Person: {
                        label: "name",
                        [NeoVis.NEOVIS_ADVANCED_CONFIG]: {
                            function: { color: nodeColor, size: nodeSize, physics: nodePhysics }
                        },
                    }
                },
            };
            render(config);
        }
        function nodeColor(node) {
            if(node.identity === currentId) return CFG.render.node.active.color;
            return CFG.render.node.inactive.color;
        }
        function nodeSize(node) {
            if(node.identity === currentId) return CFG.render.node.active.size;
            return CFG.render.node.inactive.size;
        }
        function nodePhysics(node) {
            if(node.identity === currentId) return false;
            return true;
        }
        function cypherQuery() {
            if(currentId) return CFG.query.byId(currentId);
            return CFG.query.initial;
        }
        function render(config) {
            viz = new NeoVis.default(config);
            viz.renderWithCypher(cypherQuery());
            viz.registerOnEvent("completed", (e) => {
                viz.network.on("click", (e) => {
                    if(e.nodes[0]) {
                        currentId = e.nodes[0];
                        viz.reload();
                    }
                });
            });
        }
    </script>
</head>
<body onload="draw()">
    <div id="viz"></div>
</body>
</html>

additional info (latest results)

Changing the event handler (see below) improves the behavior. Before, the number of websocket connection doubles at each node click, after the number only increases by 1 at each node click...

        function render(config) {
            viz = new NeoVis.default(config);
            viz.renderWithCypher(cypherQuery());
            viz.registerOnEvent("completed", (e) => {
                viz.network.on("click", (e) => {
                    if(e.nodes[0]) {
                        currentId = e.nodes[0];
                        render(config);
                    }
                });
            });
        }
@thebestnom
Copy link
Collaborator

That's wierd... There shouldn't be a new neo4j session, Im pretty sure chrome network panel has which line of code generated the websocket, I checked the code and I did close the session on render complete, which makes it really weird as you didn't use any cypher config...

@thebestnom
Copy link
Collaborator

Also checked I did close session when used, that's why the websocket still open?

@wvullhorst
Copy link
Author

wvullhorst commented Dec 4, 2022

First connection:

  | n | @ | browser-channel.js:45
-- | -- | -- | --
  | (anonymous) | @ | browser-channel.js:215
  | t | @ | browser-channel.js:56
  | o | @ | connection-channel.js:93
  | e.createChannelConnection | @ | connection-channel.js:95
  | C._createChannelConnection | @ | connection-provider-pooled.js:109
  | e._createConnection | @ | connection-provider-pooled.js:133
  | (anonymous) | @ | pool.js:261
  | (anonymous) | @ | pool.js:51
  | (anonymous) | @ | pool.js:32
  | (anonymous) | @ | pool.js:26
  | r | @ | pool.js:22
  | t._acquire | @ | pool.js:208
  | t.acquire | @ | pool.js:106
  | e.acquireConnection | @ | connection-provider-direct.js:102
  | t.initializeConnection | @ | connection-holder.js:87
  | t._run | @ | session.js:161
  | t.run | @ | session.js:139
  | render | @ | neovis.ts:371
  | renderWithCypher | @ | neovis.ts:528
  | render | @ | vis.html:103
  | draw | @ | vis.html:83
  | onload | @ | vis.html:115

Subsequent connections using viz.reload():

  | n | @ | browser-channel.js:45
-- | -- | -- | --
  | (anonymous) | @ | browser-channel.js:215
  | t | @ | browser-channel.js:56
  | o | @ | connection-channel.js:93
  | e.createChannelConnection | @ | connection-channel.js:95
  | C._createChannelConnection | @ | connection-provider-pooled.js:109
  | e._createConnection | @ | connection-provider-pooled.js:133
  | (anonymous) | @ | pool.js:261
  | (anonymous) | @ | pool.js:51
  | (anonymous) | @ | pool.js:32
  | (anonymous) | @ | pool.js:26
  | r | @ | pool.js:22
  | t._acquire | @ | pool.js:208
  | t.acquire | @ | pool.js:106
  | e.acquireConnection | @ | connection-provider-direct.js:102
  | t.initializeConnection | @ | connection-holder.js:87
  | t._run | @ | session.js:161
  | t.run | @ | session.js:139
  | render | @ | neovis.ts:371
  | reload | @ | neovis.ts:509
  | (anonymous) | @ | vis.html:112
  | e.emit | @ | vis-network.js:1502
  | value | @ | vis-network.js:36352
  | value | @ | vis-network.js:35061
  | (anonymous) | @ | vis-network.js:33439
  | e.emit | @ | vis-network.js:7332
  | n.emit | @ | vis-network.js:6480
  | e.tryEmit | @ | vis-network.js:6266
  | e.recognize | @ | vis-network.js:6319
  | e.recognize | @ | vis-network.js:7169
  | fd | @ | vis-network.js:5362
  | e.handler | @ | vis-network.js:5585
  | domHandler | @ | vis-network.js:5437

Subsequent connections reinitializing viz (see additional info in original post)

  | n | @ | browser-channel.js:45
-- | -- | -- | --
  | (anonymous) | @ | browser-channel.js:215
  | t | @ | browser-channel.js:56
  | o | @ | connection-channel.js:93
  | e.createChannelConnection | @ | connection-channel.js:95
  | C._createChannelConnection | @ | connection-provider-pooled.js:109
  | e._createConnection | @ | connection-provider-pooled.js:133
  | (anonymous) | @ | pool.js:261
  | (anonymous) | @ | pool.js:51
  | (anonymous) | @ | pool.js:32
  | (anonymous) | @ | pool.js:26
  | r | @ | pool.js:22
  | t._acquire | @ | pool.js:208
  | t.acquire | @ | pool.js:106
  | e.acquireConnection | @ | connection-provider-direct.js:102
  | t.initializeConnection | @ | connection-holder.js:87
  | t._run | @ | session.js:161
  | t.run | @ | session.js:139
  | render | @ | neovis.ts:371
  | renderWithCypher | @ | neovis.ts:528
  | render | @ | vis.html:103
  | (anonymous) | @ | vis.html:108
  | e.emit | @ | vis-network.js:1502
  | value | @ | vis-network.js:36352
  | value | @ | vis-network.js:35061
  | (anonymous) | @ | vis-network.js:33439
  | e.emit | @ | vis-network.js:7332
  | n.emit | @ | vis-network.js:6480
  | e.tryEmit | @ | vis-network.js:6266
  | e.recognize | @ | vis-network.js:6319
  | e.recognize | @ | vis-network.js:7169
  | fd | @ | vis-network.js:5362
  | e.handler | @ | vis-network.js:5585
  | domHandler | @ | vis-network.js:5437

@thebestnom
Copy link
Collaborator

This is really wierd, it looks like driver bug as I do close this session onComplete, Ill test that out later this week

@thebestnom
Copy link
Collaborator

Also for just changing color I would not suggest reloading the entire network, you can get the id from viz.nodes.get and change the data there

@wvullhorst
Copy link
Author

Also for just changing color I would not suggest reloading the entire network, you can get the id from viz.nodes.get and change the data there

When you select a node, a new cypher query is executed with the selected node being the "the root of the query" (see viz.renderWithCypher(cypherQuery()))

@thebestnom
Copy link
Collaborator

In the second one, yes, in the original you only called reload 😅 anyway Ill test why the session doesn't close even though I call close probably tomorrow

@mdopp
Copy link

mdopp commented Sep 18, 2023

this one is almost a year old...but maybe this helps, as it seams to fit into the same area (possible the same root cause)

With every reload() an extra "clickNode" event is created. What I mean: First time you create viz, everything is fine. I registerOnEvent for "clickNode", user clicks, and the function is called.
If you now do a reload, the clickNode is fired twice. Another reload: three times clickNode. (just print it to the console and have a look).

That said: Something like this could cause internnaly to create multiple requests to the server, hence the websocket is spammed.

Just as an idea.

@thebestnom
Copy link
Collaborator

@mdopp that's a bug 😅 but it shouldn't affect the websocket as the event doesn't add any session to the neo4j

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