Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Shelld Examples

This directory contains example scripts demonstrating how to use Shelld's async job execution API.

Prerequisites

  1. Start the Shelld daemon:

    cd ../src/build
    ./shelld /tmp/shelld.sock
  2. Create a test session:

    echo "CREATE mysession" | nc -U /tmp/shelld.sock

Scripts

1. stream_job.sh - Pseudo-Streaming Output

Demonstrates the pseudo-streaming pattern with real-time output updates.

Usage:

./stream_job.sh <session_name> <command> [poll_interval]

Example:

# Stream output from a build (poll every 2 seconds)
./stream_job.sh mysession "npm run build" 2

# Monitor a long-running task (poll every 5 seconds)
./stream_job.sh mysession "python train_model.py" 5

Features:

  • ✓ Real-time output updates
  • ✓ Progress indicator with elapsed time
  • ✓ Automatic cleanup when done
  • ✓ Colored status messages
  • ✓ Proper exit codes

2. parallel_jobs.sh - Parallel Job Monitoring

Run multiple commands in parallel and monitor them with a live dashboard.

Usage:

./parallel_jobs.sh <session_name> <command1> <command2> [command3...]

Example:

# Run test suites in parallel
./parallel_jobs.sh test \
    "npm run test:unit" \
    "npm run test:integration" \
    "npm run test:e2e"

# Parallel builds
./parallel_jobs.sh build \
    "gcc -o app1 app1.c" \
    "gcc -o app2 app2.c" \
    "gcc -o app3 app3.c"

Features:

  • ✓ Live dashboard showing all job statuses
  • ✓ Partial output preview (last 3 lines per job)
  • ✓ Summary with success/failure counts
  • ✓ Automatic cleanup
  • ✓ Fails if any job fails (useful for CI/CD)

Quick Manual Tests

Test 1: Basic Async Job

# Start a simple job
echo "EXEC_ASYNC mysession 'sleep 3 && echo Done'" | nc -U /tmp/shelld.sock
# Output: OK: Job 1

# Check status
echo "JOB_STATUS mysession 1" | nc -U /tmp/shelld.sock
# Output: RUNNING elapsed_ms=1234

# Wait for completion...
sleep 4

# Get output
echo "JOB_OUTPUT mysession 1" | nc -U /tmp/shelld.sock
# Output: Done

Test 2: Job Cancellation

# Start a long job
echo "EXEC_ASYNC mysession sleep 60" | nc -U /tmp/shelld.sock
# Output: OK: Job 1

# Cancel it
echo "JOB_CANCEL mysession 1" | nc -U /tmp/shelld.sock
# Output: OK: Job cancelled

# Verify
echo "JOB_STATUS mysession 1" | nc -U /tmp/shelld.sock
# Output: CANCELLED elapsed_ms=...

Test 3: Pseudo-Streaming

# Start a job with incremental output
echo "EXEC_ASYNC mysession 'for i in 1 2 3 4 5; do echo Line \$i; sleep 1; done'" | nc -U /tmp/shelld.sock
# Output: OK: Job 1

# Poll for partial output (run multiple times)
echo "JOB_OUTPUT mysession 1 partial" | nc -U /tmp/shelld.sock
# After 2s: Line 1
#           Line 2
# After 4s: Line 1
#           Line 2
#           Line 3
#           Line 4

Test 4: Job Listing

# Start multiple jobs
echo "EXEC_ASYNC mysession 'sleep 5'" | nc -U /tmp/shelld.sock
echo "EXEC_ASYNC mysession 'sleep 10'" | nc -U /tmp/shelld.sock
echo "EXEC_ASYNC mysession 'echo Hello'" | nc -U /tmp/shelld.sock

# List all jobs
echo "JOB_LIST mysession" | nc -U /tmp/shelld.sock
# Output:
# Jobs:
#   - Job 3 (COMPLETED): echo Hello
#   - Job 2 (RUNNING): sleep 10
#   - Job 1 (RUNNING): sleep 5

Environment Variables

All scripts support the following environment variable:

  • SHELLD_SOCKET: Path to the shelld Unix socket (default: /tmp/shelld.sock)

Example:

export SHELLD_SOCKET=/custom/path/shelld.sock
./stream_job.sh mysession "ls -la"

Exit Codes

Scripts return standard exit codes:

Code Meaning
0 Success (all jobs completed)
1 General error (job failed, session not found, etc.)
124 Timeout (job exceeded time limit)
130 Cancelled (job was cancelled by user)

Troubleshooting

Socket not found

Error: Socket /tmp/shelld.sock not found. Is shelld running?

Solution: Start the daemon first:

cd ../src/build && ./shelld /tmp/shelld.sock

Session not found

ERROR: Session not found

Solution: Create the session:

echo "CREATE mysession" | nc -U /tmp/shelld.sock

Job stuck in RUNNING

Cause: Command is waiting for input (interactive prompt)

Solution: Use non-interactive flags:

./stream_job.sh mysession "apt-get install -y package"  # -y flag

Advanced Usage

Custom Poll Interval

Adjust based on job duration:

# Quick jobs: poll frequently (1s)
./stream_job.sh build "make" 1

# Long jobs: poll less often (10s)
./stream_job.sh deploy "terraform apply" 10

Output to File

# Capture output to file
./stream_job.sh build "npm run build" 2 > build.log 2>&1

# Or redirect in the command itself
./stream_job.sh build "npm run build > /tmp/build.log 2>&1" 2

Integration with CI/CD

#!/bin/bash
# ci_pipeline.sh

set -e

# Create session
echo "CREATE ci_session" | nc -U /tmp/shelld.sock

# Run tests in parallel
./parallel_jobs.sh ci_session \
    "npm run test:unit" \
    "npm run test:integration" \
    "npm run lint"

# If tests pass, deploy
./stream_job.sh ci_session "npm run deploy" 5

echo "Pipeline completed successfully!"

More Examples

For detailed documentation and advanced patterns, see:


Contributing

Feel free to add your own example scripts! Useful patterns to demonstrate:

  • Job timeout handling
  • Error recovery and retry logic
  • Complex pipelines with dependencies
  • Integration with monitoring tools
  • Webhook notifications on completion