Merge branch '10968-arvput-resume-progress'
[arvados.git] / services / api / script / permission-updater.rb
1 #!/usr/bin/env ruby
2
3 ENV["RAILS_ENV"] = ARGV[0] || ENV["RAILS_ENV"] || "development"
4 require File.dirname(__FILE__) + '/../config/boot'
5 require File.dirname(__FILE__) + '/../config/environment'
6 include DbCurrentTime
7
8 def update_permissions
9   timestamp = DbCurrentTime::db_current_time.to_i
10   Rails.logger.info "Begin updating permission cache"
11   User.all.each do |u|
12     u.calculate_group_permissions
13   end
14   Rails.cache.write "last_updated_permissions", timestamp
15   Rails.logger.info "Permission cache updated"
16 end
17
18 ActiveRecord::Base.connection_pool.with_connection do |connection|
19   conn = connection.instance_variable_get(:@connection)
20   begin
21     conn.async_exec "LISTEN invalidate_permissions_cache"
22
23     # Initial refresh of permissions graph
24     update_permissions
25
26     while true
27       # wait_for_notify will block until there is a change
28       # notification from Postgres about the permission cache,
29       # and then rebuild the permission cache.
30       conn.wait_for_notify do |channel, pid, payload|
31         last_updated = Rails.cache.read("last_updated_permissions")
32         Rails.logger.info "Got notify #{payload} last update #{last_updated}"
33         if last_updated.nil? || last_updated.to_i <= payload.to_i
34           update_permissions
35         end
36       end
37     end
38   ensure
39     # Don't want the connection to still be listening once we return
40     # it to the pool - could result in weird behavior for the next
41     # thread to check it out.
42     conn.async_exec "UNLISTEN *"
43   end
44 end