scrolls 0.3.9 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +2 -0
- data/README.md +53 -14
- data/Rakefile +4 -2
- data/docs/global-context.md +1 -1
- data/docs/syslog.md +14 -1
- data/lib/scrolls/{iolog.rb → iologger.rb} +4 -2
- data/lib/scrolls/logger.rb +323 -0
- data/lib/scrolls/parser.rb +4 -2
- data/lib/scrolls/sysloglogger.rb +17 -0
- data/lib/scrolls/utils.rb +55 -13
- data/lib/scrolls/version.rb +1 -1
- data/lib/scrolls.rb +57 -77
- data/test/test_helper.rb +4 -1
- data/test/test_parser.rb +17 -2
- data/test/test_scrolls.rb +58 -47
- metadata +6 -10
- data/lib/scrolls/atomic.rb +0 -59
- data/lib/scrolls/log.rb +0 -262
- data/lib/scrolls/syslog.rb +0 -46
- data/test/test_atomic.rb +0 -33
data/lib/scrolls.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
require "
|
2
|
-
require "scrolls/atomic"
|
3
|
-
require "scrolls/log"
|
1
|
+
require "scrolls/logger"
|
4
2
|
require "scrolls/version"
|
5
3
|
|
6
4
|
module Scrolls
|
@@ -8,33 +6,27 @@ module Scrolls
|
|
8
6
|
|
9
7
|
# Public: Initialize a Scrolls logger
|
10
8
|
#
|
11
|
-
# Convienence method to prepare for future releases. Currently mimics
|
12
|
-
# behavior found in other methods. This prepares the developer for a future
|
13
|
-
# backward incompatible change, see:
|
14
|
-
# https://github.com/asenchi/scrolls/pull/54
|
15
|
-
#
|
16
9
|
# options - A hash of key/values for configuring Scrolls
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
Log.single_line_exceptions = true
|
33
|
-
end
|
10
|
+
# stream - Stream to output data (default: STDOUT)
|
11
|
+
# log_facility - Syslog facility (default: Syslog::LOG_USER)
|
12
|
+
# time_unit - Unit of time (default: seconds)
|
13
|
+
# timestamp - Prepend logs with a timestamp (default: false)
|
14
|
+
# exceptions - Method for outputting exceptions (default: single line)
|
15
|
+
# global_context - Immutable context to prepend all messages with
|
16
|
+
# syslog_options - Syslog options (default: Syslog::LOG_PID|Syslog::LOG_CONS)
|
17
|
+
# escape_keys - Escape chars in keys
|
18
|
+
# strict_logfmt - Always use double quotes to quote values
|
19
|
+
#
|
20
|
+
def init(options={})
|
21
|
+
# Set a hint whether #init was called.
|
22
|
+
@initialized = true
|
23
|
+
@log = Logger.new(options)
|
24
|
+
end
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
26
|
+
# Public: Get the primary logger
|
27
|
+
#
|
28
|
+
def logger
|
29
|
+
@log.logger
|
38
30
|
end
|
39
31
|
|
40
32
|
# Public: Set a context in a block for logs
|
@@ -45,37 +37,13 @@ module Scrolls
|
|
45
37
|
# Examples:
|
46
38
|
#
|
47
39
|
def context(data, &blk)
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
# Deprecated: Get or set a global context that prefixs all logs
|
52
|
-
#
|
53
|
-
# data - A hash of key/values to prepend to each log
|
54
|
-
#
|
55
|
-
# This method will be deprecated two releases after 0.3.8.
|
56
|
-
# See https://github.com/asenchi/scrolls/releases/tag/v0.3.8
|
57
|
-
# for more details.
|
58
|
-
#
|
59
|
-
def global_context(data=nil)
|
60
|
-
$stderr.puts "global_context() will be deprecated after v0.3.8, please see https://github.com/asenchi/scrolls for more information."
|
61
|
-
if data
|
62
|
-
Log.global_context = data
|
63
|
-
else
|
64
|
-
Log.global_context
|
65
|
-
end
|
40
|
+
@log.with_context(data, &blk)
|
66
41
|
end
|
67
42
|
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# data - A hash of key/values to prepend to each log
|
71
|
-
#
|
72
|
-
# This method will be deprecated two releases after 0.3.8.
|
73
|
-
# See https://github.com/asenchi/scrolls/releases/tag/v0.3.8
|
74
|
-
# for more details.
|
43
|
+
# Public: Get the global context that prefixs all logs
|
75
44
|
#
|
76
|
-
def
|
77
|
-
|
78
|
-
Log.add_global_context(data)
|
45
|
+
def global_context
|
46
|
+
@log.global_context
|
79
47
|
end
|
80
48
|
|
81
49
|
# Public: Log data and/or wrap a block with start/finish
|
@@ -96,26 +64,32 @@ module Scrolls
|
|
96
64
|
# => nil
|
97
65
|
#
|
98
66
|
def log(data, &blk)
|
99
|
-
|
67
|
+
# Allows us to call #log directly and initialize defaults
|
68
|
+
@log = Logger.new({}) unless @initialized
|
69
|
+
|
70
|
+
@log.log(data, &blk)
|
100
71
|
end
|
101
72
|
|
102
73
|
# Public: Log an exception
|
103
74
|
#
|
104
|
-
# data - A hash of key/values to log
|
105
75
|
# e - An exception to pass to the logger
|
76
|
+
# data - A hash of key/values to log
|
106
77
|
#
|
107
78
|
# Examples:
|
108
79
|
#
|
109
80
|
# begin
|
110
81
|
# raise Exception
|
111
82
|
# rescue Exception => e
|
112
|
-
# Scrolls.log_exception({test: "test"}
|
83
|
+
# Scrolls.log_exception(e, {test: "test"})
|
113
84
|
# end
|
114
85
|
# test=test at=exception class=Exception message=Exception exception_id=70321999017240
|
115
86
|
# ...
|
116
87
|
#
|
117
|
-
def log_exception(
|
118
|
-
|
88
|
+
def log_exception(e, data)
|
89
|
+
# Allows us to call #log directly and initialize defaults
|
90
|
+
@log = Logger.new({}) unless @initialized
|
91
|
+
|
92
|
+
@log.log_exception(e, data)
|
119
93
|
end
|
120
94
|
|
121
95
|
# Public: Setup a logging facility (default: Syslog::LOG_USER)
|
@@ -127,7 +101,7 @@ module Scrolls
|
|
127
101
|
# Scrolls.facility = Syslog::LOG_LOCAL7
|
128
102
|
#
|
129
103
|
def facility=(f)
|
130
|
-
|
104
|
+
@log.facility=(f)
|
131
105
|
end
|
132
106
|
|
133
107
|
# Public: Return the Syslog facility
|
@@ -138,7 +112,7 @@ module Scrolls
|
|
138
112
|
# => 8
|
139
113
|
#
|
140
114
|
def facility
|
141
|
-
|
115
|
+
@log.facility
|
142
116
|
end
|
143
117
|
|
144
118
|
# Public: Setup a new output (default: STDOUT)
|
@@ -154,7 +128,7 @@ module Scrolls
|
|
154
128
|
# Scrolls.stream = StringIO.new
|
155
129
|
#
|
156
130
|
def stream=(out)
|
157
|
-
|
131
|
+
@log.stream=(out)
|
158
132
|
end
|
159
133
|
|
160
134
|
# Public: Return the stream
|
@@ -165,7 +139,7 @@ module Scrolls
|
|
165
139
|
# => #<IO:<STDOUT>>
|
166
140
|
#
|
167
141
|
def stream
|
168
|
-
|
142
|
+
@log.stream
|
169
143
|
end
|
170
144
|
|
171
145
|
# Public: Set the time unit we use for 'elapsed' (default: "seconds")
|
@@ -177,7 +151,7 @@ module Scrolls
|
|
177
151
|
# Scrolls.time_unit = "milliseconds"
|
178
152
|
#
|
179
153
|
def time_unit=(unit)
|
180
|
-
|
154
|
+
@log.time_unit = unit
|
181
155
|
end
|
182
156
|
|
183
157
|
# Public: Return the time unit currently configured
|
@@ -188,7 +162,7 @@ module Scrolls
|
|
188
162
|
# => "seconds"
|
189
163
|
#
|
190
164
|
def time_unit
|
191
|
-
|
165
|
+
@log.time_unit
|
192
166
|
end
|
193
167
|
|
194
168
|
# Public: Set whether to include a timestamp (now=<ISO8601>) field in the log
|
@@ -199,7 +173,7 @@ module Scrolls
|
|
199
173
|
# Scrolls.add_timestamp = true
|
200
174
|
#
|
201
175
|
def add_timestamp=(boolean)
|
202
|
-
|
176
|
+
@log.timestamp = boolean
|
203
177
|
end
|
204
178
|
|
205
179
|
# Public: Return whether the timestamp field will be included in the log
|
@@ -211,7 +185,7 @@ module Scrolls
|
|
211
185
|
# => true
|
212
186
|
#
|
213
187
|
def add_timestamp
|
214
|
-
|
188
|
+
@log.timestamp
|
215
189
|
end
|
216
190
|
|
217
191
|
# Public: Set whether exceptions should generate a single log
|
@@ -222,7 +196,7 @@ module Scrolls
|
|
222
196
|
# Scrolls.single_line_exceptions = true
|
223
197
|
#
|
224
198
|
def single_line_exceptions=(boolean)
|
225
|
-
|
199
|
+
@log.exceptions = boolean
|
226
200
|
end
|
227
201
|
|
228
202
|
# Public: Return whether exceptions generate a single log message.
|
@@ -233,7 +207,7 @@ module Scrolls
|
|
233
207
|
# => true
|
234
208
|
#
|
235
209
|
def single_line_exceptions?
|
236
|
-
|
210
|
+
@log.single_line_exceptions?
|
237
211
|
end
|
238
212
|
|
239
213
|
# Public: Convience method for Logger replacement
|
@@ -249,7 +223,7 @@ module Scrolls
|
|
249
223
|
#
|
250
224
|
def debug(data, &blk)
|
251
225
|
data = data.merge(:level => "debug") if data.is_a?(Hash)
|
252
|
-
|
226
|
+
@log.log(data, &blk)
|
253
227
|
end
|
254
228
|
|
255
229
|
# Public: Convience method for Logger replacement
|
@@ -267,7 +241,7 @@ module Scrolls
|
|
267
241
|
#
|
268
242
|
def error(data, &blk)
|
269
243
|
data = data.merge(:level => "warning") if data.is_a?(Hash)
|
270
|
-
|
244
|
+
@log.log(data, &blk)
|
271
245
|
end
|
272
246
|
|
273
247
|
# Public: Convience method for Logger replacement
|
@@ -285,7 +259,7 @@ module Scrolls
|
|
285
259
|
#
|
286
260
|
def fatal(data, &blk)
|
287
261
|
data = data.merge(:level => "error") if data.is_a?(Hash)
|
288
|
-
|
262
|
+
@log.log(data, &blk)
|
289
263
|
end
|
290
264
|
|
291
265
|
# Public: Convience method for Logger replacement
|
@@ -303,7 +277,7 @@ module Scrolls
|
|
303
277
|
#
|
304
278
|
def info(data, &blk)
|
305
279
|
data = data.merge(:level => "info") if data.is_a?(Hash)
|
306
|
-
|
280
|
+
@log.log(data, &blk)
|
307
281
|
end
|
308
282
|
|
309
283
|
# Public: Convience method for Logger replacement
|
@@ -321,7 +295,7 @@ module Scrolls
|
|
321
295
|
#
|
322
296
|
def warn(data, &blk)
|
323
297
|
data = data.merge(:level => "notice") if data.is_a?(Hash)
|
324
|
-
|
298
|
+
@log.log(data, &blk)
|
325
299
|
end
|
326
300
|
|
327
301
|
# Public: Convience method for Logger replacement
|
@@ -339,7 +313,13 @@ module Scrolls
|
|
339
313
|
#
|
340
314
|
def unknown(data, &blk)
|
341
315
|
data = data.merge(:level => "alert") if data.is_a?(Hash)
|
342
|
-
|
316
|
+
@log.log(data, &blk)
|
317
|
+
end
|
318
|
+
|
319
|
+
# Internal: The Logger initialized by #init
|
320
|
+
#
|
321
|
+
def internal
|
322
|
+
@log
|
343
323
|
end
|
344
324
|
|
345
325
|
end
|
data/test/test_helper.rb
CHANGED
data/test/test_parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
2
|
|
3
|
-
class TestScrollsParser < Test
|
3
|
+
class TestScrollsParser < Minitest::Test
|
4
4
|
include Scrolls::Parser
|
5
5
|
|
6
6
|
def test_parse_bool
|
@@ -79,6 +79,21 @@ class TestScrollsParser < Test::Unit::TestCase
|
|
79
79
|
assert_equal 't="2012-06-19T16:02:35+01:00"', unparse(data)
|
80
80
|
end
|
81
81
|
|
82
|
+
def test_unparse_escape_keys
|
83
|
+
html = "<p>p</p>"
|
84
|
+
slash = "p/p"
|
85
|
+
|
86
|
+
data = { html => "d", slash => "d" }
|
87
|
+
assert_equal '<p>p</p>=d p/p=d',
|
88
|
+
unparse(data, escape_keys=true)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_unparse_strict_logfmt
|
92
|
+
data = { s: 'echo "hello"' }
|
93
|
+
assert_equal 's="echo \"hello\""', unparse(data, escape_keys=false, strict_logfmt=true)
|
94
|
+
assert_equal data.inspect, parse(unparse(data, escape_keys=false, strict_logfmt=true)).inspect
|
95
|
+
end
|
96
|
+
|
82
97
|
def test_parse_time
|
83
98
|
time = Time.new(2012, 06, 19, 16, 02, 35, "+01:00")
|
84
99
|
string = "t=2012-06-19T16:02:35+01:00"
|
data/test/test_scrolls.rb
CHANGED
@@ -1,44 +1,35 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
2
|
|
3
|
-
class TestScrolls < Test
|
3
|
+
class TestScrolls < Minitest::Test
|
4
4
|
def setup
|
5
5
|
@out = StringIO.new
|
6
|
-
Scrolls.init(
|
7
|
-
|
8
|
-
|
9
|
-
def teardown
|
10
|
-
Scrolls.global_context({})
|
11
|
-
# Reset our syslog context
|
12
|
-
Scrolls.facility = Scrolls::LOG_FACILITY
|
13
|
-
Scrolls.add_timestamp = false
|
6
|
+
Scrolls.init(
|
7
|
+
:stream => @out
|
8
|
+
)
|
14
9
|
end
|
15
10
|
|
16
|
-
def
|
17
|
-
|
11
|
+
def test_default_construct
|
12
|
+
Scrolls.init
|
13
|
+
assert_equal Scrolls::IOLogger, Scrolls.logger.class
|
18
14
|
end
|
19
15
|
|
20
16
|
def test_default_global_context
|
17
|
+
Scrolls.init(:stream => @out)
|
21
18
|
assert_equal Hash.new, Scrolls.global_context
|
22
19
|
end
|
23
20
|
|
24
21
|
def test_setting_global_context
|
25
|
-
Scrolls.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_adding_to_global_context
|
32
|
-
Scrolls.global_context(:g => "g")
|
33
|
-
Scrolls.add_global_context(:h => "h")
|
22
|
+
Scrolls.init(
|
23
|
+
:stream => @out,
|
24
|
+
:global_context => {:g => "g"},
|
25
|
+
)
|
34
26
|
Scrolls.log(:d => "d")
|
35
|
-
|
36
|
-
assert_match /g=g.*h=h.*d=d/, global
|
27
|
+
assert_equal "g=g d=d\n", @out.string
|
37
28
|
end
|
38
29
|
|
39
30
|
def test_default_context
|
40
|
-
Scrolls.log(:
|
41
|
-
assert_equal Hash.new, Scrolls
|
31
|
+
Scrolls.log(:d => "d")
|
32
|
+
assert_equal Hash.new, Scrolls.internal.context
|
42
33
|
end
|
43
34
|
|
44
35
|
def test_setting_context
|
@@ -48,15 +39,19 @@ class TestScrolls < Test::Unit::TestCase
|
|
48
39
|
end
|
49
40
|
|
50
41
|
def test_all_the_contexts
|
51
|
-
Scrolls.
|
42
|
+
Scrolls.init(
|
43
|
+
:stream => @out,
|
44
|
+
:global_context => {:g => "g"},
|
45
|
+
)
|
52
46
|
Scrolls.log(:o => "o") do
|
53
47
|
Scrolls.context(:c => "c") do
|
54
48
|
Scrolls.log(:ic => "i")
|
55
49
|
end
|
56
50
|
Scrolls.log(:i => "i")
|
57
51
|
end
|
58
|
-
|
59
|
-
|
52
|
+
@out.truncate(37)
|
53
|
+
output = "g=g o=o at=start\ng=g c=c ic=i\ng=g i=i"
|
54
|
+
assert_equal output, @out.string
|
60
55
|
end
|
61
56
|
|
62
57
|
def test_deeply_nested_context
|
@@ -89,12 +84,27 @@ class TestScrolls < Test::Unit::TestCase
|
|
89
84
|
raise "Error from inside of context"
|
90
85
|
end
|
91
86
|
fail "Exception did not escape context block"
|
92
|
-
rescue
|
87
|
+
rescue
|
93
88
|
Scrolls.log(:o => 'o')
|
94
89
|
assert_equal "o=o\n", @out.string
|
95
90
|
end
|
96
91
|
end
|
97
92
|
|
93
|
+
def test_deeply_nested_context_after_exception
|
94
|
+
Scrolls.log(:o => "o") do
|
95
|
+
begin
|
96
|
+
Scrolls.log(:io => 'io') do
|
97
|
+
raise "Error from inside of nested logging"
|
98
|
+
end
|
99
|
+
rescue
|
100
|
+
Scrolls.log(:o => 'o')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
@out.truncate(124)
|
104
|
+
output = "o=o at=start\nio=io at=start\nio=io at=exception reraise=true class=RuntimeError message=\"Error from inside of nested logging\""
|
105
|
+
assert_equal output, @out.string
|
106
|
+
end
|
107
|
+
|
98
108
|
def test_default_time_unit
|
99
109
|
assert_equal "seconds", Scrolls.time_unit
|
100
110
|
end
|
@@ -105,8 +115,15 @@ class TestScrolls < Test::Unit::TestCase
|
|
105
115
|
end
|
106
116
|
|
107
117
|
def test_setting_incorrect_time_unit
|
108
|
-
|
118
|
+
assert_raises Scrolls::TimeUnitError do
|
109
119
|
Scrolls.time_unit = "years"
|
120
|
+
Scrolls.log(:tu => "yrs")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_unknown_log_level
|
125
|
+
assert_raises Scrolls::LogLevelError do
|
126
|
+
Scrolls.log(:level => "nope")
|
110
127
|
end
|
111
128
|
end
|
112
129
|
|
@@ -125,28 +142,28 @@ class TestScrolls < Test::Unit::TestCase
|
|
125
142
|
begin
|
126
143
|
raise Exception
|
127
144
|
rescue Exception => e
|
128
|
-
Scrolls.log_exception({:test => "exception"}
|
145
|
+
Scrolls.log_exception(e, {:test => "exception"})
|
129
146
|
end
|
130
147
|
|
131
|
-
|
132
|
-
|
133
|
-
assert_match /test=exception at=exception.*test_log_exception.*XX/,
|
134
|
-
oneline_backtrace
|
148
|
+
oneline_bt = @out.string.gsub("\n", 'XX')
|
149
|
+
assert_match(/test=exception at=exception.*test_log_exception.*XX/, oneline_bt)
|
135
150
|
end
|
136
151
|
|
137
|
-
def
|
138
|
-
Scrolls.single_line_exceptions =
|
152
|
+
def test_multi_line_exceptions
|
153
|
+
Scrolls.single_line_exceptions = "multi"
|
139
154
|
begin
|
140
155
|
raise Exception
|
141
156
|
rescue Exception => e
|
142
|
-
Scrolls.log_exception({:o => "o"}
|
157
|
+
Scrolls.log_exception(e, {:o => "o"})
|
143
158
|
end
|
144
|
-
|
159
|
+
|
160
|
+
oneline_bt = @out.string.gsub("\n", 'XX')
|
161
|
+
assert_match(/o=o at=exception.*test_multi_line_exceptions.*XX/, oneline_bt)
|
145
162
|
end
|
146
163
|
|
147
164
|
def test_syslog_integration
|
148
165
|
Scrolls.stream = 'syslog'
|
149
|
-
assert_equal Scrolls::SyslogLogger, Scrolls.
|
166
|
+
assert_equal Scrolls::SyslogLogger, Scrolls.internal.logger.class
|
150
167
|
end
|
151
168
|
|
152
169
|
def test_syslog_facility
|
@@ -162,13 +179,7 @@ class TestScrolls < Test::Unit::TestCase
|
|
162
179
|
def test_setting_syslog_facility_after_instantiation
|
163
180
|
Scrolls.stream = 'syslog'
|
164
181
|
Scrolls.facility = 'local7'
|
165
|
-
assert_match
|
166
|
-
end
|
167
|
-
|
168
|
-
def test_logging_message_with_syslog
|
169
|
-
Scrolls.stream = 'syslog'
|
170
|
-
Scrolls.facility = 'local7'
|
171
|
-
Scrolls.log "scrolls test"
|
182
|
+
assert_match(/facility=184/, Scrolls.internal.logger.inspect)
|
172
183
|
end
|
173
184
|
|
174
185
|
def test_add_timestamp
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scrolls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Curt Micol
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Logging, easier, more consistent.
|
14
14
|
email:
|
@@ -25,15 +25,13 @@ files:
|
|
25
25
|
- docs/global-context.md
|
26
26
|
- docs/syslog.md
|
27
27
|
- lib/scrolls.rb
|
28
|
-
- lib/scrolls/
|
29
|
-
- lib/scrolls/
|
30
|
-
- lib/scrolls/log.rb
|
28
|
+
- lib/scrolls/iologger.rb
|
29
|
+
- lib/scrolls/logger.rb
|
31
30
|
- lib/scrolls/parser.rb
|
32
|
-
- lib/scrolls/
|
31
|
+
- lib/scrolls/sysloglogger.rb
|
33
32
|
- lib/scrolls/utils.rb
|
34
33
|
- lib/scrolls/version.rb
|
35
34
|
- scrolls.gemspec
|
36
|
-
- test/test_atomic.rb
|
37
35
|
- test/test_helper.rb
|
38
36
|
- test/test_parser.rb
|
39
37
|
- test/test_scrolls.rb
|
@@ -56,13 +54,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
54
|
- !ruby/object:Gem::Version
|
57
55
|
version: '0'
|
58
56
|
requirements: []
|
59
|
-
|
60
|
-
rubygems_version: 2.6.11
|
57
|
+
rubygems_version: 3.2.29
|
61
58
|
signing_key:
|
62
59
|
specification_version: 4
|
63
60
|
summary: When do we log? All the time.
|
64
61
|
test_files:
|
65
|
-
- test/test_atomic.rb
|
66
62
|
- test/test_helper.rb
|
67
63
|
- test/test_parser.rb
|
68
64
|
- test/test_scrolls.rb
|
data/lib/scrolls/atomic.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
|
-
module Scrolls
|
4
|
-
# The result of issues with an update I made to Scrolls. After talking with
|
5
|
-
# Fabio Kung about a fix I started work on an atomic object, but he added some
|
6
|
-
# fixes to #context without it and then used Headius' atomic gem.
|
7
|
-
#
|
8
|
-
# The code below is the start and cleanup of my atomic object. It's slim on
|
9
|
-
# details and eventually cleaned up around inspiration from Headius' code.
|
10
|
-
#
|
11
|
-
# LICENSE: Apache 2.0
|
12
|
-
#
|
13
|
-
# See Headius' atomic gem here:
|
14
|
-
# https://github.com/headius/ruby-atomic
|
15
|
-
class AtomicObject
|
16
|
-
def initialize(o)
|
17
|
-
@mtx = Mutex.new
|
18
|
-
@o = o
|
19
|
-
end
|
20
|
-
|
21
|
-
def get
|
22
|
-
@mtx.synchronize { @o }
|
23
|
-
end
|
24
|
-
|
25
|
-
def set(n)
|
26
|
-
@mtx.synchronize { @o = n }
|
27
|
-
end
|
28
|
-
|
29
|
-
def verify_set(o, n)
|
30
|
-
return false unless @mtx.try_lock
|
31
|
-
begin
|
32
|
-
return false unless @o.equal? o
|
33
|
-
@o = n
|
34
|
-
ensure
|
35
|
-
@mtx.unlock
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Atomic < AtomicObject
|
41
|
-
def initialize(v=nil)
|
42
|
-
super(v)
|
43
|
-
end
|
44
|
-
|
45
|
-
def value
|
46
|
-
self.get
|
47
|
-
end
|
48
|
-
|
49
|
-
def value=(v)
|
50
|
-
self.set(v)
|
51
|
-
v
|
52
|
-
end
|
53
|
-
|
54
|
-
def update
|
55
|
-
true until self.verify_set(o = self.get, n = yield(o))
|
56
|
-
n
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|