celluloid 官网的文档通读下来,基本有所心得。现结合实际生产,编写一个应用程序,展示如下。
程序目的: 比对新旧两套数据库的同名表记录条数是否一致。预先已将需比对的表名写入 diff_log 表中,添加了两个字段new_count和 old_count用于保存表的记录条数。
-
require 'celluloid'
-
require 'dbi'
-
-
class MyWorker
-
-
# 定义一个 actor
-
include Celluloid
-
-
# 析构函数,当主 actor 退出时,所有的子 actor 将调用析构函数并退出
-
finalizer :my_finalizer
-
-
# 构造函数:连接新旧两套数据库
-
def initialize
-
@newdb = DBI.connect('dbi:OCI8:db_new','new_user','new_pass') or exit
-
@olddb = DBI.connect('dbi:OCI8:db_old','old_user','old_pass') or exit
-
end
-
-
# 统计记录条数,写入 diff_log
-
def calc(table_name)
-
new_count = @newdb.select_one("select count(1) c from #{table_name}").by_field("C");
-
old_count = @olddb.select_one("select count(1) c from #{table_name}").by_field("C");
-
-
sql = sprintf "update diff_log set new_count = %d,old_count = %d where table_name = '%s'",
-
new_count,old_count,table_name
-
puts sql
-
-
@newdb.execute(sql)
-
@newdb.commit
-
end
-
-
def my_finalizer
-
@newdb.disconnect if @newdb
-
@olddb.disconnect if @olddb
-
end
-
end
-
# 开启一个进程池,可以同时运行 20 个 actor
-
pool = MyWorker.pool(size: 20)
-
-
dbh = DBI.connect('dbi:OCI8:db_new','new_user','new_pass') or exit
-
# 主循环
-
dbh.select_all("select table_name from diff_log where new_count is null") do |row|
-
table_name = row.by_field "TABLE_NAME"
-
# 异步调用
-
pool.async.calc(table_name)
-
end
-
-
dbh.disconnect if dbh
-
# 休眠主进程。否则主进程将直接退出,所有子 actor 也将被 kill 掉。
-
# 终止程序只有按 ctrl+c
-
sleep
阅读(1652) | 评论(0) | 转发(0) |