game_server.entity_backup
简介
基于engine实现的mongo db数据安全存取功能模块
- 主要目的是在系统发生异常的情况下,能够减少数据损失;
- 实现的基本想法是: 待保存的数据先备份到本地文件再向数据库实际写入
- 几点说明:
- 1.本模块初始化后将替换掉engine.mods.mongo中的一些mongo脚本实现,以保证上层脚本使用时是透明的;
- 2.所有自定义的本模块的功能模块需要包含FEntityBackupOp组件
组件接口
EntityBackupContext.gs
持久操作的全局上下文
| 函数原型 | 函数作用 |
|---|---|
| void setup() | 初始化上下文 |
| void notify_persist_done(array backup_id_list) | 响应指定变化的持久化操作完成 |
| int get_last_save_backup_id() | 获取已完成的最大持久化操作的编号id(最大编号id) |
| int get_last_droppable_backup_id() | 获取可丢弃的最大持久化操作编号id |
| void set_last_save_backup_id(int backup_id) | 设置最近一次持久化操作编号id |
EntityBackupPersist.gs
持久化操作对象 将实体数据写入mongodb数据库中
对于同一个实体对象的多个持久化操作执行合并,比如连续2个全量写操作将合并为一个全量写操作
| 函数原型 | 函数作用 |
|---|---|
| string desc() | 获取描述信息 |
| bool notify_persist_at_once(string rid, mixed wait_time = -1) | 通知立刻执行指定rid的实体对象持久化操作并等待结果 |
| void dispatch(int backup_id, array args, function persist_callback = nil) | 向持久化队列中添加持久化操作 |
| void enqueue(int backup_id, array args, function persist_callback = nil) | 添加到持久化操作队列中 |
| void set_recovery_mode(bool on = true) | 设置是否开启恢复模式 |
EntityBackupPersistPool.gs
持久化操作处理的协程池
| 函数原型 | 函数作用 |
|---|---|
| void startup(map para) | 启动 |
| void shutdown() | 关闭 |
| void dispatch(int backup_id, array args, function persist_callback = nil) | 分发操作 |
| bool notify_persist_at_once(string rid, mixed wait_time = -1) | 通知立刻执行指定rid的实体对象的持久化操作并等待结果(阻塞异步模式) |
| void set_recovery_mode(bool on = true) | 设置是否开启恢复模式 |
| void scan_ops_until_complete() | 扫描所有持久化操作直至完成 |
entity_backup.gs
| 函数原型 | 函数作用 |
|---|---|
| bool setup(map para = ) | 初始化模块设置 |
| bool startup(map para = ) | 本模块初始化, 等同于调用setup |
| array read(string db_name, string coll, string op, string rid, ...) | 读操作: 在目标数据库集合上对指定的实体rid进行读操作 |
| bool write(string db_name, string coll, string op, string rid, ...) | 写操作: 在目标数据库集合上对指定的实体rid进行写操作;在本地文件上写成功后就返回 |
| bool write_async(string db_name, string coll, string op, string rid, ...) | 异步写操作: 在目标数据库集合上对指定的实体rid进行写操作;投递后立刻返回 |
| bool write_async_callback(function callback, string db_name, string coll, string op, string rid, ...) | 异步写操作带有回调: 在目标数据库集合上对指定的实体rid进行写操作;在本地文件上写成功后执行回调 |
| bool persist(string db_name, string coll, string op, string rid, ...) | 持久化操作: 在目标数据库集合上对指定的实体rid进行写操作;在持久化数据以后返回 |
| bool persist_async_callback(function callback, string db_name, string coll, string op, string rid, ...) | 异步持久化操作带有回调: 在目标数据库集合上对指定的实体rid进行写操作;在持久化数据后执行回调 |
| bool is_writing(string rid) | 指定实体rid的是否正在进行写操作 |
| void try_drop_docs() | 尝试删除本地无用的备份数据文件 |
FEntityBackupOp.gs
实体备份机制支持的数据库操作组件
自定义的数据库操作需要包含本组件(参考ops/目录下的操作实现)
| 函数原型 | 函数作用 |
|---|---|
| bool is_combinable() | 虚函数 - 两个相同名称的持久化操作是否可以合并(默认是可以合并的) |
样例
public void test()
{
cfg.init_by_map({
"server_id" : 1234,
});
engine.boot();
LogD.disable_mongodb();
load_static(entity_backup, domain.create());
entity_backup.startup();
int now;
int st = time.time_ms();
now = time.time();
for (int i = 1 upto 100000)
{
string rid = sprintf("R%d%d", now, i % COUNT);
map data = {
"rid" : rid,
"value" : i
};
entity_backup.write_async("base@1234", "entity", "update_fields", rid, {}, data);
}
printf("1->cost %d ms\n", time.time_ms() - st);
for (int n = 1 upto COUNT)
{
string rid = sprintf("R%d%d", now, n % COUNT);
entity_backup.notify_persist_at_once(rid);
}
printf("2->cost %d ms\n", time.time_ms() - st);
object ob = mongo.agent("base@1234");
now = time.time();
for (int i = 1 upto 1)
{
string rid = sprintf("R%d%d", now, i % COUNT);
map data = {
"rid" : rid,
"value" : i
};
ob.save_entity_sync(data);
}
}