/
isolated_execution_state.rb
76 lines (57 loc) · 1.6 KB
/
isolated_execution_state.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# frozen_string_literal: true
require "fiber"
module ActiveSupport
module IsolatedExecutionState # :nodoc:
@isolation_level = nil
Thread.attr_accessor :active_support_execution_state
Fiber.attr_accessor :active_support_execution_state
class << self
attr_reader :isolation_level, :scope
def isolation_level=(level)
return if level == @isolation_level
unless %i(thread fiber).include?(level)
raise ArgumentError, "isolation_level must be `:thread` or `:fiber`, got: `#{level.inspect}`"
end
clear if @isolation_level
@scope =
case level
when :thread; Thread
when :fiber; Fiber
end
@isolation_level = level
end
def unique_id
self[:__id__] ||= Object.new
end
def [](key)
state[key]
end
def []=(key, value)
state[key] = value
end
def key?(key)
state.key?(key)
end
def delete(key)
state.delete(key)
end
def clear
state.clear
end
def context
scope.current
end
def share_with(other)
# Action Controller streaming spawns a new thread and copy thread locals.
# We do the same here for backward compatibility, but this is very much a hack
# and streaming should be rethought.
context.active_support_execution_state = other.active_support_execution_state.dup
end
private
def state
context.active_support_execution_state ||= {}
end
end
self.isolation_level = :thread
end
end