tartarus-rb 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee9118a9365d2a74dd802218b0b0b36286c6494ecffe4f81cbf9bfed35597057
4
- data.tar.gz: f85ffe0e1f182667b5b9b522746a85b45cc9cd3452270f583549a0616d06337c
3
+ metadata.gz: d964cd9b85733405512f08d58cea33e9f12f5b6d3fa05d8fb2d1c979463ffead
4
+ data.tar.gz: 955301decdf77128432413afb6dd40612bb5c279e2cb65129f740cf1c81c1373
5
5
  SHA512:
6
- metadata.gz: '08e1ab969f1681fca948bdfb4ae98fb919e7caef4e95a1cf5a3a2dffc6fa79a59c73655927be759408f951ad0846ff5c1dea6b7396220801f31c179730e9d6e3'
7
- data.tar.gz: 72f485499631b46912293650672cd79e8df364ebbc7b18144731c1077e7fa8157be8b20e4078212b04dfb539a3de19af99abcca720163785c3132f51bf574968
6
+ metadata.gz: d455a12a6503b078c1b49e3902d840a017bfa50f99c6eee2ff17367d3398eb62b376503f84b260a90663e9c3f465ac59ba4509a1b3f9767835548853a24f3469
7
+ data.tar.gz: 2b4502ce62eb6bd831413d237e9b69535fbbe113c09e25e35f0ee680c902599bd0c52a210c0eb365ccde044c6a200da32c4b12798a6137e996a228f1192d8b10
data/Changelog.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Master
4
4
 
5
+ ## 0.6.0
6
+
7
+ - Optimize query from `Tartarus::ArchivableCollectionRepository#items_older_than` by adding explicit ordering
8
+
9
+ ## 0.5.0
10
+
11
+ - Provide ability to explicitly set the name of archivable item to have multiple ways of archiving the same model
12
+
13
+ ## 0.4.1
14
+
15
+ - Do not make Glacier a required dependency if not used
16
+
5
17
  ## 0.4.0
6
18
 
7
19
  - Add Glacier remote storage support to upload data before deleting it
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tartarus-rb (0.4.0)
5
- aws-sdk-glacier
4
+ tartarus-rb (0.6.0)
6
5
  sidekiq (>= 5)
7
6
  sidekiq-cron (~> 1)
8
7
 
@@ -58,7 +57,7 @@ GEM
58
57
  erubi (1.10.0)
59
58
  et-orbi (1.2.4)
60
59
  tzinfo
61
- fugit (1.4.2)
60
+ fugit (1.4.5)
62
61
  et-orbi (~> 1.1, >= 1.1.8)
63
62
  raabro (~> 1.4)
64
63
  hashdiff (1.0.0)
@@ -141,6 +140,7 @@ PLATFORMS
141
140
 
142
141
  DEPENDENCIES
143
142
  activerecord (~> 6)
143
+ aws-sdk-glacier
144
144
  dotenv
145
145
  pg
146
146
  postgres-copy
data/README.md CHANGED
@@ -64,6 +64,7 @@ if File.exist?(schedule_file) && Sidekiq.server?
64
64
  root_path: Rails.root.to_s,
65
65
  archive_registry_factory: ArchiveRegistry,
66
66
  )
67
+ # don't forget about installing `aws-sdk-glacier` gem
67
68
 
68
69
  tartarus.register do |item|
69
70
  item.model = YetAnotherModel
@@ -81,6 +82,31 @@ end
81
82
 
82
83
  You can use the following config params:
83
84
  - `model` - a name of the ActiveReord model you want to archive, required
85
+ - `name` - name of your strategy, optional. It fallbacks `model.to_s`. It's important to set in in cases when you have several strategies for the same model:
86
+ ```rb
87
+ tartarus.register do |item|
88
+ item.model = InternalEvent
89
+ item.name = "archive_account_and_user_internal_events"
90
+ item.cron = "5 5 * * *"
91
+ item.queue = "default"
92
+ item.tenants_range = -> { ["Account", "User"] }
93
+ item.tenant_id_field = :model_type
94
+ item.archive_items_older_than = -> { 30.days.ago }
95
+ item.timestamp_field = :created_at
96
+ end
97
+
98
+ tartarus.register do |item|
99
+ item.model = InternalEvent
100
+ item.name = "archive_post_and_comment_internal_events"
101
+ item.cron = "5 15 * * *"
102
+ item.queue = "default"
103
+ item.tenants_range = -> { ["Post", "Comment"] }
104
+ item.tenant_id_field = :model_type
105
+ item.archive_items_older_than = -> { 10.days.ago }
106
+ item.timestamp_field = :created_at
107
+ end
108
+ ```
109
+
84
110
  - `cron` - cron syntax, required
