数据库查询无论如何都会被执行,但是是透明的。下面以 ActiveJob 内部的代码为例:
gid = User.find(1).to_global_id
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<GlobalID:0x00007f86f76f46d8 @uri=#<URI::GID gid://app/User/1>>
然后,当作业执行时,ActiveJob 在内部运行以下代码,无论如何都会查询数据库:
GlobalID::Locator.locate(gid)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> #<User id: 1, ... >
使用 GlobalIDs 的一个问题是,如果在作业入队之后但在调用 #perform 方法之前删除了传递的记录,则 Active Job 将引发 ActiveJob::DeserializationError 异常。
性能
根据 Sidekiq 的作者 Mike Perham 的说法,基准测试表明 ActiveJob 将作业推送到 Redis 的速度要慢 2-20 倍,处理开销大约是 3 倍 (https://github.com/mperham/sidekiq/wiki/Active-Job#performance)。
附加信息
关于 Sidekiq、ActiveJob 和 GlobalID 的所有信息都可以在这里找到:https://github.com/mperham/sidekiq/wiki/Active-Job#using-global-id