Curiosity

Troubleshooting Coding and Queries

This guide covers common issues and performance tips when working with custom code and queries in Curiosity Workspace.

Deadlocking

Deadlocks occur when two concurrent operations wait for each other to release a lock, causing both to freeze.

Common Causes

  1. Inconsistent Locking Order:
    • Thread A locks Node 1, then tries to lock Node 2.
    • Thread B locks Node 2, then tries to lock Node 1.
  2. Long-held Locks: Holding a lock while performing long network requests or heavy computation increases the window for conflicts.

Solutions

  • Consistent Ordering: If you need to lock multiple nodes, always sort them by their UID before acquiring locks.

    // CORRECT: Consistent order prevents deadlocks
    var uidsToLock = new[] { uidA, uidB }.OrderBy(u => u).ToList();
    // Lock in this order
    
    // WRONG: Locking in arbitrary order
    await Graph.GetOrAddLockedAsync(uidA);
    // ... some work ...
    await Graph.GetOrAddLockedAsync(uidB); // Risk of deadlock if another thread locked B then A
    
  • Lock Late, Commit Early: Acquire locks immediately before you need to modify data, and call CommitAsync as soon as the modification is done.

  • Avoid Expensive Operations Inside Locks: Do not perform network requests or heavy calculations while holding a lock.

    // WRONG
    var node = await Graph.GetOrAddLockedAsync(uid);
    var data = await CallSlowExternalApi(); // Slow! Blocks other threads needing 'node'
    node.UpdateProperty("data", data);
    await Graph.CommitAsync(node);
    
    // CORRECT
    var data = await CallSlowExternalApi(); // Do slow work first
    var node = await Graph.GetOrAddLockedAsync(uid); // Lock briefly
    node.UpdateProperty("data", data);
    await Graph.CommitAsync(node);
    

Uncommitted Nodes

One of the most common errors is forgetting to commit a locked node.

var node = await Graph.GetOrAddLockedAsync(uid);
node.UpdateProperty("status", "processing");

// ... exception thrown here ...

// Commit is never reached! Node remains locked forever (until restart).
await Graph.CommitAsync(node);

Fix: Use try/finally or ensure code paths are safe. If an endpoint finishes and a node is still locked, the system will eventually detect it, abandon the changes, and throw an exception to warn you, but this causes instability.

Performance Optimization

Curiosity's GraphDB is an in-memory graph database, but understanding its performance characteristics is crucial for writing efficient code.

Edge Traversal is Fast

Relationships are stored as direct memory pointers. Operations like Out(), IsRelatedTo(), and SortByConnectivity() are extremely fast because they traverse these pointers without deserializing data.

Property Access can be Slower

Reading a property value (e.g., node.GetString("name")) involves deserializing the node's content blob. While fast, doing this for millions of nodes in a loop is significantly slower than edge traversal.

Implication:

  • Avoid Where(n => n.GetString("status") == "Active") if possible. This forces the engine to load and deserialize every node to check the property.
  • Instead, use WhereString("status", "Active"). This uses internal indexes to filter UIDs before loading the content.

Indexing

  • Exact Match: Use StartWhereString or WhereString to leverage hash indexes for exact value lookups.
  • Full Text: Use StartSearch for fuzzy matching or relevance-based search. This uses the inverted index.

Large Result Sets

If a query returns thousands of nodes:

  • Don't use ToList() immediately if you don't need all data in memory.
  • Do use AsEnumerableAsync() to stream results.
  • Do use Take() and Skip() for pagination.

Common Exceptions

Exception Cause Fix
RequestedAlreadyLockedNodeException You tried to lock a node that is already locked by another thread (or your own thread in a different context). Use retry logic or review locking strategy.
DeadlockHadToBePreventedException The system detected a potential deadlock or unreleased lock. Check for missing CommitAsync calls.
NodeNotFoundException You tried to perform an operation on a UID that doesn't exist. Check if the node exists using Graph.HasNode(uid) before proceeding.

Referenced by

© 2026 Curiosity. All rights reserved.