Skip to content

Commit 57c7f2a

Browse files
committed
feat: add action_policy.init event
1 parent 4fa0fad commit 57c7f2a

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## master
44

5+
- Add `action_policy.init` instrumentation event. ([@palkan][])
6+
7+
Triggered every time a new policy object is initialized.
8+
59
- Fix policy memoization with explicit context. ([@palkan][])
610

711
Explicit context (`authorize! context: {}`) wasn't considered during

docs/instrumentation.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ permitted to do that).
4747

4848
The `action_policy.apply_rule` might have a large number of failures, 'cause it also tracks the usage of non-raising applications (i.e. `allowed_to?`).
4949

50+
### `action_policy.init`
51+
52+
This event is triggered every time a new policy object is initialized.
53+
54+
The event contains the following information:
55+
56+
- `:policy` – policy class name.
57+
58+
This event is useful if you want to track the number of initialized policies per _action_ (for example, when you want to ensure that
59+
the [memoization](caching.md) works as expected).
60+
5061
## Turn off instrumentation
5162

5263
Instrumentation is enabled by default. To turn it off add to your configuration:

lib/action_policy/rails/policy/instrumentation.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ module Rails
66
# Add ActiveSupport::Notifications support.
77
#
88
# Fires `action_policy.apply_rule` event on every `#apply` call.
9+
# Fires `action_policy.init` event on every policy initialization.
910
module Instrumentation
10-
EVENT_NAME = "action_policy.apply_rule"
11+
INIT_EVENT_NAME = "action_policy.init"
12+
APPLY_EVENT_NAME = "action_policy.apply_rule"
13+
14+
def initialize(*)
15+
event = {policy: self.class.name}
16+
ActiveSupport::Notifications.instrument(INIT_EVENT_NAME, event) { super }
17+
end
1118

1219
def apply(rule)
1320
event = {policy: self.class.name, rule: rule.to_s}
14-
ActiveSupport::Notifications.instrument(EVENT_NAME, event) do
21+
ActiveSupport::Notifications.instrument(APPLY_EVENT_NAME, event) do
1522
res = super
1623
event[:cached] = result.cached?
1724
event[:value] = result.value

test/action_policy/rails/instrumentation_test.rb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def teardown
6262
def test_instrument_apply
6363
policy = TestPolicy.new false
6464

65+
# drop init event
66+
events.shift
67+
6568
refute policy.apply(:show?)
6669

6770
assert_equal 1, events.size
@@ -78,6 +81,9 @@ def test_instrument_apply
7881
def test_instrument_cached_apply
7982
policy = TestPolicy.new true
8083

84+
# drop init event
85+
events.shift
86+
8187
assert policy.apply(:manage?)
8288

8389
assert_equal 1, events.size
@@ -102,7 +108,11 @@ def test_instrument_authorize
102108
service = Service.new
103109

104110
assert_equal "OK", service.call
105-
assert_equal 2, events.size
111+
112+
assert_equal 3, events.size
113+
114+
# drop init event
115+
events.shift
106116

107117
event, data = events.shift
108118

@@ -122,7 +132,10 @@ def test_instrument_authorize
122132

123133
refute service.visible?(false)
124134

125-
assert_equal 1, events.size
135+
assert_equal 2, events.size
136+
137+
# drop init event
138+
events.shift
126139

127140
event, data = events.shift
128141

@@ -133,4 +146,14 @@ def test_instrument_authorize
133146
refute data[:value]
134147
refute data[:cached]
135148
end
149+
150+
def test_instrument_initialize
151+
TestPolicy.new true
152+
assert_equal 1, events.size
153+
154+
event, data = events.shift
155+
156+
assert_equal "action_policy.init", event
157+
assert_equal TestPolicy.name, data[:policy]
158+
end
136159
end

0 commit comments

Comments
 (0)