Question
· Oct 11

How can I use $Order() traversal with lock-free concurrency for real-time analytics in IRIS?

We want to iterate over large global structures in real-time without blocking or locking readers. How can we safely use $Order() and implement a lock-free analytics approach?

Discussion (2)2
Log in or sign up to continue

Implementing a lock-free, concurrency-safe traversal over large global structures for real-time analytics in InterSystems IRIS can be optimized by carefully utilizing functions like $Order() or $Query(). Here are steps and considerations for such an approach:

  1. Lock-Free Traversal with $Order():

    • $Order() allows you to navigate node-by-node through the global structure, returning the next (or previous) subscript at a specified level. It works without mandatory locking, which is suitable for concurrent environments. Use $Order() to iterate through your data efficiently:
      objectscript
      SET key = $Order(^YourGlobal(""))
      WHILE key'="" {
      // Process the node
      SET key = $Order(^YourGlobal(key))
      }

      You can choose forward (1, default) or backward (-1) traversals with the direction argument [1][2].
  2. Optimized Data Fetching:

    • Utilize the third argument of $Order() to also retrieve the value of the node simultaneously, minimizing the overhead of multiple global accesses:
      objectscript
      SET key = ""
      WHILE (key='') {
      SET key=$Order(^YourGlobal("",1,Value))
      WRITE key,": ",Value,!
      }
  3. Avoid Gaps with $Query():

    • Use $Query() for traversing globals in sequential order while skipping undefined nodes. This can be more efficient in cases with sparse data:
      objectscript
      SET node = $Query(^YourGlobal(""))
      WHILE (node'="") {
      // Process the node
      WRITE @node,!
      SET node = $Query(@node)
      }

      $Query() provides the next global node's full reference and implicitly omits undefined nodes [3].
  4. Concurrency Considerations:

    • While both $Order() and $Query() are safe for use in lock-free access patterns, concurrent modifications to nodes may cause iteration to omit or include unintended elements. Real-time loads should therefore focus on ensuring no destructive updates are performed by other processes during traversal.
  5. Real-Time Applications:

    • With a focus on read-heavy real-time analytics, these methods avoid the overhead of locks and ensure the global structure remains responsive. Using $Order() and $Query() lets you scale analytics with concurrent readers effectively.

These methodologies allow implementing fast and non-blocking access to data stored in globals for real-time operations [1][2][3].

Sources:

Hi Jack,

IRIS locking works optimistically; the lock does not do anything in and of itself. It is the responsibility of other processes to attempt to take out a lock and/or verify if an existing lock has already been taken out. Shared locking would generally be used so that multiple processes can read a value at the same time while the values are not being modified. It may take consideration of the table architecture and an understanding of the general access patterns and what types of queries you are running to efficiently only lock what is necessary and not block modifications on a large scale.

It does feel like this is a small question that fits into a bigger project so there might be more to consider. I would recommend reaching out to your ISC contact / sales engineer to discuss this in larger scope.