有两种方法可以检测文件更改(据我所知):
Polling,这意味着以一定的时间间隔检查文件夹中所有文件的时间戳。达到“近乎即时”的变化检测需要非常短的时间间隔。这是 CPU 和磁盘密集型的。
操作系统事件(Linux 上为 inotify,OS X 上为 FSEvents),其中的更改是可检测的,因为文件操作会通过操作系统子系统。这对 CPU 和磁盘来说很容易。
网络文件系统 (NFS) 等不会生成事件。由于文件更改不会通过来宾操作系统子系统,因此操作系统不知道更改;仅操作系统making更改(OS X)知道它们。
Grails 和许多其他文件观察器工具依赖于 FSEvents 或 inotify(或类似)事件。
那么该怎么办?考虑到可能产生的流量,在正常情况下将 NFS 更改从主机“广播”到所有来宾是不切实际的。然而,我认为 VirtualBox 股票应该算作一个特殊的例外......
弥补这一差距的机制可能涉及一个监视主机变化并触发客户机同步的进程。
查看这些文章,了解一些有趣的想法和解决方案,涉及某种类型的 rsync 操作:
http://drunomics.com/en/blog/syncd-sync-changes-vagrant-box http://drunomics.com/en/blog/syncd-sync-changes-vagrant-box(Linux)https://github.com/ggreer/fsevents-tools https://github.com/ggreer/fsevents-tools (OS X)
Rsync 到来宾 (Docker) 实例上的非 NFS 文件夹具有 I/O 性能显着提高的额外优势。 VirtualBox 的股票速度慢得令人痛苦。
Update!
这就是我所做的。首次安装lsyncd(OS X 示例,更多信息位于http://kesar.es/tag/lsyncd/ http://kesar.es/tag/lsyncd/):
brew install lsyncd
在 Mac 上的 Vagrant 文件夹中,我创建了该文件lsyncd.lua:
settings {
logfile = "./lsyncd.log",
statusFile = "./lsyncd.status",
nodaemon = true,
pidfile = "./lsyncd.pid",
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
delay = 2,
source = "./demo",
target = "vagrant@localhost:~/demo",
rsync = {
binary = "/usr/bin/rsync",
protect_args = false,
archive = true,
compress = false,
whole_file = false,
rsh = "/usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no"
},
}
其作用是同步文件夹demo
在我的 Vagrant 文件夹中到来宾操作系统中/home/vagrant/demo
。请注意,您需要使用 SSH 密钥设置登录,以使此过程顺利进行。
然后,随着 vagrant VM 的运行,我启动了 lsyncd 进程。这-log Exec
是可选的;它将其活动记录到标准输出:
sudo lsyncd lsyncd.lua -log Exec
在 vagrant VM 上,我在同步文件夹中启动了 Grails (2.4.4):
cd /home/vagrant/demo
grails -reloading run-app
回到 Mac 上的 IntelliJ,我编辑了一个 Controller 类。它几乎立即触发了 lsyncd(2 秒延迟),之后我很快就确认 Grails 重新编译了该类!
总结一下:
- 在 Mac 上编辑项目文件,在 VM 上执行
- 使用 lsyncd 将更改同步到虚拟机内的文件夹
- Grails 注意到更改并触发重新加载
- 不使用 VirtualBox 共享,磁盘性能更快
Issues:Textmate 触发 lsyncd(尚)无法识别的 FSEvent 类型,因此不会检测到更改。不过,Vim 和 IntelliJ 都很好。
希望这对某人有帮助!我花了一天时间才弄清楚这些东西。