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:
- Read: Pull the value from the database (e.g.,
10). - Modify: Calculate the next value (
10 + 1 = 11). - Write: Save
11back 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:
| Metric | Normal number (using Config Element) | AtomicInteger |
| Logic | read() -> +1 -> save() | incrementAndGet() |
| Speed | Slow (Database Disk I/O) | Ultra-Fast (Server RAM) |
| Safety | Dangerous: Results in duplicates | Safe: No two threads get the same ID |
| Outcome | IP 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
AtomicIntegerto 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
AtomicIntegermakes 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
| Feature | Normal Integer | AtomicInteger | LockingSystem |
| Scope | Local to one WF run. | Shared across all runs. | Shared across all runs. |
| Best For | Loops/Internal math. | Counters and IDs. | Complex multi-step tasks. |
| Mechanism | No protection. | Hardware-level (CAS). | Mutual Exclusion |
| Performance | Instant. | Ultra-Fast. | Slower (Wait-time overhead). |
| Data Type | Number only. | Integer only. | Anything (JSON, Arrays, APIs) |
Discover more from Cloud Blogger
Subscribe to get the latest posts sent to your email.










