litestack 0.4.2 → 0.4.4
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 +4 -4
- data/.standard.yml +3 -1
- data/BENCHMARKS.md +3 -3
- data/CAVEATS.md +20 -0
- data/CHANGELOG.md +40 -1
- data/FILESYSTEMS.md +55 -0
- data/Gemfile +2 -0
- data/README.md +8 -4
- data/ROADMAP.md +6 -6
- data/assets/litestack_advantage.png +0 -0
- data/bench/bench.rb +2 -0
- data/bench/bench_cache_rails.rb +33 -2
- data/bench/bench_cache_raw.rb +36 -12
- data/bench/bench_jobs_rails.rb +3 -3
- data/bench/bench_jobs_raw.rb +3 -3
- data/bin/liteboard +16 -13
- data/gemfiles/rails70.gemfile +5 -0
- data/gemfiles/rails71.gemfile +5 -0
- data/gemfiles/rails71.gemfile.lock +264 -0
- data/lib/active_job/queue_adapters/litejob_adapter.rb +11 -3
- data/lib/active_record/connection_adapters/litedb_adapter.rb +8 -0
- data/lib/active_support/cache/litecache.rb +40 -7
- data/lib/generators/litestack/install/install_generator.rb +2 -2
- data/lib/generators/litestack/install/templates/cable.yml +0 -3
- data/lib/litestack/liteboard/liteboard.rb +15 -19
- data/lib/litestack/liteboard/views/litecable.erb +1 -1
- data/lib/litestack/litecable.rb +1 -1
- data/lib/litestack/litecache.rb +51 -19
- data/lib/litestack/litecache.sql.yml +7 -5
- data/lib/litestack/litedb.rb +5 -1
- data/lib/litestack/litejob.rb +1 -1
- data/lib/litestack/litejobqueue.rb +24 -14
- data/lib/litestack/litemetric.rb +7 -6
- data/lib/litestack/litemetric.sql.yml +1 -1
- data/lib/litestack/litemetric_collector.sql.yml +1 -1
- data/lib/litestack/litequeue.rb +17 -2
- data/lib/litestack/litequeue.sql.yml +38 -5
- data/lib/litestack/litescheduler.rb +9 -4
- data/lib/litestack/litesearch/index.rb +11 -10
- data/lib/litestack/litesearch/model.rb +61 -3
- data/lib/litestack/litesearch/schema.rb +7 -2
- data/lib/litestack/litesearch/schema_adapters/backed_adapter.rb +69 -25
- data/lib/litestack/litesearch/schema_adapters.rb +4 -4
- data/lib/litestack/litesearch.rb +2 -2
- data/lib/litestack/litesupport.rb +9 -7
- data/lib/litestack/railtie.rb +4 -2
- data/lib/litestack/version.rb +1 -1
- data/lib/litestack.rb +15 -15
- data/lib/railties/rails/commands/dbconsole.rb +5 -5
- data/lib/sequel/adapters/litedb.rb +9 -1
- data/lib/sequel/adapters/shared/litedb.rb +2 -2
- data/scripts/build_metrics.rb +2 -2
- data/scripts/test_cable.rb +1 -1
- metadata +105 -56
- data/Gemfile.lock +0 -92
@@ -0,0 +1,264 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
litestack (0.4.4)
|
5
|
+
erubi
|
6
|
+
oj
|
7
|
+
rack
|
8
|
+
rackup
|
9
|
+
sqlite3
|
10
|
+
tilt
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
actioncable (7.1.3.2)
|
16
|
+
actionpack (= 7.1.3.2)
|
17
|
+
activesupport (= 7.1.3.2)
|
18
|
+
nio4r (~> 2.0)
|
19
|
+
websocket-driver (>= 0.6.1)
|
20
|
+
zeitwerk (~> 2.6)
|
21
|
+
actionmailbox (7.1.3.2)
|
22
|
+
actionpack (= 7.1.3.2)
|
23
|
+
activejob (= 7.1.3.2)
|
24
|
+
activerecord (= 7.1.3.2)
|
25
|
+
activestorage (= 7.1.3.2)
|
26
|
+
activesupport (= 7.1.3.2)
|
27
|
+
mail (>= 2.7.1)
|
28
|
+
net-imap
|
29
|
+
net-pop
|
30
|
+
net-smtp
|
31
|
+
actionmailer (7.1.3.2)
|
32
|
+
actionpack (= 7.1.3.2)
|
33
|
+
actionview (= 7.1.3.2)
|
34
|
+
activejob (= 7.1.3.2)
|
35
|
+
activesupport (= 7.1.3.2)
|
36
|
+
mail (~> 2.5, >= 2.5.4)
|
37
|
+
net-imap
|
38
|
+
net-pop
|
39
|
+
net-smtp
|
40
|
+
rails-dom-testing (~> 2.2)
|
41
|
+
actionpack (7.1.3.2)
|
42
|
+
actionview (= 7.1.3.2)
|
43
|
+
activesupport (= 7.1.3.2)
|
44
|
+
nokogiri (>= 1.8.5)
|
45
|
+
racc
|
46
|
+
rack (>= 2.2.4)
|
47
|
+
rack-session (>= 1.0.1)
|
48
|
+
rack-test (>= 0.6.3)
|
49
|
+
rails-dom-testing (~> 2.2)
|
50
|
+
rails-html-sanitizer (~> 1.6)
|
51
|
+
actiontext (7.1.3.2)
|
52
|
+
actionpack (= 7.1.3.2)
|
53
|
+
activerecord (= 7.1.3.2)
|
54
|
+
activestorage (= 7.1.3.2)
|
55
|
+
activesupport (= 7.1.3.2)
|
56
|
+
globalid (>= 0.6.0)
|
57
|
+
nokogiri (>= 1.8.5)
|
58
|
+
actionview (7.1.3.2)
|
59
|
+
activesupport (= 7.1.3.2)
|
60
|
+
builder (~> 3.1)
|
61
|
+
erubi (~> 1.11)
|
62
|
+
rails-dom-testing (~> 2.2)
|
63
|
+
rails-html-sanitizer (~> 1.6)
|
64
|
+
activejob (7.1.3.2)
|
65
|
+
activesupport (= 7.1.3.2)
|
66
|
+
globalid (>= 0.3.6)
|
67
|
+
activemodel (7.1.3.2)
|
68
|
+
activesupport (= 7.1.3.2)
|
69
|
+
activerecord (7.1.3.2)
|
70
|
+
activemodel (= 7.1.3.2)
|
71
|
+
activesupport (= 7.1.3.2)
|
72
|
+
timeout (>= 0.4.0)
|
73
|
+
activestorage (7.1.3.2)
|
74
|
+
actionpack (= 7.1.3.2)
|
75
|
+
activejob (= 7.1.3.2)
|
76
|
+
activerecord (= 7.1.3.2)
|
77
|
+
activesupport (= 7.1.3.2)
|
78
|
+
marcel (~> 1.0)
|
79
|
+
activesupport (7.1.3.2)
|
80
|
+
base64
|
81
|
+
bigdecimal
|
82
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
83
|
+
connection_pool (>= 2.2.5)
|
84
|
+
drb
|
85
|
+
i18n (>= 1.6, < 2)
|
86
|
+
minitest (>= 5.1)
|
87
|
+
mutex_m
|
88
|
+
tzinfo (~> 2.0)
|
89
|
+
ast (2.4.2)
|
90
|
+
base64 (0.2.0)
|
91
|
+
bigdecimal (3.1.6)
|
92
|
+
builder (3.2.4)
|
93
|
+
concurrent-ruby (1.2.3)
|
94
|
+
connection_pool (2.4.1)
|
95
|
+
crass (1.0.6)
|
96
|
+
date (3.3.4)
|
97
|
+
docile (1.4.0)
|
98
|
+
drb (2.2.1)
|
99
|
+
erubi (1.12.0)
|
100
|
+
globalid (1.2.1)
|
101
|
+
activesupport (>= 6.1)
|
102
|
+
hanami-router (0.6.2)
|
103
|
+
hanami-utils (~> 0.7)
|
104
|
+
http_router (~> 0.11)
|
105
|
+
hanami-utils (0.9.2)
|
106
|
+
http_router (0.11.2)
|
107
|
+
rack (>= 1.0.0)
|
108
|
+
url_mount (~> 0.2.1)
|
109
|
+
i18n (1.14.1)
|
110
|
+
concurrent-ruby (~> 1.0)
|
111
|
+
io-console (0.7.2)
|
112
|
+
irb (1.11.2)
|
113
|
+
rdoc
|
114
|
+
reline (>= 0.4.2)
|
115
|
+
json (2.7.1)
|
116
|
+
language_server-protocol (3.17.0.3)
|
117
|
+
lint_roller (1.1.0)
|
118
|
+
loofah (2.22.0)
|
119
|
+
crass (~> 1.0.2)
|
120
|
+
nokogiri (>= 1.12.0)
|
121
|
+
mail (2.8.1)
|
122
|
+
mini_mime (>= 0.1.1)
|
123
|
+
net-imap
|
124
|
+
net-pop
|
125
|
+
net-smtp
|
126
|
+
marcel (1.0.4)
|
127
|
+
mini_mime (1.1.5)
|
128
|
+
minitest (5.22.2)
|
129
|
+
mutex_m (0.2.0)
|
130
|
+
net-imap (0.4.10)
|
131
|
+
date
|
132
|
+
net-protocol
|
133
|
+
net-pop (0.1.2)
|
134
|
+
net-protocol
|
135
|
+
net-protocol (0.2.2)
|
136
|
+
timeout
|
137
|
+
net-smtp (0.4.0.1)
|
138
|
+
net-protocol
|
139
|
+
nio4r (2.7.0)
|
140
|
+
nokogiri (1.16.2-arm64-darwin)
|
141
|
+
racc (~> 1.4)
|
142
|
+
oj (3.16.3)
|
143
|
+
bigdecimal (>= 3.0)
|
144
|
+
parallel (1.24.0)
|
145
|
+
parser (3.3.0.5)
|
146
|
+
ast (~> 2.4.1)
|
147
|
+
racc
|
148
|
+
psych (5.1.2)
|
149
|
+
stringio
|
150
|
+
racc (1.7.3)
|
151
|
+
rack (3.0.9.1)
|
152
|
+
rack-session (2.0.0)
|
153
|
+
rack (>= 3.0.0)
|
154
|
+
rack-test (2.1.0)
|
155
|
+
rack (>= 1.3)
|
156
|
+
rackup (2.1.0)
|
157
|
+
rack (>= 3)
|
158
|
+
webrick (~> 1.8)
|
159
|
+
rails (7.1.3.2)
|
160
|
+
actioncable (= 7.1.3.2)
|
161
|
+
actionmailbox (= 7.1.3.2)
|
162
|
+
actionmailer (= 7.1.3.2)
|
163
|
+
actionpack (= 7.1.3.2)
|
164
|
+
actiontext (= 7.1.3.2)
|
165
|
+
actionview (= 7.1.3.2)
|
166
|
+
activejob (= 7.1.3.2)
|
167
|
+
activemodel (= 7.1.3.2)
|
168
|
+
activerecord (= 7.1.3.2)
|
169
|
+
activestorage (= 7.1.3.2)
|
170
|
+
activesupport (= 7.1.3.2)
|
171
|
+
bundler (>= 1.15.0)
|
172
|
+
railties (= 7.1.3.2)
|
173
|
+
rails-dom-testing (2.2.0)
|
174
|
+
activesupport (>= 5.0.0)
|
175
|
+
minitest
|
176
|
+
nokogiri (>= 1.6)
|
177
|
+
rails-html-sanitizer (1.6.0)
|
178
|
+
loofah (~> 2.21)
|
179
|
+
nokogiri (~> 1.14)
|
180
|
+
railties (7.1.3.2)
|
181
|
+
actionpack (= 7.1.3.2)
|
182
|
+
activesupport (= 7.1.3.2)
|
183
|
+
irb
|
184
|
+
rackup (>= 1.0.0)
|
185
|
+
rake (>= 12.2)
|
186
|
+
thor (~> 1.0, >= 1.2.2)
|
187
|
+
zeitwerk (~> 2.6)
|
188
|
+
rainbow (3.1.1)
|
189
|
+
rake (13.1.0)
|
190
|
+
rdoc (6.6.2)
|
191
|
+
psych (>= 4.0.0)
|
192
|
+
regexp_parser (2.9.0)
|
193
|
+
reline (0.4.3)
|
194
|
+
io-console (~> 0.5)
|
195
|
+
rexml (3.2.6)
|
196
|
+
rubocop (1.61.0)
|
197
|
+
json (~> 2.3)
|
198
|
+
language_server-protocol (>= 3.17.0)
|
199
|
+
parallel (~> 1.10)
|
200
|
+
parser (>= 3.3.0.2)
|
201
|
+
rainbow (>= 2.2.2, < 4.0)
|
202
|
+
regexp_parser (>= 1.8, < 3.0)
|
203
|
+
rexml (>= 3.2.5, < 4.0)
|
204
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
205
|
+
ruby-progressbar (~> 1.7)
|
206
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
207
|
+
rubocop-ast (1.31.1)
|
208
|
+
parser (>= 3.3.0.4)
|
209
|
+
rubocop-performance (1.20.2)
|
210
|
+
rubocop (>= 1.48.1, < 2.0)
|
211
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
212
|
+
ruby-progressbar (1.13.0)
|
213
|
+
sequel (5.78.0)
|
214
|
+
bigdecimal
|
215
|
+
simplecov (0.22.0)
|
216
|
+
docile (~> 1.1)
|
217
|
+
simplecov-html (~> 0.11)
|
218
|
+
simplecov_json_formatter (~> 0.1)
|
219
|
+
simplecov-html (0.12.3)
|
220
|
+
simplecov_json_formatter (0.1.4)
|
221
|
+
sqlite3 (1.7.2-arm64-darwin)
|
222
|
+
standard (1.34.0)
|
223
|
+
language_server-protocol (~> 3.17.0.2)
|
224
|
+
lint_roller (~> 1.0)
|
225
|
+
rubocop (~> 1.60)
|
226
|
+
standard-custom (~> 1.0.0)
|
227
|
+
standard-performance (~> 1.3)
|
228
|
+
standard-custom (1.0.2)
|
229
|
+
lint_roller (~> 1.0)
|
230
|
+
rubocop (~> 1.50)
|
231
|
+
standard-performance (1.3.1)
|
232
|
+
lint_roller (~> 1.1)
|
233
|
+
rubocop-performance (~> 1.20.2)
|
234
|
+
stringio (3.1.0)
|
235
|
+
thor (1.3.1)
|
236
|
+
tilt (2.3.0)
|
237
|
+
timeout (0.4.1)
|
238
|
+
tzinfo (2.0.6)
|
239
|
+
concurrent-ruby (~> 1.0)
|
240
|
+
unicode-display_width (2.5.0)
|
241
|
+
url_mount (0.2.1)
|
242
|
+
rack
|
243
|
+
webrick (1.8.1)
|
244
|
+
websocket-driver (0.7.6)
|
245
|
+
websocket-extensions (>= 0.1.0)
|
246
|
+
websocket-extensions (0.1.5)
|
247
|
+
zeitwerk (2.6.13)
|
248
|
+
|
249
|
+
PLATFORMS
|
250
|
+
arm64-darwin
|
251
|
+
|
252
|
+
DEPENDENCIES
|
253
|
+
litestack!
|
254
|
+
minitest
|
255
|
+
rack (~> 3.0)
|
256
|
+
rails (~> 7.1)
|
257
|
+
railties
|
258
|
+
rake
|
259
|
+
sequel
|
260
|
+
simplecov
|
261
|
+
standard
|
262
|
+
|
263
|
+
BUNDLED WITH
|
264
|
+
2.5.3
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../../litestack/litejob"
|
4
|
+
require "active_support"
|
4
5
|
require "active_support/core_ext/enumerable"
|
6
|
+
require "active_support/core_ext/numeric/time"
|
5
7
|
require "active_support/core_ext/array/access"
|
6
8
|
require "active_job"
|
7
9
|
|
@@ -18,20 +20,26 @@ module ActiveJob
|
|
18
20
|
# Job.options = DEFAULT_OPTIONS.merge(options)
|
19
21
|
end
|
20
22
|
|
23
|
+
def enqueue_after_transaction_commit?
|
24
|
+
Job.options[:enqueue_after_transaction_commit]
|
25
|
+
end
|
26
|
+
|
21
27
|
def enqueue(job) # :nodoc:
|
22
28
|
Job.queue = job.queue_name
|
23
29
|
Job.perform_async(job.serialize)
|
24
30
|
end
|
25
31
|
|
26
|
-
def enqueue_at(job,
|
32
|
+
def enqueue_at(job, time) # :nodoc:
|
33
|
+
time = time.from_now if time.respond_to?(:from_now) #is_a?(ActiveSupport::Duration)
|
27
34
|
Job.queue = job.queue_name
|
28
|
-
Job.perform_at(
|
35
|
+
Job.perform_at(time, job.serialize)
|
29
36
|
end
|
30
37
|
|
31
38
|
class Job # :nodoc:
|
32
39
|
DEFAULT_OPTIONS = {
|
33
40
|
config_path: "./config/litejob.yml",
|
34
|
-
logger: nil # Rails performs its logging already
|
41
|
+
logger: nil, # Rails performs its logging already
|
42
|
+
enqueue_after_transaction_commit: true
|
35
43
|
}
|
36
44
|
|
37
45
|
include ::Litejob
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "../../litestack/litedb"
|
2
|
+
|
2
3
|
require "active_record"
|
3
4
|
require "active_record/connection_adapters/sqlite3_adapter"
|
4
5
|
require "active_record/tasks/sqlite_database_tasks"
|
@@ -90,3 +91,10 @@ module ActiveRecord
|
|
90
91
|
end
|
91
92
|
end
|
92
93
|
end
|
94
|
+
|
95
|
+
ActiveRecord::ConnectionAdapters.register(
|
96
|
+
"litedb", "ActiveRecord::ConnectionAdapters::LitedbAdapter",
|
97
|
+
"active_record/connection_adapters/litedb_adapter"
|
98
|
+
) if ActiveRecord::ConnectionAdapters.respond_to?(:register)
|
99
|
+
|
100
|
+
|
@@ -1,14 +1,16 @@
|
|
1
|
-
require "
|
2
|
-
require "active_support/core_ext/enumerable"
|
3
|
-
require "active_support/core_ext/array/extract_options"
|
1
|
+
require "active_support"
|
4
2
|
require "active_support/core_ext/numeric/time"
|
5
3
|
require "active_support/cache"
|
4
|
+
|
6
5
|
require_relative "../../litestack/litecache"
|
7
6
|
|
8
7
|
module ActiveSupport
|
9
8
|
module Cache
|
9
|
+
|
10
|
+
self.format_version = 7.0
|
11
|
+
|
10
12
|
class Litecache < Store
|
11
|
-
prepend Strategy::LocalCache
|
13
|
+
# prepend Strategy::LocalCache
|
12
14
|
|
13
15
|
def self.supports_cache_versioning?
|
14
16
|
true
|
@@ -25,17 +27,22 @@ module ActiveSupport
|
|
25
27
|
options = merged_options(options)
|
26
28
|
# todo: fix me
|
27
29
|
# this is currently a hack to avoid dealing with Rails cache encoding and decoding
|
30
|
+
# and it can result in a race condition as it stands
|
28
31
|
# @cache.transaction(:immediate) do
|
32
|
+
# currently transactions are not compatible with acquiring connections
|
33
|
+
# this needs fixing by storing the connection to the context once acquired
|
29
34
|
if (value = read(key, options))
|
30
35
|
value = value.to_i + amount
|
31
36
|
write(key, value, options)
|
37
|
+
else
|
38
|
+
write(key, amount, options)
|
32
39
|
end
|
33
40
|
# end
|
34
41
|
end
|
35
42
|
|
36
43
|
def decrement(key, amount = 1, options = nil)
|
37
44
|
options = merged_options(options)
|
38
|
-
increment(key, -1 * amount, options
|
45
|
+
increment(key, -1 * amount, options)
|
39
46
|
end
|
40
47
|
|
41
48
|
def prune(limit = nil, time = nil)
|
@@ -46,7 +53,7 @@ module ActiveSupport
|
|
46
53
|
@cache.prune(limit)
|
47
54
|
end
|
48
55
|
|
49
|
-
def clear
|
56
|
+
def clear(options = nil)
|
50
57
|
@cache.clear
|
51
58
|
end
|
52
59
|
|
@@ -68,18 +75,44 @@ module ActiveSupport
|
|
68
75
|
|
69
76
|
private
|
70
77
|
|
78
|
+
def serialize_entries(entry, **options)
|
79
|
+
Marshal.dump(entry)
|
80
|
+
end
|
81
|
+
|
82
|
+
def deserialize_entries(entry)
|
83
|
+
Marshal.load(entry.to_s)
|
84
|
+
end
|
85
|
+
|
71
86
|
# Read an entry from the cache.
|
72
87
|
def read_entry(key, **options)
|
73
88
|
deserialize_entry(@cache.get(key))
|
74
89
|
end
|
75
90
|
|
91
|
+
def read_multi_entries(names, **options)
|
92
|
+
results = {}
|
93
|
+
return results if names == []
|
94
|
+
rs = @cache.get_multi(*names.flatten)
|
95
|
+
rs.each_pair { |k, v| results[k] = deserialize_entry(v).value }
|
96
|
+
results
|
97
|
+
end
|
98
|
+
|
76
99
|
# Write an entry to the cache.
|
77
100
|
def write_entry(key, entry, **options)
|
78
101
|
write_serialized_entry(key, serialize_entry(entry, **options), **options)
|
79
102
|
end
|
80
103
|
|
104
|
+
def write_multi_entries(entries, **options)
|
105
|
+
return if entries.empty?
|
106
|
+
entries.each_pair { |k, v| entries[k] = serialize_entry(v, **options) }
|
107
|
+
expires_in = options[:expires_in].to_i if options[:expires_in]
|
108
|
+
if options[:race_condition_ttl] && expires_in > 0 && !options[:raw]
|
109
|
+
expires_in += 5.minutes
|
110
|
+
end
|
111
|
+
@cache.set_multi(entries, expires_in)
|
112
|
+
end
|
113
|
+
|
81
114
|
def write_serialized_entry(key, payload, **options)
|
82
|
-
expires_in = options[:expires_in].to_i
|
115
|
+
expires_in = options[:expires_in].to_i if options[:expires_in]
|
83
116
|
if options[:race_condition_ttl] && expires_in > 0 && !options[:raw]
|
84
117
|
expires_in += 5.minutes
|
85
118
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class Litestack::InstallGenerator < Rails::Generators::Base
|
2
2
|
source_root File.expand_path("templates", __dir__)
|
3
3
|
|
4
|
-
# Force copy
|
4
|
+
# Force copy configuration files so Rails installs don't ask questions
|
5
5
|
# that less experienced people might not understand. The more Sr folks.
|
6
6
|
# will know to check git to look at what changed.
|
7
|
-
def
|
7
|
+
def modify_database_adapter
|
8
8
|
copy_file "database.yml", "config/database.yml", force: true
|
9
9
|
end
|
10
10
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "rack"
|
4
4
|
require "tilt"
|
5
5
|
require "erubi"
|
6
6
|
|
@@ -11,37 +11,32 @@ class Liteboard
|
|
11
11
|
@@resolutions = {"minute" => [300, 12], "hour" => [3600, 24], "day" => [3600 * 24, 7], "week" => [3600 * 24 * 7, 53], "year" => [3600 * 24 * 365, 100]}
|
12
12
|
@@res_mapping = {"hour" => "minute", "day" => "hour", "week" => "day", "year" => "week"}
|
13
13
|
@@templates = {}
|
14
|
-
@@app =
|
15
|
-
|
14
|
+
@@app = proc do |env|
|
15
|
+
case path = env["PATH_INFO"]
|
16
|
+
when "/"
|
16
17
|
Liteboard.new(env).call(:index)
|
17
|
-
|
18
|
-
|
19
|
-
get "/topics/Litejob", to: ->(env) do
|
18
|
+
when "/topics/Litejob"
|
20
19
|
Liteboard.new(env).call(:litejob)
|
21
|
-
|
22
|
-
|
23
|
-
get "/topics/Litecache", to: ->(env) do
|
20
|
+
when "/topics/Litecache"
|
24
21
|
Liteboard.new(env).call(:litecache)
|
25
|
-
|
26
|
-
|
27
|
-
get "/topics/Litedb", to: ->(env) do
|
22
|
+
when "/topics/Litedb"
|
28
23
|
Liteboard.new(env).call(:litedb)
|
29
|
-
|
30
|
-
|
31
|
-
get "/topics/Litecable", to: ->(env) do
|
24
|
+
when "/topics/Litecable"
|
32
25
|
Liteboard.new(env).call(:litecable)
|
33
26
|
end
|
27
|
+
|
34
28
|
end
|
35
29
|
|
36
30
|
def initialize(env)
|
37
31
|
@env = env
|
38
|
-
@
|
32
|
+
@req = Rack::Request.new(@env)
|
33
|
+
@params = @req.params
|
39
34
|
@running = true
|
40
35
|
@lm = Litemetric.instance
|
41
36
|
end
|
42
37
|
|
43
38
|
def params(key)
|
44
|
-
URI.decode_uri_component(@params[key].to_s)
|
39
|
+
URI.decode_uri_component(@params[key.to_s].to_s)
|
45
40
|
end
|
46
41
|
|
47
42
|
def call(method)
|
@@ -227,9 +222,9 @@ class Liteboard
|
|
227
222
|
@topic = "Litejob"
|
228
223
|
@events = @lm.events_summaries(@topic, @resolution, @order, @dir, @search, @step * @count)
|
229
224
|
@events.each do |event|
|
230
|
-
data_points = @lm.event_data_points(@step, @count, @resolution, @topic, event[
|
225
|
+
data_points = @lm.event_data_points(@step, @count, @resolution, @topic, event[:name])
|
231
226
|
event["counts"] = data_points.collect { |r| [r["rtime"], r["rcount"] || 0] }
|
232
|
-
event["values"] = data_points.collect { |r| [r["rtime"], r["rtotal"] || 0] }
|
227
|
+
event["values"] = data_points.collect { |r| [r["rtime"], (r["rtotal"] || 0.0)] }
|
233
228
|
end
|
234
229
|
@snapshot = read_snapshot(@topic)
|
235
230
|
@size = begin
|
@@ -391,6 +386,7 @@ class Liteboard
|
|
391
386
|
end
|
392
387
|
|
393
388
|
def format(float)
|
389
|
+
float = float.round(3)
|
394
390
|
string = float.to_s
|
395
391
|
whole, decimal = string.split(".")
|
396
392
|
whole = whole.chars.reverse.each_slice(3).map(&:join).join(",").reverse
|
@@ -61,7 +61,7 @@
|
|
61
61
|
</div>
|
62
62
|
<div class="card-body">
|
63
63
|
<span class="hidden inlinestackedcolumn">
|
64
|
-
<%=[["Time", "
|
64
|
+
<%=[["Time", "Received Count", "Delivered Count"]] + @messages_over_time.to_a%>
|
65
65
|
</span>
|
66
66
|
</div>
|
67
67
|
</div>
|
data/lib/litestack/litecable.rb
CHANGED
@@ -113,7 +113,7 @@ class Litecable
|
|
113
113
|
def create_listener
|
114
114
|
Litescheduler.spawn do
|
115
115
|
while @running
|
116
|
-
@last_fetched_id ||=
|
116
|
+
@last_fetched_id ||= run_stmt(:last_id)[0][0] || 0
|
117
117
|
run_stmt(:fetch, @last_fetched_id, @pid).to_a.each do |msg|
|
118
118
|
@logger.info "RECEIVED #{msg}"
|
119
119
|
@last_fetched_id = msg[0]
|
data/lib/litestack/litecache.rb
CHANGED
@@ -20,13 +20,13 @@ class Litecache
|
|
20
20
|
include Litemetric::Measurable
|
21
21
|
|
22
22
|
# the default options for the cache
|
23
|
-
# can be
|
23
|
+
# can be overridden by passing new options in a hash
|
24
24
|
# to Litecache.new
|
25
25
|
# path: "./cache.db"
|
26
26
|
# expiry: 60 * 60 * 24 * 30 -> one month default expiry if none is provided
|
27
27
|
# size: 128 * 1024 * 1024 -> 128MB
|
28
28
|
# mmap_size: 128 * 1024 * 1024 -> 128MB to be held in memory
|
29
|
-
# min_size: 32 * 1024 ->
|
29
|
+
# min_size: 32 * 1024 -> 32KB
|
30
30
|
# return_full_record: false -> only return the payload
|
31
31
|
# sleep_interval: 1 -> 1 second of sleep between cleanup runs
|
32
32
|
|
@@ -39,7 +39,7 @@ class Litecache
|
|
39
39
|
mmap_size: 128 * 1024 * 1024, # 128MB
|
40
40
|
min_size: 8 * 1024 * 1024, # 16MB
|
41
41
|
return_full_record: false, # only return the payload
|
42
|
-
sleep_interval:
|
42
|
+
sleep_interval: 30, # 30 seconds
|
43
43
|
metrics: false
|
44
44
|
}
|
45
45
|
|
@@ -63,15 +63,15 @@ class Litecache
|
|
63
63
|
|
64
64
|
def initialize(options = {})
|
65
65
|
options[:size] = DEFAULT_OPTIONS[:min_size] if options[:size] && options[:size] < DEFAULT_OPTIONS[:min_size]
|
66
|
-
@last_visited = {}
|
67
66
|
init(options)
|
67
|
+
@expires_in = @options[:expiry] || 60 * 60 * 24 * 30
|
68
68
|
collect_metrics if @options[:metrics]
|
69
69
|
end
|
70
70
|
|
71
71
|
# add a key, value pair to the cache, with an optional expiry value (number of seconds)
|
72
72
|
def set(key, value, expires_in = nil)
|
73
73
|
key = key.to_s
|
74
|
-
expires_in
|
74
|
+
expires_in ||= @expires_in
|
75
75
|
@conn.acquire do |cache|
|
76
76
|
cache.stmts[:setter].execute!(key, value, expires_in)
|
77
77
|
capture(:set, key)
|
@@ -83,10 +83,27 @@ class Litecache
|
|
83
83
|
true
|
84
84
|
end
|
85
85
|
|
86
|
+
# set multiple keys and values in one shot set_multi({k1: v1, k2: v2, ... })
|
87
|
+
def set_multi(keys_and_values, expires_in = nil)
|
88
|
+
expires_in ||= @expires_in
|
89
|
+
transaction do |conn|
|
90
|
+
keys_and_values.each_pair do |k, v|
|
91
|
+
key = k.to_s
|
92
|
+
conn.stmts[:setter].execute!(key, v, expires_in)
|
93
|
+
capture(:set, key)
|
94
|
+
rescue SQLite3::FullException
|
95
|
+
conn.stmts[:extra_pruner].execute!(0.2)
|
96
|
+
conn.execute("vacuum")
|
97
|
+
retry
|
98
|
+
end
|
99
|
+
end
|
100
|
+
true
|
101
|
+
end
|
102
|
+
|
86
103
|
# add a key, value pair to the cache, but only if the key doesn't exist, with an optional expiry value (number of seconds)
|
87
104
|
def set_unless_exists(key, value, expires_in = nil)
|
88
105
|
key = key.to_s
|
89
|
-
expires_in
|
106
|
+
expires_in ||= @expires_in
|
90
107
|
changes = 0
|
91
108
|
@conn.acquire do |cache|
|
92
109
|
cache.transaction(:immediate) do
|
@@ -107,7 +124,6 @@ class Litecache
|
|
107
124
|
def get(key)
|
108
125
|
key = key.to_s
|
109
126
|
if (record = @conn.acquire { |cache| cache.stmts[:getter].execute!(key)[0] })
|
110
|
-
@last_visited[key] = true
|
111
127
|
capture(:get, key, 1)
|
112
128
|
return record[1]
|
113
129
|
end
|
@@ -115,6 +131,24 @@ class Litecache
|
|
115
131
|
nil
|
116
132
|
end
|
117
133
|
|
134
|
+
# get multiple values by their keys, a hash with values corresponding to the keys
|
135
|
+
# is returned,
|
136
|
+
def get_multi(*keys)
|
137
|
+
results = {}
|
138
|
+
transaction(:deferred) do |conn|
|
139
|
+
keys.length.times do |i|
|
140
|
+
key = keys[i].to_s
|
141
|
+
if (record = conn.stmts[:getter].execute!(key)[0])
|
142
|
+
results[keys[i]] = record[1] # use the original key format
|
143
|
+
capture(:get, key, 1)
|
144
|
+
else
|
145
|
+
capture(:get, key, 0)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
results
|
150
|
+
end
|
151
|
+
|
118
152
|
# delete a key, value pair from the cache
|
119
153
|
def delete(key)
|
120
154
|
changes = 0
|
@@ -126,13 +160,13 @@ class Litecache
|
|
126
160
|
end
|
127
161
|
|
128
162
|
# increment an integer value by amount, optionally add an expiry value (in seconds)
|
129
|
-
def increment(key, amount, expires_in = nil)
|
163
|
+
def increment(key, amount = 1, expires_in = nil)
|
130
164
|
expires_in ||= @expires_in
|
131
165
|
@conn.acquire { |cache| cache.stmts[:incrementer].execute!(key.to_s, amount, expires_in) }
|
132
166
|
end
|
133
167
|
|
134
168
|
# decrement an integer value by amount, optionally add an expiry value (in seconds)
|
135
|
-
def decrement(key, amount, expires_in = nil)
|
169
|
+
def decrement(key, amount = 1, expires_in = nil)
|
136
170
|
increment(key, -amount, expires_in)
|
137
171
|
end
|
138
172
|
|
@@ -189,11 +223,14 @@ class Litecache
|
|
189
223
|
end
|
190
224
|
|
191
225
|
# low level access to SQLite transactions, use with caution
|
192
|
-
def transaction(mode
|
193
|
-
return cache.transaction(mode) { yield } unless acquire
|
226
|
+
def transaction(mode = :immediate)
|
194
227
|
@conn.acquire do |cache|
|
195
|
-
cache.
|
228
|
+
if cache.transaction_active?
|
196
229
|
yield
|
230
|
+
else
|
231
|
+
cache.transaction(mode) do
|
232
|
+
yield cache
|
233
|
+
end
|
197
234
|
end
|
198
235
|
end
|
199
236
|
end
|
@@ -202,19 +239,14 @@ class Litecache
|
|
202
239
|
|
203
240
|
def setup
|
204
241
|
super # create connection
|
205
|
-
@bgthread = spawn_worker # create
|
242
|
+
@bgthread = spawn_worker # create background pruner thread
|
206
243
|
end
|
207
244
|
|
208
245
|
def spawn_worker
|
209
246
|
Litescheduler.spawn do
|
210
247
|
while @running
|
211
248
|
@conn.acquire do |cache|
|
212
|
-
cache.
|
213
|
-
@last_visited.delete_if do |k| # there is a race condition here, but not a serious one
|
214
|
-
cache.stmts[:toucher].execute!(k) || true
|
215
|
-
end
|
216
|
-
cache.stmts[:pruner].execute!
|
217
|
-
end
|
249
|
+
cache.stmts[:pruner].execute!
|
218
250
|
rescue SQLite3::BusyException
|
219
251
|
retry
|
220
252
|
rescue SQLite3::FullException
|