Skip to content

Run concurrent writers

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

Keep the terminal open from Run sequential appends. After those lines print, the same script run continues automatically into the concurrent phase. Scroll your terminal to the output that follows the sequential summary line.

The concurrent phase is controlled by three constants at the top of atomic-session-append-demo.py:

atomic-session-append-demo.py
WRITERS = 64
WRITES_PER_WRITER = 1000
MAX_IN_FLIGHT = 4
sem = asyncio.Semaphore(MAX_IN_FLIGHT)

WRITERS and WRITES_PER_WRITER set how many async workers run and how many appends each one issues.

A semaphore limits how many tasks can hold a resource at the same time. The script uses asyncio.Semaphore(MAX_IN_FLIGHT) so at most four append_event calls run concurrently. Workers beyond that limit wait until a slot opens. That protects a single Aerospike Database Community Edition deployment in Docker from overload during the demo.

Review the concurrent phase output

  1. Find the concurrent section in your terminal output:

    After the five after append N lines and the after 5 sequential appends summary, the script launches one worker per writer ID:

    atomic-session-append-demo.py
    await asyncio.gather(*(writer(w) for w in range(WRITERS)))

    Each worker loops WRITES_PER_WRITER times and calls append_event on the same session. On a single Docker Community Edition node, the concurrent phase typically finishes in under a minute.

    after append 0: events=1, state={'app:tenant': 'acme', 'user:locale': 'en-US', 'turn': 0}
    after append 1: events=2, state={'app:tenant': 'acme', 'user:locale': 'en-US', 'turn': 1}
    after append 2: events=3, state={'app:tenant': 'acme', 'user:locale': 'en-US', 'turn': 2}
    after append 3: events=4, state={'app:tenant': 'acme', 'user:locale': 'en-US', 'turn': 3}
    after append 4: events=5, state={'app:tenant': 'acme', 'user:locale': 'en-US', 'turn': 4}
    after 5 sequential appends — cur_segment=0, session_state_keys=1
    64 writers × 1000 appends (max 4 in flight) in 12.4s — stored 64005 events (expected 64005)
    after concurrent appends — cur_segment=78, session_state_keys=1
    Connection closed.
  2. Read the summary line:

    From the output block in step 1, focus on:

    64 writers × 1000 appends (max 4 in flight) in 12.4s — stored 64005 events (expected 64005)
    • 64 writers × 1000 appends comes from WRITERS and WRITES_PER_WRITER.
    • max 4 in flight comes from MAX_IN_FLIGHT. Each worker acquires the semaphore before appending, so only four append_event calls run at once.
    • stored 64005 events (expected 64005) is the key invariant: five sequential appends plus 64,000 concurrent appends, with no duplicates or gaps. Your elapsed time can differ.
  3. Read the session record line:

    The next line in the same output block is:

    after concurrent appends — cur_segment=78, session_state_keys=1
    • cur_segment=78 is the active segment index after rollover. After five small sequential appends, cur_segment was 0. Under 64,000 concurrent appends, the service opened new segments as earlier ones filled and advanced the cur bin on the session row.
    • session_state_keys=1 stays at 1 because the concurrent phase omits state_delta by design (see Session and segment layout).
  4. Confirm the concurrent phase:

    Matching stored and expected counts confirms idempotent, gap-free writes under concurrency. cur_segment rises as segments roll over.

    The script then deletes the session and prints Connection closed.. Elapsed time and segment count can vary by hardware.

When a segment fills, the service opens the next segment automatically. The demo script does not estimate record size or manage rollover.

Explore the demo source in the adk-aerospike repository for the full step-by-step code walkthrough.

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?