85
111
  - `queue` - name of the sidekiq queue you want to use for execution of the jobs, required
86
112
  - `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.
@@ -90,7 +116,7 @@ You can use the following config params:
90
116
  - `timestamp_field` - required, used for performing a query using the value from `archive_items_older_than`
91
117
  - `archive_with` - optional (defaults to `delete_all`). Could be `delete_all`, `destroy_all`, `delete_all_without_batches`, `destroy_all_without_batches`, `delete_all_using_limit_in_batches`
92
118
  - `batch_size` - optional (defaults to `10_000`, used with `delete_all_using_limit_in_batches` strategy)
93
- - `remote_storage` - optional (defaults to `Tartarus::RemoteStorage::Null` which does nothing). Use this option if you want store the data somewhere before deleting it.
119
+ - `remote_storage` - optional (defaults to `Tartarus::RemoteStorage::Null` which does nothing). Use this option if you want store the data somewhere before deleting it.
94
120
 
95
121
  ### Remote Storage
96
122
 
@@ -99,6 +125,7 @@ Currently, only `Glacier` (for AWS Glacier) is supported. Also, it works only wi
99
125
  To take advantage of this feature you will need a couple of things:
100
126
  1. Apply `acts_as_copy_target` to the archivable model (from `postgres-copy` gem).
101
127
  2. Create a model that will be used as a registry for all uploads that happened.
128
+ 3. Install `aws-sdk-glacier` gem.
102
129
 
103
130
  If you want to make `Version` model archivable and use `ArchiveRegistry` as the registry, you will need the following models and tables:
104
131
 
@@ -155,6 +182,9 @@ glacier_configuration = Tartarus::RemoteStorage::Glacier::Configuration.build(
155
182
  Tartarus::RemoteStorage::Glacier.new(glacier_configuration)
156
183
  ```
157
184
 
185
+ **Important** - do not use Glacier Storage for large batches (> 4 GB) as multipart uploads are not supported yet.
186
+
187
+
158
188
  If you know what you are doing, you can add your own storage, as long as it complies with the following interface:
159
189
 
160
190
  ``` rb
@@ -166,7 +196,7 @@ class Glacier
166
196
  @configuration = configuration
167
197
  end
168
198
 
169
- def store(collection, archivable_model, tenant_id: nil, tenant_id_field: nil)
199
+ def store(collection, archivable_model, tenant_id: nil, tenant_id_field: nil)
170
200
  end
171
201
  end
172
202
  ```
@@ -20,7 +20,7 @@ class Tartarus
20
20
  collection = collection_for(model_name)
21
21
  ensure_column_exists(collection, model_name, timestamp_field)
22
22
 
23
- collection.where("#{timestamp_field} < ?", timestamp)
23
+ collection.where("#{timestamp_field} < ?", timestamp).order(timestamp_field)
24
24
  end
25
25
 
26
26
  private
@@ -7,7 +7,7 @@ class Tartarus
7
7
  description: description_for_item(archivable_item),
8
8
  cron: archivable_item.cron,
9
9
  class: Tartarus::Sidekiq::ScheduleArchivingModelJob,
10
- args: [archivable_item.model],
10
+ args: [archivable_item.name],
11
11
  queue: archivable_item.queue,
12
12
  active_job: archivable_item.active_job
13
13
  }
@@ -16,7 +16,7 @@ class Tartarus
16
16
  private
17
17
 
18
18
  def name_for_item(archivable_item)
19
- "TARTARUS_#{archivable_item.model}"
19
+ "TARTARUS_#{archivable_item.name}"
20
20
  end
21
21
 
22
22
  def description_for_item(archivable_item)
@@ -1,7 +1,7 @@
1
1
  class Tartarus::ArchivableItem
2
2
  REQUIRED_ATTRIBUTES_NAMES = %i(model cron queue archive_items_older_than timestamp_field active_job
3
3
  archive_with tenant_value_source).freeze
4
- OPTIONAL_ATTRIBUTES_NAMES = %i(tenants_range tenant_id_field batch_size remote_storage).freeze
4
+ OPTIONAL_ATTRIBUTES_NAMES = %i(tenants_range tenant_id_field batch_size remote_storage name).freeze
5
5
 
6
6
  attr_accessor *(REQUIRED_ATTRIBUTES_NAMES + OPTIONAL_ATTRIBUTES_NAMES)
