?? Oyeku: Process Control

Sleep, exit codes, timeouts, and process management.

Use Case 1: CI/CD Exit Codes

// ci_runner.ifa - Build script with proper exit codes

ayanmo EXIT_SUCCESS = 0;
ayanmo EXIT_BUILD_FAILED = 1;
ayanmo EXIT_TEST_FAILED = 2;
ayanmo EXIT_LINT_FAILED = 3;

ise run_build() {
    Irosu.fo("?? Building project...");
    Oyeku.sleep(500);  // Simulate build
    
    // Check for build errors
    ti (!Odi.exists("src/main.ifa")) {
        Irosu.kigbe("Build failed: main.ifa not found");
        padap? iro;
    }
    
    Irosu.fo("? Build successful");
    padap? otito;
}

ise run_tests() {
    Irosu.fo("?? Running tests...");
    Oyeku.sleep(300);
    
    ayanmo passed = 10;
    ayanmo failed = 0;
    
    Irosu.fo("? Tests passed: " + passed + "/" + (passed + failed));
    padap? failed == 0;
}

ise run_lint() {
    Irosu.fo("?? Linting code...");
    Oyeku.sleep(200);
    
    ayanmo warnings = 2;
    ayanmo errors = 0;
    
    ti (errors > 0) {
        Irosu.kigbe("? Lint errors: " + errors);
        padap? iro;
    }
    
    Irosu.fo("? Lint passed (" + warnings + " warnings)");
    padap? otito;
}

// Main CI pipeline
Irosu.fo("?? CI Pipeline Starting\n");

ti (!run_lint()) {
    Oyeku.exit(EXIT_LINT_FAILED);
}

ti (!run_build()) {
    Oyeku.exit(EXIT_BUILD_FAILED);
}

ti (!run_tests()) {
    Oyeku.exit(EXIT_TEST_FAILED);
}

Irosu.fo("\n? Pipeline completed successfully!");
Oyeku.exit(EXIT_SUCCESS);

Use Case 2: Polling with Timeout

// poll.ifa - Poll for condition with timeout

ise poll_until(check_fn, timeout_ms, interval_ms) {
    ayanmo start = Iwori.now_ms();
    ayanmo elapsed = 0;
    
    nigba (elapsed < timeout_ms) {
        ayanmo result = check_fn();
        ti (result) {
            padap? {"success": otito, "elapsed": elapsed};
        }
        
        Oyeku.sleep(interval_ms);
        ayanmo elapsed = Iwori.now_ms() - start;
    }
    
    padap? {"success": iro, "elapsed": elapsed, "error": "Timeout"};
}

// Example: Wait for file to appear
ise wait_for_file(path) {
    Irosu.fo("Waiting for " + path + "...");
    
    ayanmo result = poll_until(
        || Odi.exists(path),
        10000,  // 10 second timeout
        500     // Check every 500ms
    );
    
    ti (result["success"]) {
        Irosu.fo("? File appeared after " + result["elapsed"] + "ms");
        padap? otito;
    } bib?k? {
        Irosu.kigbe("? Timeout waiting for file");
        padap? iro;
    }
}

// Example: Wait for server to be ready
ise wait_for_server(url) {
    Irosu.fo("Waiting for server at " + url + "...");
    
    ayanmo check = || {
        ayanmo result = Okanran.try(|| Otura.get(url));
        padap? !Okanran.is_error(result) && result["status"] == 200;
    };
    
    ayanmo result = poll_until(check, 30000, 1000);
    
    ti (result["success"]) {
        Irosu.fo("? Server ready after " + result["elapsed"] + "ms");
    } bib?k? {
        Irosu.kigbe("? Server not responding");
    }
    
    padap? result["success"];
}

Use Case 3: Graceful Shutdown

// server.ifa - Server with graceful shutdown

ayanmo running = otito;
ayanmo active_connections = 0;

ise handle_connection(conn) {
    ayanmo active_connections = active_connections + 1;
    Irosu.fo("Connection opened. Active: " + active_connections);
    
    // Simulate request processing
    Oyeku.sleep(1000 + Owonrin.pese(0, 500));
    
    ayanmo active_connections = active_connections - 1;
    Irosu.fo("Connection closed. Active: " + active_connections);
}

ise graceful_shutdown(timeout_seconds) {
    Irosu.fo("\n?? Shutting down gracefully...");
    ayanmo running = iro;
    
    ayanmo waited = 0;
    nigba (active_connections > 0 && waited < timeout_seconds) {
        Irosu.fo("Waiting for " + active_connections + " connections...");
        Oyeku.sleep(1000);
        ayanmo waited = waited + 1;
    }
    
    ti (active_connections > 0) {
        Irosu.kigbe("Force closing " + active_connections + " connections");
    }
    
    Irosu.fo("? Shutdown complete");
    Oyeku.exit(0);
}

// Main server loop
Irosu.fo("??? Server starting on port 8080");

// Simulate receiving connections
ayanmo i = 0;
nigba (running && i < 5) {
    handle_connection(i);
    ayanmo i = i + 1;
}

graceful_shutdown(10);

Use Case 4: Rate Limiter

// rate_limit.ifa - Throttle operations

ayanmo request_times = [];
ayanmo MAX_REQUESTS = 10;   // Max 10 requests
ayanmo WINDOW_MS = 60000;   // Per minute

ise check_rate_limit() {
    ayanmo now = Iwori.now_ms();
    ayanmo window_start = now - WINDOW_MS;
    
    // Remove old requests
    ayanmo recent = [];
    fun t ninu request_times {
        ti (t > window_start) {
            ayanmo recent = Ogunda.push(recent, t);
        }
    }
    ayanmo request_times = recent;
    
    // Check limit
    ti (Ogunda.len(request_times) >= MAX_REQUESTS) {
        ayanmo oldest = Ogunda.first(request_times);
        ayanmo retry_after = Oturupon.div(oldest + WINDOW_MS - now, 1000);
        padap? {"allowed": iro, "retry_after": retry_after};
    }
    
    // Record this request
    ayanmo request_times = Ogunda.push(request_times, now);
    padap? {"allowed": otito, "remaining": MAX_REQUESTS - Ogunda.len(request_times)};
}

ise throttled_request(operation) {
    ayanmo limit = check_rate_limit();
    
    ti (!limit["allowed"]) {
        Irosu.fo("? Rate limited. Retry in " + limit["retry_after"] + "s");
        Oyeku.sleep(limit["retry_after"] * 1000);
        ayanmo limit = check_rate_limit();
    }
    
    Irosu.fo("? Request allowed (" + limit["remaining"] + " remaining)");
    padap? operation();
}

// Usage
ayanmo i = 0;
nigba (i < 15) {
    throttled_request(|| {
        Irosu.fo("  ? Processing request " + i);
    });
    Oyeku.sleep(100);
    ayanmo i = i + 1;
}