andyvanee / synchroversion
基于文件的版本控制缓存系统
README
Synchroversion的设计考虑以下特性
- 保留变更历史(diffs)的全历史
- 写入不会阻塞或干扰读取
- 读取不会阻塞或干扰写入
- 变更带有时戳
一般来说,它基于以下假设构建:你的数据是
- 基于文本的
- 每次调用时不会剧烈变化(因此diffs不是很大)
- 面向行的(如果你想看到可读的diffs)
- 单生产者,多消费者
- 获取速度比获取频率快。我预计如果您的获取需要5分钟但您每2分钟运行一次,它可能会爆炸。
一些可能的用例可能包括
- 存储和版本控制大型API调用
- 记录目录树中做出的更改
- 添加数据库版本控制(使用数据库转储)
它是通过在state
目录中存储内容的变更日志(以diff格式),并在latest
目录中存储文件的最新几个完整版本来实现的。生产者和消费者永远不会同时访问相同的文件。
我的初始原型是用bash编写的,但这个版本是PHP,因为我目前正在使用的语言。由于格式完全是基于文本文件的,所以它对语言无关,应该很容易在其他语言中实现。
使用方法
使用composer安装
composer require andyvanee/synchroversion
new Synchroversion\Synchroversion($root, $path)
创建一个新实例,准备读取或写入。第一个参数是所有文件存储的根目录,第二个参数是你想要在该根目录中使用的路径。在这个例子中,我们将跟踪syslog,所以我们将其命名为syslog
。
$sync = new Synchroversion\Synchroversion(dirname(__FILE__), 'syslog');
setUmask($umask)
这可以用来设置创建的文件和目录的权限。默认的umask是0022
,这意味着世界可读和用户可写。你可以选择将其设置为0000
以获得完全开放的权限,或者设置为0007
以获得用户和组的读/写权限,但拒绝其他人的权限。查看UNIX umask
的文档以获取更多示例。
$sync->setUmask(0007);
latest()
这返回已存储内容的最新版本。
$content = $sync->latest();
exec(callable $cb)
要写入内容的一个版本,传递一个可调用的返回要存储的数据。如果存在先前的版本,将创建一个版本文件以及一个diff。
$sync->exec(function(){ return 'Hello World!'; });
retainState(int $count)
默认情况下,保留内容的最后三个完整版本。这可以通过将其设置为更少或更多来调整。请注意,diffs保留整个历史,所以总是可以重建任何过去的状态。这些只是保留以审查一致性。
// Hoard all the versions! $sync->retainState(10); // Save my disk space! $sync->retainState(1);
状态文件在每次调用exec()时都会清理。如果你想在调用exec()而不调用它的情况下清理状态文件,请调用purgeStateFiles()
。
$sync->retainState(1); $sync->purgeStateFiles()
示例文件
<?php // producer.php require 'vendor/autoload.php'; $sync = new Synchroversion\Synchroversion(dirname(__FILE__), 'syslog'); $sync->exec(function () { return file_get_contents('/var/log/system.log'); });
<?php // consumer.php require 'vendor/autoload.php'; $sync = new Synchroversion\Synchroversion(dirname(__FILE__), 'syslog'); echo $sync->latest();
这两个文件说明了跟踪syslog文件的写入器和读取器。
生产者可能会定期通过cron或其他动作运行。它可以每分钟运行一次,也可以一年运行一次——选择适合你数据的时间。
每5秒运行一次更新
while [[ true ]]; do php producer.php; sleep 5; done
在另一个终端中,获取最新版本
php consumer.php
待办事项
- 回放状态文件以验证当前状态
- 回放状态文件以生成历史状态
- 压缩状态文件