Skip to main content

Overview

MCReleaser supports two execution modes when publishing to multiple platforms: asynchronous (parallel) and synchronous (sequential). This is controlled by the sync property.

Configuration

Set the execution mode using the sync property:
# Asynchronous (default) - parallel uploads
java -Dsync=false -jar mcreleaser.jar

# Synchronous - sequential uploads
java -Dsync=true -jar mcreleaser.jar
Or via environment variable:
export SYNC=true
java -jar mcreleaser.jar

Asynchronous (Parallel) Mode

Default behavior (sync=false) In asynchronous mode, MCReleaser uploads to all configured platforms simultaneously using CompletableFuture.runAsync().

Advantages

  • Faster execution: All platforms are uploaded to concurrently
  • Efficient resource usage: Network requests happen in parallel
  • Ideal for most use cases: CI/CD pipelines, automated releases

When to Use

  • Publishing to multiple platforms (2+)
  • Time-sensitive releases
  • CI/CD automated deployments
  • Platforms are independent and don’t require specific ordering

Example

java -Dplatforms="github,modrinth,curseforge" \
     -Dsync=false \
     -jar mcreleaser.jar
With 3 platforms, uploads happen simultaneously, potentially completing in the time of the slowest single upload.

Synchronous (Sequential) Mode

Explicit configuration (sync=true) In synchronous mode, MCReleaser uploads to each platform one at a time, waiting for each to complete before starting the next.

Advantages

  • Predictable execution order: Platforms are processed in a defined sequence
  • Lower resource usage: Only one upload active at a time
  • Easier debugging: Clearer logs showing which platform failed
  • Rate limit friendly: Avoids overwhelming network or APIs

When to Use

  • Rate-limited networks: Corporate firewalls or restricted bandwidth
  • Debugging: Identifying which specific platform is causing issues
  • Resource-constrained environments: Limited CPU or memory
  • Platform dependencies: One platform must complete before another (rare)
  • Conservative deployments: Prefer stability over speed

Example

java -Dplatforms="github,modrinth,curseforge" \
     -Dsync=true \
     -jar mcreleaser.jar
Platforms are processed sequentially: GitHub → Modrinth → CurseForge.

Implementation Details

The sync property is read in CLIExecutor.java:19:
boolean runSync = CLIPropertyKey.SYNC.asBoolean(false);
In BundlePlatform.java:73-82, the execution mode is determined:
if (runSync) {
    // Sequential: add each platform to the task pool
    TaskPool pool = process.getCurrentTaskPool();
    runnableList.forEach(pool::addLast);
} else {
    // Parallel: run all platforms concurrently
    CompletableFuture<?>[] futures = runnableList.stream()
        .map(CompletableFuture::runAsync)
        .toArray(CompletableFuture[]::new);
    CompletableFuture.allOf(futures).thenRun(process::next);
}

Recommendations

ScenarioRecommended ModeReason
CI/CD automationAsync (default)Speed is critical
Local developmentAsync (default)Faster iteration
Debugging failuresSync (sync=true)Clearer error tracking
Network issuesSync (sync=true)Avoid overwhelming connection
Single platformEitherNo difference
3+ platformsAsync (default)Significant time savings

Performance Comparison

Assuming each platform takes ~10 seconds to upload:
PlatformsAsync ModeSync Mode
1 platform~10s~10s
3 platforms~10s~30s
5 platforms~10s~50s
Async mode completes in approximately the time of the slowest upload, while sync mode adds up the time for all uploads.

Error Handling

Both modes handle errors differently:
  • Async mode: If one platform fails, others continue. All results are collected at the end.
  • Sync mode: If one platform fails, subsequent platforms may not be processed (depends on error handling configuration).
For production releases where partial success is acceptable, use async mode. For critical releases where all platforms must succeed, consider sync mode with proper error checking.

Build docs developers (and LLMs) love