Stop the Race Condition: AtomicInteger class in Orchestrator

Two vRO workflows updating the same Configuration Element counter can hand out the same IP. AtomicInteger does the read, modify and write in one step, so every concurrent run gets a unique value. Includes a test package and LockingSystem comparison.

In this article

In a single-threaded world, 1 + 1 always equals 2. But in a high-concurrency environment like VCF Orchestrator (vRO), 1 + 1 can sometimes equal 1. This phenomenon is known as a Race Condition, and it’s the primary cause of duplication in scenarios like IP allocations and unique naming conventions, etc.

The Problem: The “Read-Modify-Write” Gap

Most vRO developers store shared data (like the next available IP index) in a Configuration Element. To increment it, the workflow does three things:

  1. Read: Pull the value from the database (e.g., 10).
  2. Modify: Calculate the next value (10 + 1 = 11).
  3. Write: Save 11 back to the database.

If two workflows run at the same time, Workflow B reads the value 10 before Workflow A has finished saving 11. Both workflows then try to assign the same IP address.

The Solution: AtomicInteger

The AtomicInteger class (available via AtomicSystem) provides a way to manage numbers that is “Atomic”—meaning the Read, Modify, and Write steps happen in a single, indivisible heartbeat at the CPU level.

How it works in vRO 8.x:

// Grab the shared counter from the vRO Server's RAM
var atomic = AtomicSystem.getAtomicInteger("production_ip_pool");

// This single line replaces the entire Read-Modify-Write cycle
var nextIPIndex = atomic.incrementAndGet();

System.log("Your unique, guaranteed IP index is: " + nextIPIndex);

Atomic vs. Normal: The “IP Allocation” Showdown

When we tested these two approaches side-by-side by launching 10 workflows simultaneously, the results were clear:

MetricNormal number (using Config Element)AtomicInteger
Logicread() -> +1 -> save()incrementAndGet()
SpeedSlow (Database Disk I/O)Ultra-Fast (Server RAM)
SafetyDangerous: Results in duplicatesSafe: No two threads get the same ID
OutcomeIP Conflict (10.0.0.5 assigned twice)Success (Every VM gets a unique IP)

Live Example

Grab the vRO package here to test it yourself and get used to the concept.

There are 2 workflows: Master and Worker

Master Workflow

  • Setup: It resets the AtomicInteger to the starting point.
  • Dispatch: It triggers multiple Worker workflows simultaneously (using the .execute() method).
  • Verify: It waits for everyone to finish and reports the final count.

Worker workflow

  • Isolation: Every worker runs in its own private memory space (“sandbox”). They can’t talk to each other directly.
  • Competition: Because they are all running at the exact same time, they “fight” to grab the next available IP index.
  • Atomicity: You will notice that mechanism that uses AtomicInteger makes sure every new IP is different but with a normal integer number, there is a race condition causing same IP to get assigned multiple times due to lack of atomicity in operations.

Key Advantages of AtomicInteger

1. Hardware-Level Locking (CAS)

AtomicInteger uses a “Compare and Swap” (CAS) mechanism. It doesn’t just blindly save a number; it checks if the value has changed since it last looked. If it has, it retries automatically. This is significantly faster than locking the entire database.

2. Cross-Workflow Visibility

Standard variables are trapped in the memory of a single workflow run. AtomicInteger lives in the vRO Service’s JVM memory, making it a “source of truth” that all concurrent runs can see and update instantly.

3. Zero Database Overhead

Configuration Elements require a database transaction every time you save an attribute. If you are deploying 100 VMs, that’s 100 database writes just for a counter. AtomicInteger happens in memory, reducing the load on your vRO database.

When Should You Use It?

  • IP Address Management (IPAM): Ensuring no two VMs get the same address.
  • Hostname Generation: Ensuring unique names (e.g., WEB-01, WEB-02).
  • Rate Limiting: Tracking how many API calls are currently in flight to an external system.
  • Sequential ID Generation: For ticketing systems or invoice numbers.

The Concurrency Hierarchy: AtomicInteger vs. LockingSystem vs. Number

Adding the LockingSystem to the mix completes the picture. While AtomicInteger is a specialized tool for numbers, the LockingSystem is the “heavy machinery” of vRO concurrency.

Think of it this way: AtomicInteger protects a variable, but LockingSystem protects a process.

Comparison

FeatureNormal IntegerAtomicIntegerLockingSystem
ScopeLocal to one WF run.Shared across all runs.Shared across all runs.
Best ForLoops/Internal math.Counters and IDs.Complex multi-step tasks.
MechanismNo protection.Hardware-level (CAS).Mutual Exclusion
PerformanceInstant.Ultra-Fast.Slower (Wait-time overhead).
Data TypeNumber only.Integer only.Anything (JSON, Arrays, APIs)

Discover more from Cloud Blogger

Subscribe to get the latest posts sent to your email.

Enjoyed this post?

Was this helpful?

Leave a Reply