litestack 0.4.1 → 0.4.2
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 -0
- data/BENCHMARKS.md +23 -7
- data/CHANGELOG.md +11 -0
- data/Gemfile +1 -7
- data/Gemfile.lock +92 -0
- data/README.md +120 -6
- data/ROADMAP.md +45 -0
- data/Rakefile +3 -1
- data/WHYLITESTACK.md +1 -1
- data/assets/litecache_metrics.png +0 -0
- data/assets/litedb_metrics.png +0 -0
- data/assets/litemetric_logo_teal.png +0 -0
- data/assets/litesearch_logo_teal.png +0 -0
- data/bench/bench.rb +17 -10
- data/bench/bench_cache_rails.rb +10 -13
- data/bench/bench_cache_raw.rb +17 -22
- data/bench/bench_jobs_rails.rb +18 -12
- data/bench/bench_jobs_raw.rb +17 -10
- data/bench/bench_queue.rb +4 -6
- data/bench/rails_job.rb +5 -7
- data/bench/skjob.rb +4 -4
- data/bench/uljob.rb +6 -6
- data/lib/action_cable/subscription_adapter/litecable.rb +5 -8
- data/lib/active_job/queue_adapters/litejob_adapter.rb +6 -8
- data/lib/active_record/connection_adapters/litedb_adapter.rb +65 -75
- data/lib/active_support/cache/litecache.rb +38 -41
- data/lib/generators/litestack/install/install_generator.rb +3 -3
- data/lib/generators/litestack/install/templates/database.yml +7 -1
- data/lib/litestack/liteboard/liteboard.rb +269 -149
- data/lib/litestack/litecable.rb +41 -37
- data/lib/litestack/litecable.sql.yml +22 -11
- data/lib/litestack/litecache.rb +79 -88
- data/lib/litestack/litecache.sql.yml +81 -22
- data/lib/litestack/litecache.yml +1 -1
- data/lib/litestack/litedb.rb +35 -40
- data/lib/litestack/litejob.rb +30 -29
- data/lib/litestack/litejobqueue.rb +63 -65
- data/lib/litestack/litemetric.rb +80 -92
- data/lib/litestack/litemetric.sql.yml +244 -234
- data/lib/litestack/litemetric_collector.sql.yml +38 -41
- data/lib/litestack/litequeue.rb +39 -41
- data/lib/litestack/litequeue.sql.yml +39 -31
- data/lib/litestack/litescheduler.rb +15 -15
- data/lib/litestack/litesearch/index.rb +93 -63
- data/lib/litestack/litesearch/model.rb +66 -65
- data/lib/litestack/litesearch/schema.rb +53 -56
- data/lib/litestack/litesearch/schema_adapters/backed_adapter.rb +46 -50
- data/lib/litestack/litesearch/schema_adapters/basic_adapter.rb +44 -35
- data/lib/litestack/litesearch/schema_adapters/contentless_adapter.rb +3 -6
- data/lib/litestack/litesearch/schema_adapters/standalone_adapter.rb +7 -9
- data/lib/litestack/litesearch/schema_adapters.rb +4 -9
- data/lib/litestack/litesearch.rb +6 -9
- data/lib/litestack/litesupport.rb +76 -86
- data/lib/litestack/railtie.rb +1 -1
- data/lib/litestack/version.rb +2 -2
- data/lib/litestack.rb +6 -4
- data/lib/railties/rails/commands/dbconsole.rb +11 -15
- data/lib/sequel/adapters/litedb.rb +16 -21
- data/lib/sequel/adapters/shared/litedb.rb +168 -168
- data/scripts/build_metrics.rb +91 -0
- data/scripts/test_cable.rb +30 -0
- data/scripts/test_job_retry.rb +33 -0
- data/scripts/test_metrics.rb +60 -0
- data/template.rb +2 -2
- metadata +101 -6
data/bench/bench_jobs_rails.rb
CHANGED
@@ -1,39 +1,45 @@
|
|
1
|
-
require
|
1
|
+
require "./bench"
|
2
2
|
|
3
|
-
count =
|
3
|
+
count = begin
|
4
|
+
ARGV[0].to_i
|
5
|
+
rescue
|
6
|
+
1000
|
7
|
+
end
|
4
8
|
env = ARGV[1] || "t"
|
5
|
-
|
6
|
-
|
9
|
+
_delay = begin
|
10
|
+
ARGV[2].to_f
|
11
|
+
rescue
|
12
|
+
0
|
13
|
+
end
|
7
14
|
|
8
|
-
#ActiveJob::Base.logger = Logger.new(IO::NULL)
|
15
|
+
# ActiveJob::Base.logger = Logger.new(IO::NULL)
|
9
16
|
|
10
|
-
require
|
17
|
+
require "./rails_job"
|
11
18
|
|
12
19
|
RailsJob.queue_adapter = :sidekiq
|
13
20
|
t = Time.now.to_f
|
14
|
-
puts "Make sure sidekiq is started with -c ./rails_job.rb"
|
15
|
-
bench("enqueuing sidekiq jobs", count) do
|
21
|
+
puts "Make sure sidekiq is started with -c ./rails_job.rb"
|
22
|
+
bench("enqueuing sidekiq jobs", count) do
|
16
23
|
RailsJob.perform_later(count, t)
|
17
24
|
end
|
18
25
|
|
19
26
|
puts "Don't forget to check the sidekiq log for processing time conclusion"
|
20
27
|
|
21
|
-
|
22
28
|
# Litejob bench
|
23
29
|
###############
|
24
30
|
|
25
31
|
if env == "a" # threaded
|
26
|
-
require
|
32
|
+
require "async/scheduler"
|
27
33
|
Fiber.set_scheduler Async::Scheduler.new
|
28
34
|
ActiveSupport::IsolatedExecutionState.isolation_level = :fiber
|
29
35
|
end
|
30
36
|
|
31
|
-
require_relative
|
37
|
+
require_relative "../lib/active_job/queue_adapters/litejob_adapter"
|
32
38
|
puts Litescheduler.backend
|
33
39
|
|
34
40
|
RailsJob.queue_adapter = :litejob
|
35
41
|
t = Time.now.to_f
|
36
|
-
bench("enqueuing litejobs", count) do
|
42
|
+
bench("enqueuing litejobs", count) do
|
37
43
|
RailsJob.perform_later(count, t)
|
38
44
|
end
|
39
45
|
|
data/bench/bench_jobs_raw.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
-
require
|
1
|
+
require "./bench"
|
2
2
|
|
3
|
-
count =
|
3
|
+
count = begin
|
4
|
+
ARGV[0].to_i
|
5
|
+
rescue
|
6
|
+
1000
|
7
|
+
end
|
4
8
|
env = ARGV[1] || "t"
|
5
|
-
delay =
|
9
|
+
delay = begin
|
10
|
+
ARGV[2].to_f
|
11
|
+
rescue
|
12
|
+
0
|
13
|
+
end
|
6
14
|
|
7
15
|
# Sidekiq bench
|
8
16
|
###############
|
9
|
-
require
|
17
|
+
require "./skjob"
|
10
18
|
|
11
19
|
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
12
|
-
puts "make sure sidekiq is started with skjob.rb as the job"
|
20
|
+
puts "make sure sidekiq is started with skjob.rb as the job"
|
13
21
|
bench("enqueuing sidekiq jobs", count) do |i|
|
14
22
|
SidekiqJob.perform_async(count, t, delay)
|
15
23
|
end
|
@@ -20,15 +28,15 @@ puts "Don't forget to check the sidekiq log for processing time conclusion"
|
|
20
28
|
###############
|
21
29
|
|
22
30
|
if env == "t" # threaded
|
23
|
-
# do nothing
|
31
|
+
# do nothing
|
24
32
|
elsif env == "a" # async
|
25
|
-
require
|
33
|
+
require "async/scheduler"
|
26
34
|
Fiber.set_scheduler Async::Scheduler.new
|
27
35
|
end
|
28
36
|
|
29
|
-
require
|
37
|
+
require "./uljob"
|
30
38
|
|
31
|
-
|
39
|
+
warn "litejob started in #{Litescheduler.backend} environment"
|
32
40
|
|
33
41
|
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
34
42
|
bench("enqueuing litejobs", count) do |i|
|
@@ -40,4 +48,3 @@ puts "Please wait for the benchmark to finish .."
|
|
40
48
|
Fiber.scheduler.run if env == "a"
|
41
49
|
|
42
50
|
sleep
|
43
|
-
|
data/bench/bench_queue.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require_relative
|
1
|
+
require "./bench"
|
2
|
+
require_relative "../lib/litestack"
|
3
3
|
|
4
4
|
count = 1000
|
5
5
|
|
6
|
-
q = Litequeue.new({path:
|
6
|
+
q = Litequeue.new({path: "../db/queue.db"})
|
7
7
|
|
8
8
|
bench("Litequeue enqueue", count) do |i|
|
9
9
|
q.push i.to_s
|
10
10
|
end
|
11
11
|
|
12
12
|
bench("Litequeue dequeue", count) do |i|
|
13
|
-
q.pop
|
13
|
+
q.pop
|
14
14
|
end
|
15
|
-
|
16
|
-
|
data/bench/rails_job.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "active_job"
|
2
2
|
|
3
3
|
class RailsJob < ActiveJob::Base
|
4
|
-
|
5
4
|
queue_as :default
|
6
5
|
|
7
6
|
@@count = 0
|
8
|
-
|
7
|
+
|
9
8
|
def perform(count, time)
|
10
|
-
#sleep 1
|
11
|
-
@@count += 1
|
12
|
-
if @@count == count
|
9
|
+
# sleep 1
|
10
|
+
@@count += 1
|
11
|
+
if @@count == count
|
13
12
|
puts "[litejob] Finished in #{Time.now.to_f - time} seconds (#{count / (Time.now.to_f - time)} jps)"
|
14
13
|
@@count = 0
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
data/bench/skjob.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "sidekiq"
|
2
2
|
|
3
3
|
class SidekiqJob
|
4
4
|
include Sidekiq::Job
|
5
5
|
@@count = 0
|
6
6
|
def perform(count, time, sleep_interval = nil)
|
7
|
-
sleep sleep_interval if sleep_interval
|
7
|
+
sleep sleep_interval if sleep_interval
|
8
8
|
@@count += 1
|
9
|
-
if @@count == count
|
9
|
+
if @@count == count
|
10
10
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
11
|
-
|
11
|
+
warn "Sidekiq finished in #{now - time} seconds (#{count / (now - time)} jps)"
|
12
12
|
@@count = 0
|
13
13
|
end
|
14
14
|
end
|
data/bench/uljob.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "./bench"
|
2
|
+
require "../lib/litestack/litejob"
|
3
3
|
|
4
4
|
class MyJob
|
5
5
|
include Litejob
|
6
6
|
@@count = 0
|
7
|
-
#self.queue = :default
|
7
|
+
# self.queue = :default
|
8
8
|
def perform(count, time, sleep_interval = nil)
|
9
|
-
sleep sleep_interval if sleep_interval
|
9
|
+
sleep sleep_interval if sleep_interval
|
10
10
|
@@count += 1
|
11
|
-
if @@count == count
|
11
|
+
if @@count == count
|
12
12
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
13
|
-
|
13
|
+
warn "Litejob finished in #{now - time} seconds (#{count / (now - time)} jps)"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -1,26 +1,23 @@
|
|
1
1
|
# frozen_stringe_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../../litestack/litecable"
|
4
4
|
|
5
5
|
module ActionCable
|
6
6
|
module SubscriptionAdapter
|
7
|
-
class Litecable < ::Litecable# :nodoc:
|
8
|
-
|
7
|
+
class Litecable < ::Litecable # :nodoc:
|
9
8
|
attr_reader :logger, :server
|
10
|
-
|
9
|
+
|
11
10
|
prepend ChannelPrefix
|
12
11
|
|
13
|
-
def initialize(server, logger=nil)
|
12
|
+
def initialize(server, logger = nil)
|
14
13
|
@server = server
|
15
14
|
@logger = server.logger
|
16
15
|
super({config_path: "./config/litecable.yml"})
|
17
16
|
end
|
18
|
-
|
17
|
+
|
19
18
|
def shutdown
|
20
19
|
close
|
21
20
|
end
|
22
|
-
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
26
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "../../litestack/litejob"
|
4
4
|
require "active_support/core_ext/enumerable"
|
5
5
|
require "active_support/core_ext/array/access"
|
6
6
|
require "active_job"
|
@@ -12,13 +12,12 @@ module ActiveJob
|
|
12
12
|
#
|
13
13
|
# Rails.application.config.active_job.queue_adapter = :litejob
|
14
14
|
class LitejobAdapter
|
15
|
-
|
16
|
-
def initialize(options={})
|
15
|
+
def initialize(options = {})
|
17
16
|
# we currently don't honour individual options per job class
|
18
17
|
# possible in the future?
|
19
18
|
# Job.options = DEFAULT_OPTIONS.merge(options)
|
20
19
|
end
|
21
|
-
|
20
|
+
|
22
21
|
def enqueue(job) # :nodoc:
|
23
22
|
Job.queue = job.queue_name
|
24
23
|
Job.perform_async(job.serialize)
|
@@ -30,14 +29,13 @@ module ActiveJob
|
|
30
29
|
end
|
31
30
|
|
32
31
|
class Job # :nodoc:
|
33
|
-
|
34
32
|
DEFAULT_OPTIONS = {
|
35
33
|
config_path: "./config/litejob.yml",
|
36
|
-
logger: nil
|
37
|
-
}
|
34
|
+
logger: nil # Rails performs its logging already
|
35
|
+
}
|
38
36
|
|
39
37
|
include ::Litejob
|
40
|
-
|
38
|
+
|
41
39
|
def perform(job_data)
|
42
40
|
Base.execute job_data
|
43
41
|
end
|
@@ -1,54 +1,47 @@
|
|
1
|
-
require_relative
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require_relative "../../litestack/litedb"
|
2
|
+
require "active_record"
|
3
|
+
require "active_record/connection_adapters/sqlite3_adapter"
|
4
|
+
require "active_record/tasks/sqlite_database_tasks"
|
5
5
|
|
6
6
|
module ActiveRecord
|
7
|
+
module ConnectionHandling # :nodoc:
|
8
|
+
def litedb_connection(config)
|
9
|
+
config = config.symbolize_keys
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
config = config.symbolize_keys
|
13
|
-
|
14
|
-
# Require database.
|
15
|
-
unless config[:database]
|
16
|
-
raise ArgumentError, "No database file specified. Missing argument: database"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Allow database path relative to Rails.root, but only if the database
|
20
|
-
# path is not the special path that tells sqlite to build a database only
|
21
|
-
# in memory.
|
22
|
-
if ":memory:" != config[:database] && !config[:database].to_s.start_with?("file:")
|
23
|
-
config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
|
24
|
-
dirname = File.dirname(config[:database])
|
25
|
-
Dir.mkdir(dirname) unless File.directory?(dirname)
|
26
|
-
end
|
27
|
-
|
28
|
-
db = ::Litedb.new(
|
29
|
-
config[:database].to_s,
|
30
|
-
config.merge(results_as_hash: true)
|
31
|
-
)
|
11
|
+
# Require database.
|
12
|
+
unless config[:database]
|
13
|
+
raise ArgumentError, "No database file specified. Missing argument: database"
|
14
|
+
end
|
32
15
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
16
|
+
# Allow database path relative to Rails.root, but only if the database
|
17
|
+
# path is not the special path that tells sqlite to build a database only
|
18
|
+
# in memory.
|
19
|
+
if config[:database] != ":memory:" && !config[:database].to_s.start_with?("file:")
|
20
|
+
config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
|
21
|
+
dirname = File.dirname(config[:database])
|
22
|
+
Dir.mkdir(dirname) unless File.directory?(dirname)
|
23
|
+
end
|
43
24
|
|
44
|
-
|
25
|
+
db = ::Litedb.new(
|
26
|
+
config[:database].to_s,
|
27
|
+
config.merge(results_as_hash: true)
|
28
|
+
)
|
29
|
+
|
30
|
+
ConnectionAdapters::LitedbAdapter.new(db, logger, nil, config)
|
31
|
+
rescue Errno::ENOENT => error
|
32
|
+
if error.message.include?("No such file or directory")
|
33
|
+
raise ActiveRecord::NoDatabaseError
|
34
|
+
else
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
45
39
|
|
46
|
-
|
40
|
+
module ConnectionAdapters # :nodoc:
|
41
|
+
class LitedbAdapter < SQLite3Adapter
|
42
|
+
ADAPTER_NAME = "litedb"
|
47
43
|
|
48
|
-
ADAPTER_NAME = "litedb"
|
49
|
-
|
50
44
|
class << self
|
51
|
-
|
52
45
|
def dbconsole(config, options = {})
|
53
46
|
args = []
|
54
47
|
|
@@ -58,45 +51,42 @@ module ActiveRecord
|
|
58
51
|
|
59
52
|
find_cmd_and_exec("sqlite3", *args)
|
60
53
|
end
|
61
|
-
|
62
54
|
end
|
63
55
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
56
|
+
NATIVE_DATABASE_TYPES = {
|
57
|
+
primary_key: "integer PRIMARY KEY NOT NULL",
|
58
|
+
string: {name: "text"},
|
59
|
+
text: {name: "text"},
|
60
|
+
integer: {name: "integer"},
|
61
|
+
float: {name: "real"},
|
62
|
+
decimal: {name: "real"},
|
63
|
+
datetime: {name: "text"},
|
64
|
+
time: {name: "integer"},
|
65
|
+
date: {name: "text"},
|
66
|
+
binary: {name: "blob"},
|
67
|
+
boolean: {name: "integer"},
|
68
|
+
json: {name: "text"},
|
69
|
+
unixtime: {name: "integer"}
|
70
|
+
}
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def connect
|
75
|
+
@raw_connection = ::Litedb.new(
|
76
|
+
@config[:database].to_s,
|
77
|
+
@config.merge(results_as_hash: true)
|
78
|
+
)
|
79
|
+
configure_connection
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
90
83
|
|
91
|
-
end
|
92
|
-
|
93
84
|
module Tasks # :nodoc:
|
94
85
|
class LitedbDatabaseTasks < SQLiteDatabaseTasks # :nodoc:
|
95
86
|
end
|
96
|
-
|
87
|
+
|
97
88
|
module DatabaseTasks
|
98
89
|
register_task(/litedb/, "ActiveRecord::Tasks::LitedbDatabaseTasks")
|
99
|
-
|
100
90
|
end
|
101
|
-
|
91
|
+
end
|
102
92
|
end
|
@@ -3,23 +3,21 @@ require "active_support/core_ext/enumerable"
|
|
3
3
|
require "active_support/core_ext/array/extract_options"
|
4
4
|
require "active_support/core_ext/numeric/time"
|
5
5
|
require "active_support/cache"
|
6
|
-
require_relative
|
7
|
-
|
6
|
+
require_relative "../../litestack/litecache"
|
8
7
|
|
9
8
|
module ActiveSupport
|
10
9
|
module Cache
|
11
10
|
class Litecache < Store
|
12
|
-
|
13
11
|
prepend Strategy::LocalCache
|
14
|
-
|
12
|
+
|
15
13
|
def self.supports_cache_versioning?
|
16
14
|
true
|
17
15
|
end
|
18
16
|
|
19
|
-
def initialize(options={})
|
17
|
+
def initialize(options = {})
|
20
18
|
super
|
21
19
|
@options[:return_full_record] = true
|
22
|
-
|
20
|
+
@cache = ::Litecache.new(@options) # reachout to the outer litecache class
|
23
21
|
end
|
24
22
|
|
25
23
|
def increment(key, amount = 1, options = nil)
|
@@ -27,39 +25,39 @@ module ActiveSupport
|
|
27
25
|
options = merged_options(options)
|
28
26
|
# todo: fix me
|
29
27
|
# this is currently a hack to avoid dealing with Rails cache encoding and decoding
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#end
|
28
|
+
# @cache.transaction(:immediate) do
|
29
|
+
if (value = read(key, options))
|
30
|
+
value = value.to_i + amount
|
31
|
+
write(key, value, options)
|
32
|
+
end
|
33
|
+
# end
|
36
34
|
end
|
37
35
|
|
38
36
|
def decrement(key, amount = 1, options = nil)
|
39
37
|
options = merged_options(options)
|
40
38
|
increment(key, -1 * amount, options[:expires_in])
|
41
39
|
end
|
42
|
-
|
40
|
+
|
43
41
|
def prune(limit = nil, time = nil)
|
44
42
|
@cache.prune(limit)
|
45
43
|
end
|
46
44
|
|
47
45
|
def cleanup(limit = nil, time = nil)
|
48
46
|
@cache.prune(limit)
|
49
|
-
end
|
47
|
+
end
|
50
48
|
|
51
|
-
def clear
|
52
|
-
|
49
|
+
def clear
|
50
|
+
@cache.clear
|
53
51
|
end
|
54
|
-
|
52
|
+
|
55
53
|
def count
|
56
54
|
@cache.count
|
57
55
|
end
|
58
|
-
|
56
|
+
|
59
57
|
def size
|
60
58
|
@cache.size
|
61
59
|
end
|
62
|
-
|
60
|
+
|
63
61
|
def max_size
|
64
62
|
@cache.max_size
|
65
63
|
end
|
@@ -70,33 +68,32 @@ module ActiveSupport
|
|
70
68
|
|
71
69
|
private
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
# Read an entry from the cache.
|
72
|
+
def read_entry(key, **options)
|
73
|
+
deserialize_entry(@cache.get(key))
|
74
|
+
end
|
77
75
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
# Write an entry to the cache.
|
77
|
+
def write_entry(key, entry, **options)
|
78
|
+
write_serialized_entry(key, serialize_entry(entry, **options), **options)
|
79
|
+
end
|
82
80
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
if options[:unless_exist]
|
89
|
-
@cache.set_unless_exists(key, payload, expires_in)
|
90
|
-
else
|
91
|
-
@cache.set(key, payload, expires_in)
|
92
|
-
end
|
81
|
+
def write_serialized_entry(key, payload, **options)
|
82
|
+
expires_in = options[:expires_in].to_i
|
83
|
+
if options[:race_condition_ttl] && expires_in > 0 && !options[:raw]
|
84
|
+
expires_in += 5.minutes
|
93
85
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
86
|
+
if options[:unless_exist]
|
87
|
+
@cache.set_unless_exists(key, payload, expires_in)
|
88
|
+
else
|
89
|
+
@cache.set(key, payload, expires_in)
|
98
90
|
end
|
91
|
+
end
|
99
92
|
|
93
|
+
# Delete an entry from the cache.
|
94
|
+
def delete_entry(key, **options)
|
95
|
+
@cache.delete(key)
|
96
|
+
end
|
100
97
|
end
|
101
98
|
end
|
102
99
|
end
|
@@ -27,9 +27,9 @@ class Litestack::InstallGenerator < Rails::Generators::Base
|
|
27
27
|
def modify_gitignore
|
28
28
|
append_file ".gitignore", <<~TEXT
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# Ignore default Litestack SQLite databases.
|
31
|
+
/db/**/*.sqlite3
|
32
|
+
/db/**/*.sqlite3-*
|
33
33
|
TEXT
|
34
34
|
end
|
35
35
|
end
|
@@ -7,6 +7,9 @@
|
|
7
7
|
# `Litesupport.root.join("data.sqlite3")` stores
|
8
8
|
# application data in the path `./db/#{Rails.env}/data.sqlite3`
|
9
9
|
#
|
10
|
+
# `Litesupport.root(env).join(path)` stores
|
11
|
+
# application data in the path `./db/#{env}/#{path}`
|
12
|
+
#
|
10
13
|
# idle_timeout should be set to zero, to avoid recycling sqlite connections
|
11
14
|
# and losing the page cache
|
12
15
|
#
|
@@ -14,16 +17,17 @@ default: &default
|
|
14
17
|
adapter: litedb
|
15
18
|
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
16
19
|
idle_timeout: 0
|
17
|
-
database: <%= Litesupport.root.join("data.sqlite3") %>
|
18
20
|
|
19
21
|
development:
|
20
22
|
<<: *default
|
23
|
+
database: <%= Litesupport.root("development").join("data.sqlite3") %>
|
21
24
|
|
22
25
|
# Warning: The database defined as "test" will be erased and
|
23
26
|
# re-generated from your development database when you run "rake".
|
24
27
|
# Do not set this db to the same as development or production.
|
25
28
|
test:
|
26
29
|
<<: *default
|
30
|
+
database: <%= Litesupport.root("test").join("data.sqlite3") %>
|
27
31
|
|
28
32
|
# Warning: Make sure your production database path is on a persistent
|
29
33
|
# volume, otherwise your application data could be deleted between deploys.
|
@@ -32,3 +36,5 @@ test:
|
|
32
36
|
# `LITESTACK_DATA_PATH` environment variable.
|
33
37
|
production:
|
34
38
|
<<: *default
|
39
|
+
database: <%= Litesupport.root("production").join("data.sqlite3") %>
|
40
|
+
|