Pujit Mehrotra 51f025b105 fix: improve API startup reliability with timeout budget tracking (#1824)
## Summary

- Add startup budget tracking to prevent silent hangs during API boot
- Add timeout wrappers around startup operations with graceful
degradation
- Add detailed logging for startup progress and failures

## Background

A user reported being unable to start their array on v7.2-beta.1 due to
the API failing to start. The root cause was a leftover
`dynamix.my.servers` folder from a previously uninstalled Connect
plugin. The API would hang during startup with no error messages, and
PM2 would eventually kill it after 15 seconds with no diagnostic
information.

**Original syslog:**
```
Aug 2 11:55:48 Vault root: Starting Unraid API service...
Aug 2 11:55:48 Vault root: Backup file not found at '/boot/config/plugins/dynamix.my.servers/node_modules-for-v4.12.0.tar.xz'. Skipping restore.
Aug 2 11:55:52 Vault root: Starting the Unraid API
[API never completes - PM2 times out waiting for 'ready' signal]
```

## Solution

### Startup Budget Tracking

Instead of fixed timeouts per operation (which could exceed PM2's
15-second limit in aggregate), we now track a total startup budget:

- **Total budget:** 13 seconds (2 seconds before PM2's 15-second kill
timeout)
- **Bootstrap reserve:** 8 seconds reserved for NestJS bootstrap
- **Per-operation max:** 2 seconds for pre-bootstrap operations

The `StartupBudget` class dynamically calculates timeouts based on
remaining time, ensuring we never exceed PM2's limit and always provide
clear timeout messages.

### Graceful Degradation

Non-critical operations now fail gracefully with warnings instead of
crashing:
- `loadStateFiles()` - continues with default state
- `loadRegistrationKey()` - continues without registration key  
- `loadDynamixConfig()` - continues with default config
- `StateManager` - continues without file watching
- `setupRegistrationKeyWatch()` - continues without key watching

Critical operations still fail fast:
- Config directory creation
- NestJS server bootstrap

### Improved Logging

Each startup phase now logs its completion, making it easy to identify
where hangs occur:
```
Config directory ready
Emhttp state loaded
Registration key loaded
Dynamix config loaded
State manager initialized
Registration key watch active
Bootstrapping NestJS server (budget: 11234ms)...
Startup complete in 1766ms
```

## Test plan

- [x] Verify API starts normally with all startup logs visible
- [x] Verify startup completes within PM2's 15-second timeout
- [ ] Test with missing/corrupted config files to verify graceful
degradation
- [ ] Verify timeout messages appear before PM2 kills the process

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 14:59:30 -05:00
2025-11-21 10:09:30 -05:00
2025-05-27 07:52:25 -04:00
2025-09-11 21:35:13 -04:00
2025-11-10 12:18:32 -05:00
2025-07-03 10:02:34 -04:00

Contributors Forks Stargazers Issues MIT License LinkedIn Codecov Apollo Studio

Ask DeepWiki


Logo

Unraid API

Monorepo for the Unraid API and Unraid Connect.
Explore the docs »

· Report Bug · Request Feature · Submit Work Intent

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgments

About The Project

Built With

Unraid Node.js Vite Nuxt PHP

(back to top)

Getting Started

This section will guide you through the steps necessary to get the monorepo projects running and communicating with each other.

Prerequisites

Make sure the following software is installed before proceeding.

  • Bash
  • Docker (for macOS folks, Orbstack works too)
  • Node.js (v22)
  • pnpm (v9.0+) - Install with npm install -g pnpm
  • Just (optional)
  • libvirt (macOS folks can run brew install libvirt)
  • rclone (v1.70+) - Important: Version 1.70 or higher is required
  • jq - JSON processor for scripts
  • An Unraid server for development

Ubuntu/WSL Users

For Ubuntu or WSL users, note that the default Ubuntu repositories may have older versions of rclone. You'll need rclone v1.70 or higher, which can be obtained from the rclone releases page.

Verify Prerequisites

After installation, verify your dependencies:

# Verify installations and versions
node --version  # Should be v22.x
pnpm --version  # Should be v9.0+
rclone version  # Should be v1.70+
jq --version    # Should be installed
docker --version  # Should be installed

Alternative: Using Nix Flake

If you have Nix installed, you can use the provided flake to automatically set up all development dependencies:

nix develop

This will provide all the required tools (Node.js, Docker, Just, libvirt, rclone, etc.) without needing to install them manually.

SSH Key Setup

Next, create an SSH key if you haven't already. Once you have your key pair, add your public SSH key to your Unraid server:

  1. Log in to your Unraid development server.
  2. Use the navigation menu to go to 'Users'.
  3. Click on the user you logged in with (e.g. root)
  4. Paste your SSH public key into 'SSH authorized keys' and click 'Save'.

Installation

  1. Clone and enter the repo

    git clone git@github.com:unraid/api.git
    cd api
    

    If using Nix, enter the development environment:

    nix develop
    
  2. Install dependencies and verify they're correctly installed:

    # Install all monorepo dependencies
    pnpm install
    
    # The install script will automatically check for required dependencies
    # and their versions (rclone v1.70+, jq, pnpm, etc.)
    
  3. Build the project:

    # Build individual packages first (from root directory)
    cd api && pnpm build && cd ..
    cd web && pnpm build && cd ..
    
    # Then build the plugin if needed
    cd plugin && pnpm build && cd ..
    

    Note: The packages must be built in order as the plugin depends on the API build artifacts.

Development Modes

The project supports two development modes:

Mode 1: Build Watcher with Local Plugin

This mode builds the plugin continuously and serves it locally for installation on your Unraid server:

# From the root directory (api/)
pnpm build:watch

This command will output a local plugin URL that you can install on your Unraid server by navigating to Plugins → Install Plugin. Be aware it will take a while to build the first time.

Mode 2: Development Servers

For active development with hot-reload:

# From the root directory - runs all dev servers concurrently
pnpm dev

Or run individual development servers:

# API server (GraphQL backend at http://localhost:3001)
cd api && pnpm dev

# Web interface (Nuxt frontend at http://localhost:3000) 
cd web && pnpm dev

Building the Full Plugin

To build the complete plugin package (.plg file):

# From the root directory (api/)
pnpm build:plugin

# The plugin will be created in plugin/dynamix.unraid.net.plg

To deploy the plugin to your Unraid server:

# Replace SERVER_IP with your Unraid server's IP address
pnpm unraid:deploy SERVER_IP

Tip

View other workflows (local dev, etc.) in the Developer Workflows

(back to top)

Usage

See How to Use the API.

For more examples, please refer to the Documentation

(back to top)

Contributing

For a complete guide on contributing to the project, including our code of conduct and development process, please see our Contributing Guide. Please read this before contributing.

Developer Documentation

For more information about development workflows, repository organization, and other technical details, please refer to the developer documentation inside this repository:

Work Intent Process

Before starting development work on this project, you must submit a Work Intent and have it approved by a core developer. This helps prevent duplicate work and ensures changes align with the project's goals.

  1. Create a Work Intent

  2. Wait for Approval

    • A core developer will review your Work Intent
    • They may ask questions or suggest changes
    • Once approved, the unapproved label will be removed
  3. Begin Development

    • Only start coding after your Work Intent is approved
    • Follow the approach outlined in your approved Work Intent
    • Reference the Work Intent in your future PR

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

Top contributors

contrib.rocks image

Community

🌐 Forums
💬 Discord

(back to top)

Contact

@UnraidOfficial - contact@unraid.net

Project Link: https://github.com/unraid/api

(back to top)

Description
Unraid API / Connect / UI Monorepo
Readme 131 MiB
Languages
TypeScript 78.2%
Vue 11.9%
PHP 5.1%
Shell 1.9%
JavaScript 1.3%
Other 1.5%