hhxsv5 / laravel-s

LaravelS is an out-of-the-box adapter between Laravel/Lumen and Swoole.
MIT License
3.82k stars 471 forks source link

better alternative to inotify #96

Open prolic opened 5 years ago

prolic commented 5 years ago

Inotify doesn't work on mac and windows, but I found another alternative here: https://github.com/swooletw/watcher that I adjusted to laravel-s:

let fs = require('fs')
let chokidar = require('chokidar')
let colors = require('colors/safe')
let isRunning = require('is-running')

// Define our watching parameters
let basePath = process.cwd()
let pidPath = basePath + '/storage/laravels.pid'
let pid = fs.readFileSync(pidPath, 'utf8')
let ready = false

let logger = (color, message, level = 'log', skipSignal = false) => {
    console[level](colors[color](message))

    if (ready && !skipSignal) {
        sendSignal()
    }
}

let sendSignal = () => {
    if (!isRunning(pid)) {
        ready = false
        logger('red', `PID ${pid} is not alive. Close watcher process.`, 'error')
        process.exit()
    }

    process.kill(pid, 'SIGUSR1')
    logger('green', `Reloading process PID ${pid}...`, 'log', true)
}

if (!isRunning(pid)) {
    logger('red', `PID ${pid} is not alive.`, 'error')
    return
} else {
    logger('green', `PID ${pid} is alive, start watching process...`)
}

// Initialize watcher.
// Define your paths here.
let watcher = chokidar.watch([
    basePath + '/app',
    basePath + '/resources',
    basePath + '/routes'
], {
    ignored: /(^|[\/\\])\../,
    persistent: true
})

// Add event listeners.
watcher
    .on('add', path => logger('yellow', `File ${path} has been added.`))
    .on('change', path => logger('yellow', `File ${path} has been changed.`))
    .on('unlink', path => logger('yellow', `File ${path} has been removed.`))
    .on('addDir', path => logger('yellow', `Directory ${path} has been added.`))
    .on('unlinkDir', path => logger('yellow', `Directory ${path} has been removed.`))
    .on('error', error => logger('red', `Watcher error: ${error}`))
    .on('ready', () => {
        logger('green', 'Initial scan is finished. Ready for watching changes...')
        ready = true
    })

in docker-compose.yml I use this as start command: command: ./run.sh

and the run.sh file:

#!/bin/bash

# Start laravels
php artisan laravels start -d
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start laravels: $status"
  exit $status
fi

# Start watcher
node watcher.js
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start watcher: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds

while sleep 60; do
  ps aux |grep laravels |grep -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep watcher |grep -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of laravels and watcher has already exited."
    exit 1
  fi
done

I just leave it here for others to find.

hhxsv5 commented 5 years ago

Thank you, but for beginner developers, watcher.js depends on the NodeJs environment, which is a bit more complicated. In addition, fswatch is also available here, and it works on all platforms.

prolic commented 5 years ago

Thanks, can you tell me how to let laravels restart when fswatch detects a change? There is nothing is the docs.

hhxsv5 commented 5 years ago

See the shell fswatch

prolic commented 5 years ago

@hhxsv5 thanks, I'll check it out :)

prolic commented 5 years ago

You can close this issue if you like or leave it open for others to find, as you please

xinyi-1990 commented 5 years ago

239642717正在学习swoole,大家也可以进群学习下