OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / opencog-kb / language-learning / chatbot / learner.sh

144 lines · bash ref:
#!/bin/bash
#
# learner.sh - Start, stop, and query the AtomSpace learning daemon
#
# Usage:
#   ./learner.sh start    Start the daemon
#   ./learner.sh stop     Stop the daemon
#   ./learner.sh status   Show if running + stats
#   ./learner.sh restart  Stop then start
#   ./learner.sh log      Tail the log
#   ./learner.sh test     Quick test (no daemon)
#

cd "$(dirname "$0")"

SOCK="/tmp/atomspace-learner.sock"
PID_FILE="/tmp/atomspace-learner.pid"
LOG="/tmp/atomspace-learner.log"

is_running() {
    [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null
}

do_start() {
    if is_running; then
        echo "Already running (PID: $(cat "$PID_FILE"))"
        echo "Use: ./learner.sh restart"
        exit 1
    fi

    # Clean stale socket/pid
    rm -f "$SOCK" "$PID_FILE"

    echo "Starting AtomSpace Learning Daemon..."

    GUILE_AUTO_COMPILE=0 nohup guile atomspace-daemon.scm run > "$LOG" 2>&1 &
    echo $! > "$PID_FILE"

    # Wait for socket (up to 30s for bootstrap + structure discovery)
    for i in $(seq 1 30); do
        if [ -S "$SOCK" ]; then
            echo "Started (PID: $(cat "$PID_FILE"))"
            echo ""
            ./ask.sh /layers
            echo ""
            echo "Query:  ./ask.sh /gaps"
            echo "        ./ask.sh /stats"
            echo "        ./ask.sh /layers"
            echo "Log:    ./learner.sh log"
            echo "Stop:   ./learner.sh stop"
            return 0
        fi
        sleep 1
    done

    echo "Failed to start within 30s."
    echo "Check log: tail $LOG"
    return 1
}

do_stop() {
    if ! is_running; then
        echo "Not running."
        rm -f "$SOCK" "$PID_FILE"
        return 0
    fi

    local pid
    pid=$(cat "$PID_FILE")
    echo "Stopping (PID: $pid)..."
    kill "$pid" 2>/dev/null

    # Wait for clean exit
    for i in $(seq 1 10); do
        if ! kill -0 "$pid" 2>/dev/null; then
            echo "Stopped."
            rm -f "$SOCK" "$PID_FILE"
            return 0
        fi
        sleep 1
    done

    # Force kill
    kill -9 "$pid" 2>/dev/null
    rm -f "$SOCK" "$PID_FILE"
    echo "Force stopped."
}

do_status() {
    if is_running; then
        echo "Running (PID: $(cat "$PID_FILE"))"
        echo ""
        if [ -S "$SOCK" ]; then
            ./ask.sh /stats
            echo ""
            ./ask.sh /layers
            echo ""
            ./ask.sh /cost
        else
            echo "Socket not ready yet (still bootstrapping?)"
        fi
    else
        echo "Not running."
    fi
}

case "${1:-}" in
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart)
        do_stop
        sleep 1
        do_start
        ;;
    status)
        do_status
        ;;
    log)
        if [ -f "$LOG" ]; then
            tail -f "$LOG"
        else
            echo "No log file yet. Start with: ./learner.sh start"
        fi
        ;;
    test)
        echo "Running quick test..."
        GUILE_AUTO_COMPILE=0 guile atomspace-daemon.scm test
        ;;
    *)
        echo "Usage: ./learner.sh {start|stop|restart|status|log|test}"
        echo ""
        echo "  start    Start the learning daemon"
        echo "  stop     Stop the daemon"
        echo "  restart  Stop then start"
        echo "  status   Show if running + stats + layers"
        echo "  log      Tail the daemon log"
        echo "  test     Quick test (bootstrap + one learning step)"
        ;;
esac