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