tartarus-rb 0.1.0
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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Changelog.md +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +59 -0
- data/LICENSE.txt +21 -0
- data/README.md +98 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/tartarus-rb.rb +1 -0
- data/lib/tartarus.rb +44 -0
- data/lib/tartarus/archivable_collection_repository.rb +35 -0
- data/lib/tartarus/archivable_item.rb +71 -0
- data/lib/tartarus/archivable_item/sidekiq_cron_job_serializer.rb +27 -0
- data/lib/tartarus/archive_model_with_tenant.rb +26 -0
- data/lib/tartarus/archive_model_without_tenant.rb +25 -0
- data/lib/tartarus/archive_strategy.rb +12 -0
- data/lib/tartarus/archive_strategy/delete_all.rb +9 -0
- data/lib/tartarus/archive_strategy/destroy_all.rb +9 -0
- data/lib/tartarus/rb.rb +1 -0
- data/lib/tartarus/rb/version.rb +5 -0
- data/lib/tartarus/registry.rb +26 -0
- data/lib/tartarus/repository.rb +26 -0
- data/lib/tartarus/schedule_archiving_model.rb +38 -0
- data/lib/tartarus/sidekiq.rb +2 -0
- data/lib/tartarus/sidekiq/archive_model_with_tenant_job.rb +11 -0
- data/lib/tartarus/sidekiq/archive_model_without_tenant_job.rb +11 -0
- data/lib/tartarus/sidekiq/schedule_archiving_model_job.rb +11 -0
- data/tartarus-rb.gemspec +36 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ff59ebb52771abf8d4f7725d842592c3b5cb9c62e9a2dd263bdce6e4ef433fdf
|
4
|
+
data.tar.gz: a34ed59c2f0d5fd405e1b55a8537cd91d10f55782e4884c22fc327dfa5eca324
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 76f1a2a3567fb8eaacdf244c0ced23d41ac8eb98a5a52e3ce83a48c0650ac6ad0156947665611401d70598502bd4c7ede9c4b4e8729a052c69122260a99c7a0b
|
7
|
+
data.tar.gz: 0a985afc6e833ef31f08a70b3e4f4479c47b2763ce9266e77eafe6a47cf639d2ae47485a662f71bc8b1fcc09909a7682581aef39a3b93628b183769ad2a8f990
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Changelog.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tartarus-rb (0.1.0)
|
5
|
+
sidekiq (>= 5)
|
6
|
+
sidekiq-cron (~> 1)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
concurrent-ruby (1.1.7)
|
12
|
+
connection_pool (2.2.3)
|
13
|
+
diff-lcs (1.4.4)
|
14
|
+
et-orbi (1.2.4)
|
15
|
+
tzinfo
|
16
|
+
fugit (1.3.9)
|
17
|
+
et-orbi (~> 1.1, >= 1.1.8)
|
18
|
+
raabro (~> 1.3)
|
19
|
+
raabro (1.4.0)
|
20
|
+
rack (2.2.3)
|
21
|
+
rake (13.0.1)
|
22
|
+
redis (4.2.2)
|
23
|
+
rspec (3.9.0)
|
24
|
+
rspec-core (~> 3.9.0)
|
25
|
+
rspec-expectations (~> 3.9.0)
|
26
|
+
rspec-mocks (~> 3.9.0)
|
27
|
+
rspec-core (3.9.3)
|
28
|
+
rspec-support (~> 3.9.3)
|
29
|
+
rspec-expectations (3.9.2)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.9.0)
|
32
|
+
rspec-mocks (3.9.1)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.9.0)
|
35
|
+
rspec-sidekiq (3.1.0)
|
36
|
+
rspec-core (~> 3.0, >= 3.0.0)
|
37
|
+
sidekiq (>= 2.4.0)
|
38
|
+
rspec-support (3.9.3)
|
39
|
+
sidekiq (6.1.2)
|
40
|
+
connection_pool (>= 2.2.2)
|
41
|
+
rack (~> 2.0)
|
42
|
+
redis (>= 4.2.0)
|
43
|
+
sidekiq-cron (1.2.0)
|
44
|
+
fugit (~> 1.1)
|
45
|
+
sidekiq (>= 4.2.1)
|
46
|
+
tzinfo (2.0.2)
|
47
|
+
concurrent-ruby (~> 1.0)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
rake (~> 13.0)
|
54
|
+
rspec (~> 3.0)
|
55
|
+
rspec-sidekiq
|
56
|
+
tartarus-rb!
|
57
|
+
|
58
|
+
BUNDLED WITH
|
59
|
+
2.1.4
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Karol Galanciak
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Tartarus::Rb
|
2
|
+
|
3
|
+
A gem for archiving (deleting) old records you no longer need. Send them straight to tartarus!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'tartarus-rb'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install tartarus-rb
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
This game is based on sidekiq-cron, which means you can manage (e.g. disable/enable) jobs from sidekiq-cron UI.
|
24
|
+
|
25
|
+
Here are some examples how to use it
|
26
|
+
|
27
|
+
Put it in the initializer, e.g. in `config/initializers/sidekiq.rb` right after loading schedule for `sidekiq-cron`:
|
28
|
+
|
29
|
+
``` rb
|
30
|
+
schedule_file = "config/schedule.yml"
|
31
|
+
|
32
|
+
if File.exist?(schedule_file) && Sidekiq.server?
|
33
|
+
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
|
34
|
+
|
35
|
+
tartarus = Tartarus.new
|
36
|
+
|
37
|
+
tartarus.register do |item|
|
38
|
+
item.model = ModelThatYouWantToArchive
|
39
|
+
item.cron = "5 4 * * *"
|
40
|
+
item.queue = "default"
|
41
|
+
item.tenants_range = -> { Account.active }
|
42
|
+
item.tenant_value_source = :uuid
|
43
|
+
item.tenant_id_field = :account_uuid
|
44
|
+
item.archive_items_older_than = -> { 30.days.ago }
|
45
|
+
item.timestamp_field = :created_at
|
46
|
+
end
|
47
|
+
|
48
|
+
tartarus.register do |item|
|
49
|
+
item.model = OtherModelThatYouWantToArchive
|
50
|
+
item.cron = "5 5 * * *"
|
51
|
+
item.queue = "default"
|
52
|
+
item.tenants_range = -> { ["Account", "User"] }
|
53
|
+
item.tenant_id_field = :model_type
|
54
|
+
item.archive_items_older_than = -> { 30.days.ago }
|
55
|
+
item.timestamp_field = :created_at
|
56
|
+
end
|
57
|
+
|
58
|
+
tartarus.register do |item|
|
59
|
+
item.model = YetAnotherModel
|
60
|
+
item.cron = "5 6 * * *"
|
61
|
+
item.queue = "default"
|
62
|
+
item.timestamp_field = :created_at
|
63
|
+
item.archive_items_older_than = -> { 1.week.ago }
|
64
|
+
end
|
65
|
+
|
66
|
+
tartarus.schedule # this method must be called to create jobs for sidekiq-cron!
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
|
71
|
+
You can use the following config params:
|
72
|
+
- `model` - a name of the ActiveReord model you want to archive, required
|
73
|
+
- `cron` - cron syntax, required
|
74
|
+
- `queue` - name of the sidekiq queue you want to use for execution of the jobs, required
|
75
|
+
- `tenants_range` - optional, use if you want to scope items by a tenant (or any field that can be used for partitioning). It doesn't have to be ActiveRecord collection, could be just an array. Must be a proc/lambda/object responding to `call` method. For ActvieRecord collection, `find_each` loop will be used for optimization.
|
76
|
+
- `tenant_value_source` - optional but required if you want to have scoping by tenant/partitioning field. Specifying `:uuid` here means that ModelThatYouWantToArchive collection will be scheduled for archiving by uuid of each Account. It defaults to `id`.
|
77
|
+
- `tenant_id_field` - required when using tenant_value_source/tenant_value_source. It's a DB column that will be used for scoping records by a tenant. For example, here it would be: `ModelThatYouWantToArchive.where(account_uuid: value_of_uuid_from_some_active_account)`
|
78
|
+
- `archive_items_older_than` - required, for defining retention policy
|
79
|
+
- `timestamp_field` - required, used for performing a query using the value from `archive_items_older_than`
|
80
|
+
|
81
|
+
## Development
|
82
|
+
|
83
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
84
|
+
|
85
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
86
|
+
|
87
|
+
## TODO
|
88
|
+
|
89
|
+
- add support for uploading archives to AWS Glacier before deleting items
|
90
|
+
|
91
|
+
## Contributing
|
92
|
+
|
93
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tartarus-rb.
|
94
|
+
|
95
|
+
|
96
|
+
## License
|
97
|
+
|
98
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "tartarus/rb"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/tartarus-rb.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "tartarus"
|
data/lib/tartarus.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "tartarus/archivable_collection_repository"
|
2
|
+
require "tartarus/archivable_item"
|
3
|
+
require "tartarus/archivable_item/sidekiq_cron_job_serializer"
|
4
|
+
require "tartarus/archive_strategy"
|
5
|
+
require "tartarus/archive_strategy/delete_all"
|
6
|
+
require "tartarus/archive_strategy/destroy_all"
|
7
|
+
require "tartarus/sidekiq"
|
8
|
+
require "tartarus/sidekiq/archive_model_with_tenant_job"
|
9
|
+
require "tartarus/sidekiq/archive_model_without_tenant_job"
|
10
|
+
require "tartarus/sidekiq/schedule_archiving_model_job"
|
11
|
+
require "tartarus/archive_model_with_tenant"
|
12
|
+
require "tartarus/archive_model_without_tenant"
|
13
|
+
require "tartarus/rb/version"
|
14
|
+
require "tartarus/registry"
|
15
|
+
require "tartarus/repository"
|
16
|
+
require "tartarus/schedule_archiving_model"
|
17
|
+
require "sidekiq/cron/job"
|
18
|
+
require "sidekiq"
|
19
|
+
|
20
|
+
class Tartarus
|
21
|
+
attr_reader :registry, :repository
|
22
|
+
private :registry, :repository
|
23
|
+
|
24
|
+
def self.registry
|
25
|
+
@registry ||= Tartarus::Registry.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(repository: Tartarus::Repository.new(backend: ::Sidekiq::Cron::Job))
|
29
|
+
@repository = repository
|
30
|
+
@registry = self.class.registry
|
31
|
+
end
|
32
|
+
|
33
|
+
def register
|
34
|
+
item = Tartarus::ArchivableItem.new
|
35
|
+
yield item
|
36
|
+
item.validate!
|
37
|
+
|
38
|
+
registry.register(item)
|
39
|
+
end
|
40
|
+
|
41
|
+
def schedule
|
42
|
+
registry.each { |item| repository.save(item) }
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Tartarus
|
2
|
+
class ArchivableCollectionRepository
|
3
|
+
attr_reader :const_resolver
|
4
|
+
private :const_resolver
|
5
|
+
|
6
|
+
def initialize(const_resolver: Object)
|
7
|
+
@const_resolver = const_resolver
|
8
|
+
end
|
9
|
+
|
10
|
+
def items_older_than_for_tenant(model_name, timestamp_field, timestamp, tenant_id_field, tenant_id)
|
11
|
+
collection = collection_for(model_name)
|
12
|
+
ensure_column_exists(collection, model_name, timestamp_field)
|
13
|
+
ensure_column_exists(collection, model_name, tenant_id_field)
|
14
|
+
|
15
|
+
collection.where("#{timestamp_field} < ?", timestamp).where(tenant_id_field => tenant_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def items_older_than(model_name, timestamp_field, timestamp)
|
19
|
+
collection = collection_for(model_name)
|
20
|
+
ensure_column_exists(collection, model_name, timestamp_field)
|
21
|
+
|
22
|
+
collection.where("#{timestamp_field} < ?", timestamp)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def collection_for(model_name)
|
28
|
+
const_resolver.const_get(model_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def ensure_column_exists(collection, model_name, column)
|
32
|
+
collection.column_names.include?(column.to_s) or raise "column :#{column} does not exist for #{model_name}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Tartarus::ArchivableItem
|
2
|
+
REQUIRED_ATTRIBUTES_NAMES = %i(model cron queue archive_items_older_than timestamp_field active_job
|
3
|
+
archive_with tenant_value_source).freeze
|
4
|
+
OPTIONAL_ATTRIBUTES_NAMES = %i(tenants_range tenant_id_field).freeze
|
5
|
+
|
6
|
+
attr_accessor *(REQUIRED_ATTRIBUTES_NAMES + OPTIONAL_ATTRIBUTES_NAMES)
|
7
|
+
|
8
|
+
def cron=(value)
|
9
|
+
Fugit.do_parse_cron(value)
|
10
|
+
|
11
|
+
@cron = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def archive_items_older_than=(value)
|
15
|
+
raise ":archive_items_older_than must be a lambda" if !value.respond_to?(:call)
|
16
|
+
|
17
|
+
@archive_items_older_than = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def tenants_range=(value)
|
21
|
+
raise ":tenants_range must be a lambda" if !value.respond_to?(:call)
|
22
|
+
|
23
|
+
@tenants_range = value
|
24
|
+
end
|
25
|
+
|
26
|
+
def tenants_range
|
27
|
+
return @tenants_range if defined?(@tenants_range)
|
28
|
+
|
29
|
+
@tenants_range ||= -> { [] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def tenant_value_source
|
33
|
+
return @tenant_value_source if defined?(@tenant_value_source)
|
34
|
+
|
35
|
+
@tenant_value_source ||= :id
|
36
|
+
end
|
37
|
+
|
38
|
+
def active_job
|
39
|
+
@active_job || false
|
40
|
+
end
|
41
|
+
|
42
|
+
def archive_with
|
43
|
+
return @archive_with if defined?(@archive_with)
|
44
|
+
|
45
|
+
@archive_with ||= :delete_all
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate!
|
49
|
+
validate_presence
|
50
|
+
end
|
51
|
+
|
52
|
+
def scope_by_tenant?
|
53
|
+
!!tenant_id_field
|
54
|
+
end
|
55
|
+
|
56
|
+
def archive_strategy(factory: Tartarus::ArchiveStrategy.new)
|
57
|
+
factory.for(archive_with)
|
58
|
+
end
|
59
|
+
|
60
|
+
def for_model?(provided_model_name)
|
61
|
+
model.to_s == provided_model_name.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def validate_presence
|
67
|
+
REQUIRED_ATTRIBUTES_NAMES.each do |attribute|
|
68
|
+
raise ":#{attribute} must be present" if public_send(attribute).nil?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Tartarus
|
2
|
+
class ArchivableItem
|
3
|
+
class SidekiqCronJobSerializer
|
4
|
+
def serialize(archivable_item)
|
5
|
+
{
|
6
|
+
name: name_for_item(archivable_item),
|
7
|
+
description: description_for_item(archivable_item),
|
8
|
+
cron: archivable_item.cron,
|
9
|
+
class: Tartarus::Sidekiq::ScheduleArchivingModelJob,
|
10
|
+
args: [archivable_item.model],
|
11
|
+
queue: archivable_item.queue,
|
12
|
+
active_job: archivable_item.active_job
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def name_for_item(archivable_item)
|
19
|
+
"TARTARUS_#{archivable_item.model}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def description_for_item(archivable_item)
|
23
|
+
"[TARTARUS] Archiving Job for model: #{archivable_item.model}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Tartarus::ArchiveModelWithTenant
|
2
|
+
attr_reader :registry, :repository
|
3
|
+
private :registry, :repository
|
4
|
+
|
5
|
+
def initialize(registry: Tartarus.registry, repository: Tartarus::ArchivableCollectionRepository.new)
|
6
|
+
@registry = registry
|
7
|
+
@repository = repository
|
8
|
+
end
|
9
|
+
|
10
|
+
def archive(model_name, tenant_id)
|
11
|
+
archivable_item = registry.find_by_model(model_name)
|
12
|
+
|
13
|
+
archivable_item.archive_strategy.call(collection_to_archive(model_name, archivable_item, tenant_id))
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def collection_to_archive(model_name, archivable_item, tenant_id)
|
19
|
+
repository
|
20
|
+
.items_older_than_for_tenant(
|
21
|
+
model_name,
|
22
|
+
archivable_item.timestamp_field, archivable_item.archive_items_older_than.call,
|
23
|
+
archivable_item.tenant_id_field, tenant_id
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Tartarus::ArchiveModelWithoutTenant
|
2
|
+
attr_reader :registry, :repository
|
3
|
+
private :registry, :repository
|
4
|
+
|
5
|
+
def initialize(registry: Tartarus.registry, repository: Tartarus::ArchivableCollectionRepository.new)
|
6
|
+
@registry = registry
|
7
|
+
@repository = repository
|
8
|
+
end
|
9
|
+
|
10
|
+
def archive(model_name)
|
11
|
+
archivable_item = registry.find_by_model(model_name)
|
12
|
+
|
13
|
+
archivable_item.archive_strategy.call(collection_to_archive(model_name, archivable_item))
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def collection_to_archive(model_name, archivable_item)
|
19
|
+
repository
|
20
|
+
.items_older_than(
|
21
|
+
model_name,
|
22
|
+
archivable_item.timestamp_field, archivable_item.archive_items_older_than.call
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Tartarus::ArchiveStrategy
|
2
|
+
def for(strategy_name)
|
3
|
+
case strategy_name.to_sym
|
4
|
+
when :delete_all
|
5
|
+
Tartarus::ArchiveStrategy::DeleteAll.new
|
6
|
+
when :destroy_all
|
7
|
+
Tartarus::ArchiveStrategy::DestroyAll.new
|
8
|
+
else
|
9
|
+
raise "unknown strategy: #{strategy_name}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/tartarus/rb.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "../tartarus.rb"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
class Tartarus::Registry
|
4
|
+
attr_reader :storage
|
5
|
+
private :storage
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :storage, :size, :each
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
reset
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(item)
|
16
|
+
@storage << item
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_by_model(model)
|
20
|
+
storage.find(->{ raise "#{model} not found in registry" }) { |item| item.for_model?(model) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset
|
24
|
+
@storage = Concurrent::Array.new
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Tartarus::Repository
|
2
|
+
attr_reader :backend, :serializer
|
3
|
+
private :backend, :serializer
|
4
|
+
|
5
|
+
def initialize(backend: Sidekiq::Cron::Job, serializer: Tartarus::ArchivableItem::SidekiqCronJobSerializer.new)
|
6
|
+
@backend = backend
|
7
|
+
@serializer = serializer
|
8
|
+
end
|
9
|
+
|
10
|
+
def save(archivable_item)
|
11
|
+
backend.new(serializer.serialize(archivable_item)).tap do |job|
|
12
|
+
if job.valid?
|
13
|
+
job.save
|
14
|
+
else
|
15
|
+
raise_invalid_job(job)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def raise_invalid_job(job)
|
23
|
+
errors = job.errors.join(",")
|
24
|
+
raise "could not save job: #{errors}"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Tartarus::ScheduleArchivingModel
|
2
|
+
attr_reader :registry
|
3
|
+
private :registry
|
4
|
+
|
5
|
+
def initialize(registry: Tartarus.registry)
|
6
|
+
@registry = registry
|
7
|
+
end
|
8
|
+
|
9
|
+
def schedule(model_name)
|
10
|
+
archivable_item = registry.find_by_model(model_name)
|
11
|
+
|
12
|
+
if archivable_item.scope_by_tenant?
|
13
|
+
each_tenant(archivable_item) do |tenant|
|
14
|
+
enqueue(Tartarus::Sidekiq::ArchiveModelWithTenantJob, archivable_item.queue, model_name, tenant)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
enqueue(Tartarus::Sidekiq::ArchiveModelWithoutTenantJob, archivable_item.queue, model_name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def each_tenant(archivable_item)
|
24
|
+
collection = archivable_item.tenants_range.call
|
25
|
+
|
26
|
+
if collection.respond_to?(:find_each)
|
27
|
+
archivable_item.tenants_range
|
28
|
+
.call
|
29
|
+
.find_each { |element| yield element.public_send(archivable_item.tenant_value_source) }
|
30
|
+
else
|
31
|
+
collection.each { |element| yield element }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def enqueue(job_class, queue, *args)
|
36
|
+
job_class.set(queue: queue).perform_async(*args)
|
37
|
+
end
|
38
|
+
end
|
data/tartarus-rb.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'lib/tartarus/rb/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "tartarus-rb"
|
5
|
+
spec.version = Tartarus::Rb::VERSION
|
6
|
+
spec.authors = ["Karol Galanciak"]
|
7
|
+
spec.email = ["karol.galanciak@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{A gem for archving (deleting) old records you no longer need. Send them straight to tartarus!}
|
10
|
+
spec.description = %q{A gem for archving (deleting) old records you no longer need. Send them straight to tartarus!}
|
11
|
+
spec.homepage = "https://github.com/BookingSync/tartarus-rb"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
19
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_dependency "sidekiq", ">= 5"
|
31
|
+
spec.add_dependency "sidekiq-cron", "~> 1"
|
32
|
+
|
33
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
+
spec.add_development_dependency "rspec-sidekiq"
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tartarus-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Karol Galanciak
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sidekiq
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sidekiq-cron
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-sidekiq
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A gem for archving (deleting) old records you no longer need. Send them
|
84
|
+
straight to tartarus!
|
85
|
+
email:
|
86
|
+
- karol.galanciak@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Changelog.md
|
95
|
+
- Gemfile
|
96
|
+
- Gemfile.lock
|
97
|
+
- LICENSE.txt
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- bin/console
|
101
|
+
- bin/setup
|
102
|
+
- lib/tartarus-rb.rb
|
103
|
+
- lib/tartarus.rb
|
104
|
+
- lib/tartarus/archivable_collection_repository.rb
|
105
|
+
- lib/tartarus/archivable_item.rb
|
106
|
+
- lib/tartarus/archivable_item/sidekiq_cron_job_serializer.rb
|
107
|
+
- lib/tartarus/archive_model_with_tenant.rb
|
108
|
+
- lib/tartarus/archive_model_without_tenant.rb
|
109
|
+
- lib/tartarus/archive_strategy.rb
|
110
|
+
- lib/tartarus/archive_strategy/delete_all.rb
|
111
|
+
- lib/tartarus/archive_strategy/destroy_all.rb
|
112
|
+
- lib/tartarus/rb.rb
|
113
|
+
- lib/tartarus/rb/version.rb
|
114
|
+
- lib/tartarus/registry.rb
|
115
|
+
- lib/tartarus/repository.rb
|
116
|
+
- lib/tartarus/schedule_archiving_model.rb
|
117
|
+
- lib/tartarus/sidekiq.rb
|
118
|
+
- lib/tartarus/sidekiq/archive_model_with_tenant_job.rb
|
119
|
+
- lib/tartarus/sidekiq/archive_model_without_tenant_job.rb
|
120
|
+
- lib/tartarus/sidekiq/schedule_archiving_model_job.rb
|
121
|
+
- tartarus-rb.gemspec
|
122
|
+
homepage: https://github.com/BookingSync/tartarus-rb
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
metadata:
|
126
|
+
homepage_uri: https://github.com/BookingSync/tartarus-rb
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 2.3.0
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubygems_version: 3.1.4
|
143
|
+
signing_key:
|
144
|
+
specification_version: 4
|
145
|
+
summary: A gem for archving (deleting) old records you no longer need. Send them straight
|
146
|
+
to tartarus!
|
147
|
+
test_files: []
|