Table of Contents

Concurrency Viewer

The Concurrency Viewer is the React-shell view of the Concurrency Microservice. It shows operators which other users are currently editing or viewing the same record, surfaced as a small avatar pill in the top-right toolbar of an edit page.

Related docs.
Concurrency Microservice — the service that stores and serves the concurrency data.
System Overview — Concurrency MS — role, storage model (in-memory only), failure mode.

How it works at runtime

  1. On opening an edit page, the React shell starts a poll loop that pings the FrontEnd Server every MibCmsFrontEndServerBaseConfig.UserConcurrencyPollingTime (default 10s).
  2. The BFF forwards each poll to the Concurrency MS, sending the current user + page + record. The MS records the entry with a sliding TTL (default 4–5 minutes), then returns the list of other users currently on the same record.
  3. The shell renders the returned avatars in the toolbar pill.
  4. When the user navigates away, no explicit deregister happens — the user's entry just expires when the sliding TTL elapses.

This is a visibility feature, not a locking feature. Concurrent saves are still arbitrated by ETag-based optimistic concurrency in the Data API; the Concurrency MS just tells each operator who else is there.

Failure mode

If the Concurrency MS is unreachable, the React shell silently hides the pill. Operators can still edit; they just don't see who else is in the same record. There is no banner or error — the feature degrades silently.

Storage

The Concurrency MS holds all state in memory. On pod restart, all concurrency state is lost, then rebuilt over the next polling cycles (typically within 10 seconds). No persistent storage; no MongoDB; no SQL.

Setup

The Concurrency MS is required for this view to function. It is distributed as a Docker image from Amazon ECR. The available image tags:

873339144623.dkr.ecr.us-east-1.amazonaws.com/agile/mib-cms-microservices-concurrency
873339144623.dkr.ecr.us-east-1.amazonaws.com/agile/mib-cms-microservices-concurrency-bionic
873339144623.dkr.ecr.us-east-1.amazonaws.com/agile/mib-cms-microservices-concurrency-alpine

Sample docker-compose.yml:

version: '3'
services:
  mibconcurrency:
    image: 873339144623.dkr.ecr.us-east-1.amazonaws.com/agile/mib-cms-microservices-concurrency-alpine
    restart: unless-stopped
    ports:
      - 80:80
    environment:
      - mibauthorizationclientconfig_default_serverurl=http://cmsauth
      - mibcacheconfig_default_app=true
      - MibConcurrencyConfig_default_SlidingExpirationTime=00:05:00

Configurations

MibConcurrencyConfig (server side)

<?xml version="1.0" encoding="utf-8"?>
<mibConfig>
  <default>
    <slidingExpirationTime>00:04:00</slidingExpirationTime>
    <inMemoryExpirationScanFrequency>00:10:00</inMemoryExpirationScanFrequency>
    <userIdCacheExpirationTime>00:01:00</userIdCacheExpirationTime>
  </default>
</mibConfig>
Key Purpose
slidingExpirationTime How long an entry lives in memory after the last update. If the user stops polling (navigates away, closes the tab), this is how long their avatar still shows up to others.
inMemoryExpirationScanFrequency How often the in-memory store evicts expired entries. Tune downwards under high churn.
userIdCacheExpirationTime How long the service caches the user-id → user-info lookup it performs against the Authorization Server.

MibAuthorizationClientConfig

Required so the Concurrency MS can resolve user ids to user info (name, email, avatar) for the response:

<?xml version="1.0" encoding="utf-8"?>
<mibConfig>
  <default>
    <serverurl>https://auth-url</serverurl>
  </default>
</mibConfig>

MibCacheConfig

Required to enable in-process caching in the MS:

<?xml version="1.0" encoding="utf-8"?>
<mibConfig>
  <default>
    <app>true</app>
  </default>
</mibConfig>

Client-side wiring (on the BFF)

To wire the FrontEnd Server up to the MS, set on the BFF's MibCmsFrontEndServerBaseConfig:

<?xml version="1.0" encoding="utf-8" ?>
<mibConfig>
  <default>
    <userConcurrencyServiceUrl>http://concurrency.microservice.example.org</userConcurrencyServiceUrl>
    <userConcurrencyPollingTime>00:00:10</userConcurrencyPollingTime>
  </default>
</mibConfig>
Key Purpose
userConcurrencyServiceUrl The Concurrency MS URL the BFF talks to.
userConcurrencyPollingTime How often the React shell polls. Must be lower than slidingExpirationTime so entries don't expire under steady traffic.

If userConcurrencyServiceUrl is unset, the shell skips the pill entirely.

See also