question-mark

Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cruddl compatibility with multi-node ArangoDB clusters

See original GitHub issue

Issue Description

Hi, is Cruddl expected to generate AQL that is compatible with anonymous graph traversals on multi-node clusters? It seems as if the generated AQL is missing the necessary WITH <collections> stanza, resulting in error messages like the following:

Query: AQL: Error message received from cluster node 'PRMR-tn50ynem': collection not known to traversal: 'organizations'. please add 'WITH organizations' as the first line in your AQL (while executing)

Issue Analytics

  • State:closed
  • Created 4 months ago
  • Reactions:2
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
anderson900commented, Sep 26, 2022

I wanted to follow-up on this. I don’t see any contributor guides in the repo’s READMEs so it isn’t clear if you’d appreciate/accept a PR around this issue, but here is my MVP solution to this problem. I tested it by setting --query.require-with true when launching the ArangoDB database for the test suite (docker run --rm -e ARANGO_NO_AUTH=true -p 8529:8529 arangodb/arangodb:3.9.3 --query.require-with true).

Here is my modification to getAQLQuery that adds a WITH <collections> statement for any collection implicitly required by a traversal but not otherwise included in the query. Likely this isn’t the most elegant solution or the right way to solve the problem in the long run, but this is what I was able to come up wit on short notice and not much familiarity with the Cruddl internals. Suggestions for a different approach are welcome, or if you’d like me to open a PR, let me know.

export function getAQLQuery(node: QueryNode): AQLCompoundQuery {
    const context = new QueryContext();

    const compoundQuery = createAQLCompoundQuery(
        node,
        aql.queryResultVariable('result'),
        undefined,
        context,
    );

    const traversalCollections = new Set<string>();

    visitQueryNode(node, {
        leave(object, key: string | undefined) {
            if (object instanceof TraversalQueryNode) {
                (object.relationSegments || []).forEach(seg => {
                    [seg.relationSide.sourceType, seg.relationSide.targetType].forEach(type => {
                        traversalCollections.add(getCollectionForType(type, AccessType.READ, context).toString());
                    })
                })
            } else if (object instanceof FollowEdgeQueryNode) {
                [object.relationSide.sourceType, object.relationSide.targetType].forEach(type => {
                    traversalCollections.add(getCollectionForType(type, AccessType.READ, context).toString());
                });
            } else if (object instanceof RemoveEdgesQueryNode) {
                [object.relation.fromSide.sourceType, object.relation.fromSide.targetType].forEach(type => {
                    traversalCollections.add(getCollectionForType(type, AccessType.READ, context).toString());
                });
            }

            return object;
        }
    });

    if (traversalCollections.size > 0) {
        const addTraversalContext = (originalQuery: AQLCompoundQuery): AQLCompoundQuery => {
            const referencedCollections = new Set([...compoundQuery.readAccessedCollections, ...compoundQuery.writeAccessedCollections]);
            const unknownCollections = [...traversalCollections].filter(c => !referencedCollections.has(c));

            const traversalContext = (unknownCollections.length > 0) ? aql.code(`WITH ${[...unknownCollections].join(", ")}\n`) : aql.code('');

            return new AQLCompoundQuery(
                originalQuery.preExecQueries.map(peq => addTraversalContext(peq)),
                new AQLCompoundFragment([traversalContext, originalQuery.aqlQuery]),
                originalQuery.resultVar,
                originalQuery.resultValidator,
                originalQuery.readAccessedCollections,
                originalQuery.writeAccessedCollections,
            );
        };

        return addTraversalContext(compoundQuery);
    }

    return compoundQuery;
}
1reaction
anderson900commented, Oct 14, 2022

This continues to look good for us in our environments with clustered ArangoDB deployments. Thanks for the quick turn-around!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cluster: Distributed multi-model database - ArangoDB
ArangoDB clusters consist of a number of ArangoDB instances that talk to each other over the network. These instances play different roles in...
Read more >
Cluster | Deployment | Manual | ArangoDB Documentation
In an ArangoDB Cluster, the replication among the data stored by the DB-Servers is synchronous. Synchronous replication works on a per-shard basis. Using...
Read more >
High Availability Deployment Modes of ArangoDB
ArangoDB OneShard deployments are multi-node clusters with synchronous replication from leader to followers: high availability, high performance, ...
Read more >
Replication | Architecture | Manual | ArangoDB Documentation
Synchronous replication only works within an ArangoDB Cluster and is typically used for mission critical data which must be accessible at all times....
Read more >
Cluster | Deployment | Manual | ArangoDB Documentation
This chapter describes how to deploy an ArangoDB Cluster. ... This section applies to SystemV-compatible init systems (e.g. sysvinit, OpenRC, upstart).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found