7
7
 
@@ -51,6 +51,10 @@ class Tartarus::ArchivableItem
51
51
  @batch_size ||= 10_000
52
52
  end
53
53
 
54
+ def name
55
+ @name || @model.to_s
56
+ end
57
+
54
58
  def validate!
55
59
  validate_presence
56
60
  end
@@ -63,10 +67,6 @@ class Tartarus::ArchivableItem
63
67
  factory.for(archive_with, batch_size: batch_size)
64
68
  end
65
69
 
66
- def for_model?(provided_model_name)
67
- model.to_s == provided_model_name.to_s
68
- end
69
-
70
70
  def remote_storage
71
71
  @remote_storage || Tartarus::RemoteStorage::Null
72
72
  end
@@ -7,20 +7,20 @@ class Tartarus::ArchiveModelWithTenant
7
7
  @repository = repository
8
8
  end
9
9
 
10
- def archive(model_name, tenant_id)
11
- archivable_item = registry.find_by_model(model_name)
12
- collection = collection_to_archive(model_name, archivable_item, tenant_id)
13
- archivable_item.remote_storage.store(collection, model_name, tenant_id: tenant_id,
10
+ def archive(archivable_item_name, tenant_id)
11
+ archivable_item = registry.find_by_name(archivable_item_name)
12
+ collection = collection_to_archive(archivable_item, tenant_id)
13
+ archivable_item.remote_storage.store(collection, archivable_item.name, tenant_id: tenant_id,
14
14
  tenant_id_field: archivable_item.tenant_id_field)
15
15
  archivable_item.archive_strategy.call(collection)
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def collection_to_archive(model_name, archivable_item, tenant_id)
20
+ def collection_to_archive(archivable_item, tenant_id)
21
21
  repository
22
22
  .items_older_than_for_tenant(
23
- model_name,
23
+ archivable_item.model,
24
24
  archivable_item.timestamp_field, archivable_item.archive_items_older_than.call,
25
25
  archivable_item.tenant_id_field, tenant_id
26
26
  )
@@ -7,19 +7,19 @@ class Tartarus::ArchiveModelWithoutTenant
7
7
  @repository = repository
8
8
  end
9
9
 
10
- def archive(model_name)
11
- archivable_item = registry.find_by_model(model_name)
12
- collection = collection_to_archive(model_name, archivable_item)
13
- archivable_item.remote_storage.store(collection, model_name)
10
+ def archive(archivable_item_name)
11
+ archivable_item = registry.find_by_name(archivable_item_name)
12
+ collection = collection_to_archive(archivable_item)
13
+ archivable_item.remote_storage.store(collection, archivable_item.name)
14
14
  archivable_item.archive_strategy.call(collection)
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def collection_to_archive(model_name, archivable_item)
19
+ def collection_to_archive(archivable_item)
20
20
  repository
21
21
  .items_older_than(
22
- model_name,
22
+ archivable_item.model,
23
23
  archivable_item.timestamp_field, archivable_item.archive_items_older_than.call
24
24
  )
25
25
  end
@@ -1,5 +1,5 @@
1
1
  class Tartarus
2
2
  module Rb
3
- VERSION = "0.4.0"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
@@ -16,8 +16,8 @@ class Tartarus::Registry
16
16
  @storage << item
17
17
  end
18
18
 
19
- def find_by_model(model)
20
- storage.find(->{ raise "#{model} not found in registry" }) { |item| item.for_model?(model) }
19
+ def find_by_name(name)
20
+ storage.find(->{ raise "#{name} not found in registry" }) { |item| item.name == name }
21
21
  end
22
22
 
23
23
  def reset
@@ -1,3 +1,10 @@
1
+ require "aws-sdk-glacier"
2
+ require "tartarus/remote_storage/glacier/client"
3
+ require "tartarus/remote_storage/glacier/file"
4
+ require "tartarus/remote_storage/glacier/csv_export"
5
+ require "tartarus/remote_storage/glacier/register_upload"
6
+ require "tartarus/remote_storage/glacier/configuration"
7
+
1
8
  class Tartarus
2
9
  module RemoteStorage
3
10
  class Glacier
@@ -1,2 +1,4 @@
1
1
  module Tartarus::RemoteStorage
2
+ autoload :Glacier, "tartarus/remote_storage/glacier"
3
+ autoload :Null, "tartarus/remote_storage/null"
2
4
  end
@@ -6,15 +6,15 @@ class Tartarus::ScheduleArchivingModel
6
6
  @registry = registry
7
7
  end
8
8
 
9
- def schedule(model_name)
10
- archivable_item = registry.find_by_model(model_name)
9
+ def schedule(archivable_item_name)
10
+ archivable_item = registry.find_by_name(archivable_item_name)
11
11
 
12
12
  if archivable_item.scope_by_tenant?
13
13
  each_tenant(archivable_item) do |tenant|
14
- enqueue(Tartarus::Sidekiq::ArchiveModelWithTenantJob, archivable_item.queue, model_name, tenant)
14
+ enqueue(Tartarus::Sidekiq::ArchiveModelWithTenantJob, archivable_item.queue, archivable_item.name, tenant)
15
15
  end
16
16
  else
17
- enqueue(Tartarus::Sidekiq::ArchiveModelWithoutTenantJob, archivable_item.queue, model_name)
17
+ enqueue(Tartarus::Sidekiq::ArchiveModelWithoutTenantJob, archivable_item.queue, archivable_item.name)
18
18
  end
19
19
  end
20
20
 
@@ -4,8 +4,8 @@ class Tartarus
4
4
  class Sidekiq::ArchiveModelWithTenantJob
5
5
  include ::Sidekiq::Worker
6
6
 
7
- def perform(model_name, tenant_id)
8
- Tartarus::ArchiveModelWithTenant.new.archive(model_name, tenant_id)
7
+ def perform(archivable_item_name, tenant_id)
8
+ Tartarus::ArchiveModelWithTenant.new.archive(archivable_item_name, tenant_id)
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ class Tartarus
4
4
  class Sidekiq::ArchiveModelWithoutTenantJob
5
5
  include ::Sidekiq::Worker
6
6
 
7
- def perform(model_name)
8
- Tartarus::ArchiveModelWithoutTenant.new.archive(model_name)
7
+ def perform(archivable_item_name)
8
+ Tartarus::ArchiveModelWithoutTenant.new.archive(archivable_item_name)
9
9
  end
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ class Tartarus
4
4
  class Sidekiq::ScheduleArchivingModelJob
5
5
  include ::Sidekiq::Worker
6
6
 
7
- def perform(model_name)
8
- Tartarus::ScheduleArchivingModel.new.schedule(model_name)
7
+ def perform(archivable_item_name)
8
+ Tartarus::ScheduleArchivingModel.new.schedule(archivable_item_name)
9
9
  end
10
10
  end
11
11
  end
data/lib/tartarus.rb CHANGED
@@ -19,15 +19,7 @@ require "tartarus/registry"
19
19
  require "tartarus/repository"
20
20
  require "tartarus/schedule_archiving_model"
21
21
  require "tartarus/remote_storage"
22
- require "tartarus/remote_storage/null"
23
- require "tartarus/remote_storage/glacier"
24
- require "tartarus/remote_storage/glacier/client"
25
- require "tartarus/remote_storage/glacier/file"
26
- require "tartarus/remote_storage/glacier/csv_export"
27
- require "tartarus/remote_storage/glacier/register_upload"
28
- require "tartarus/remote_storage/glacier/configuration"
29
22
  require "sidekiq/cron/job"
30
- require "aws-sdk-glacier"
31
23
  require "sidekiq"
32
24
 
33
25
  class Tartarus
data/tartarus-rb.gemspec CHANGED
@@ -29,11 +29,12 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency "sidekiq", ">= 5"
31
31
  spec.add_dependency "sidekiq-cron", "~> 1"
32
- spec.add_dependency "aws-sdk-glacier"
32
+
33
33
 
34
34
  spec.add_development_dependency "rake", "~> 13.0"
35
35
  spec.add_development_dependency "rspec", "~> 3.0"
36
36
  spec.add_development_dependency "rspec-sidekiq"
37
+ spec.add_development_dependency "aws-sdk-glacier"
37
38
 
38
39
  spec.add_development_dependency "activerecord", "~> 6"
39
40
  spec.add_development_dependency "pg"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tartarus-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karol Galanciak
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-08 00:00:00.000000000 Z
11
+ date: 2022-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1'
41
- - !ruby/object:Gem::Dependency
42
- name: aws-sdk-glacier
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rake
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +80,20 @@ dependencies:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-glacier
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: activerecord
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -264,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
264
  - !ruby/object:Gem::Version
265
265
  version: '0'
266
266
  requirements: []
267
- rubygems_version: 3.1.2
267
+ rubygems_version: 3.1.4
268
268
  signing_key:
269
269
  specification_version: 4
270
270
  summary: A gem for archving (deleting) old records you no longer need. Send them straight