Skip to content

MCP/RPC server race conditions #925

@rsenden

Description

@rsenden

Current Behavior

Fcli was originally designed as a single-threaded CLI application, but with the recent additions of MCP server and upcoming JSON-RPC server capabilities, some code will need to be updated to avoid race conditions and global state persisting between separate in-process command invocations.

At the time of writing, the following potential hazards exist:

  • A thread-unsafe HashMap cache in ActionSpelFunctions
  • A static ObjectNode shared across all action runs in ActionRunnerVars
  • Unsynchronised concurrent parseArgs() on the shared root CommandLine
  • Unsynchronised concurrent writes into LogMaskHelper
  • The System.out/System.err snapshot-swap-restore race in OutputHelper/NonClosingOutHandler

Note that some other static/shared state exists in fcli, but currently this is only initialized when fcli starts up, not during individual requests through MCP/RPC calls:

  • FortifyCLIDynamicInitializer — only called once per process at startup (DefaultFortifyCLIRunner.run()), never by FcliCommandExecutor. envPrefix, DebugHelper.debugEnabled, LogMaskHelper.logMaskLevel are set once at startup.
  • FortifyCLIDefaultValueProvider.envPrefix — not registered on the execution CommandLine created by FcliCommandExecutor; only on the startup CommandLine.
  • StdIoMaskHelper.INSTANCEinstall()/uninstall() called only at process startup; methods are synchronized; no per-command hazard at the method level.
  • FoDRetryStrategy ThreadLocal — correctness neutral; instance-scoped anyway (may want to clean up ThreadLocal after use to avoid minor memory leak).

Expected Behavior

All code in fcli should be thread-safe and store per-execution state instead of global state where applicable.

Steps To Reproduce

No response

Environment

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions